iu.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <mach.h>
  5. #define Extern extern
  6. #include "power.h"
  7. void add(ulong);
  8. void addc(ulong);
  9. void adde(ulong);
  10. void addme(ulong);
  11. void addze(ulong);
  12. void and(ulong);
  13. void andc(ulong);
  14. void cmp(ulong);
  15. void cmpl(ulong);
  16. void cntlzw(ulong);
  17. void dcbf(ulong);
  18. void dcbi(ulong);
  19. void dcbst(ulong);
  20. void dcbt(ulong);
  21. void dcbtst(ulong);
  22. void dcbz(ulong);
  23. void divw(ulong);
  24. void divwu(ulong);
  25. void eciwx(ulong);
  26. void ecowx(ulong);
  27. void eieio(ulong);
  28. void eqv(ulong);
  29. void extsb(ulong);
  30. void extsh(ulong);
  31. void icbi(ulong);
  32. void lbzx(ulong);
  33. void lfdx(ulong);
  34. void lfsx(ulong);
  35. void lhax(ulong);
  36. void lhbrx(ulong);
  37. void lhzx(ulong);
  38. void lswi(ulong);
  39. void lswx(ulong);
  40. void lwarx(ulong);
  41. void lwbrx(ulong);
  42. void lwzx(ulong);
  43. void mcrxr(ulong);
  44. void mfcr(ulong);
  45. void mfmsr(ulong);
  46. void mfpmr(ulong);
  47. void mfspr(ulong);
  48. void mfsr(ulong);
  49. void mfsrin(ulong);
  50. void mftb(ulong);
  51. void mftbu(ulong);
  52. void mspr(ulong);
  53. void mtcrf(ulong);
  54. void mtmsr(ulong);
  55. void mtpmr(ulong);
  56. void mtspr(ulong);
  57. void mtsr(ulong);
  58. void mtsrin(ulong);
  59. void mttb(ulong);
  60. void mttbu(ulong);
  61. void mulhw(ulong);
  62. void mulhwu(ulong);
  63. void mullw(ulong);
  64. void nand(ulong);
  65. void neg(ulong);
  66. void nor(ulong);
  67. void or(ulong);
  68. void orc(ulong);
  69. void slbia(ulong);
  70. void slbia(ulong);
  71. void slw(ulong);
  72. void sraw(ulong);
  73. void srawi(ulong);
  74. void srw(ulong);
  75. void stbx(ulong);
  76. void stfdx(ulong);
  77. void stfiwx(ulong);
  78. void stfsx(ulong);
  79. void sthbrx(ulong);
  80. void sthx(ulong);
  81. void stswi(ulong);
  82. void stswx(ulong);
  83. void stwbrx(ulong);
  84. void stwcx(ulong);
  85. void stwx(ulong);
  86. void subf(ulong);
  87. void subfc(ulong);
  88. void subfe(ulong);
  89. void subfme(ulong);
  90. void subfze(ulong);
  91. void sync(ulong);
  92. void tlbie(ulong);
  93. void tw(ulong);
  94. void xor(ulong);
  95. Inst op31[] = {
  96. [0] {cmp, "cmp", Iarith},
  97. [4] {tw, "tw", Iarith},
  98. [8] {subfc, "subfc", Iarith},
  99. [10] {addc, "addc", Iarith},
  100. [11] {mulhwu, "mulhwu", Iarith},
  101. [19] {mfcr, "mfcr", Iarith},
  102. [20] {lwarx, "lwarx", Iload},
  103. [23] {lwzx, "lwzx", Iload},
  104. [24] {slw, "slw", Ilog},
  105. [26] {cntlzw, "cntlzw", Ilog},
  106. [28] {and, "and", Ilog},
  107. [32] {cmpl, "cmpl", Iarith},
  108. [40] {subf, "subf", Iarith},
  109. [54] {dcbst, "dcbst", Icontrol},
  110. [55] {lwzx, "lwzux", Iload},
  111. [60] {andc, "andc", Ilog},
  112. [75] {mulhw, "mulhw", Iarith},
  113. [83] {0, "mfmsr", Icontrol},
  114. [86] {dcbf, "dcbf", Icontrol},
  115. [87] {lbzx, "lbzx", Iload},
  116. [104] {neg, "neg", Iarith},
  117. [115] {0, "mfpmr", Iarith},
  118. [119] {lbzx, "lbzux", Iload},
  119. [124] {nor, "nor", Iarith},
  120. [136] {subfe, "subfe", Iarith},
  121. [138] {adde, "adde", Iarith},
  122. [144] {mtcrf, "mtcrf", Ireg},
  123. [146] {0, "mtmsr", Icontrol},
  124. [150] {stwcx, "stwcx.", Istore},
  125. [151] {stwx, "stwx", Istore},
  126. [178] {0, "mtpmr", Icontrol},
  127. [183] {stwx, "stwux", Istore},
  128. [200] {subfze, "subfze", Iarith},
  129. [202] {addze, "addze", Iarith},
  130. [210] {0, "mtsr", Ireg},
  131. [215] {stbx, "stbx", Istore},
  132. [232] {subfme, "subfme", Iarith},
  133. [234] {addme, "addme", Iarith},
  134. [235] {mullw, "mullw", Iarith},
  135. [242] {0, "mtsrin", Ireg},
  136. [246] {dcbtst, "dcbtst", Icontrol},
  137. [247] {stbx, "stbux", Istore},
  138. [266] {add, "add", Iarith},
  139. [275] {0, "mftb", Icontrol},
  140. [278] {dcbt, "dcbt", Icontrol},
  141. [279] {lhzx, "lhzx", Iload},
  142. [284] {eqv, "eqv", Ilog},
  143. [306] {0, "tlbie", Icontrol},
  144. [307] {0, "mftbu", Icontrol},
  145. [310] {0, "eciwx", Icontrol},
  146. [311] {lhzx, "lhzux", Iload},
  147. [316] {xor, "xor", Ilog},
  148. [339] {mspr, "mfspr", Ireg},
  149. [343] {lhax, "lhax", Iload},
  150. [375] {lhax, "lhaux", Iload},
  151. [403] {0, "mttb", Icontrol},
  152. [407] {sthx, "sthx", Istore},
  153. [412] {orc, "orc", Ilog},
  154. [434] {0, "slbia", Iarith},
  155. [435] {0, "mttbu", Icontrol},
  156. [438] {0, "ecowx", Icontrol},
  157. [439] {sthx, "sthux", Istore},
  158. [444] {or, "or", Ilog},
  159. [459] {divwu, "divwu", Iarith},
  160. [467] {mspr, "mtspr", Ireg},
  161. [470] {0, "dcbi", Icontrol},
  162. [476] {nand, "nand", Ilog},
  163. [491] {divw, "divw", Iarith},
  164. [498] {0, "slbia", Icontrol},
  165. [512] {mcrxr, "mcrxr", Ireg},
  166. [533] {lswx, "lswx", Iload},
  167. [534] {lwbrx, "lwbrx", Iload},
  168. [535] {lfsx, "lfsx", Ifloat},
  169. [536] {srw, "srw", Ilog},
  170. [567] {lfsx, "lfsux", Ifloat},
  171. [595] {0, "mfsr", Iarith},
  172. [597] {lswi, "lswi", Iarith},
  173. [598] {sync, "sync", Iarith},
  174. [599] {lfdx, "lfdx", Ifloat},
  175. [631] {lfdx, "lfdux", Ifloat},
  176. [659] {0, "mfsrin", Ireg},
  177. [661] {stswx, "stswx", Istore},
  178. [662] {stwbrx, "stwbrx", Istore},
  179. [663] {stfsx, "stfsx", Istore},
  180. [695] {stfsx, "stfsux", Istore},
  181. [725] {stswi, "stswi", Istore},
  182. [727] {stfdx, "stfdx", Istore},
  183. [759] {stfdx, "stfdux", Istore},
  184. [790] {lhbrx, "lhbrx", Iload},
  185. [792] {sraw, "sraw", Ilog},
  186. [824] {srawi, "srawi", Ilog},
  187. [854] {0, "eieio", Icontrol},
  188. [918] {sthbrx, "sthbrx", Istore},
  189. [922] {extsh, "extsh", Iarith},
  190. [954] {extsb, "extsb", Iarith},
  191. [982] {icbi, "icbi", Icontrol},
  192. [983] {unimp, "stfiwx", Istore},
  193. [1014] {dcbz, "dcbz", Icontrol},
  194. };
  195. Inset ops31 = {op31, nelem(op31)};
  196. void
  197. mspr(ulong ir)
  198. {
  199. int rd, ra, rb;
  200. ulong *d;
  201. char *n;
  202. char buf[20];
  203. getarrr(ir);
  204. switch((rb<<5) | ra) {
  205. case 0:
  206. undef(ir); /* was mq */
  207. return;
  208. case 1:
  209. d = &reg.xer; n = "xer";
  210. break;
  211. case 268:
  212. case 284:
  213. d = &reg.tbl; n = "tbl";
  214. break;
  215. case 269:
  216. case 285:
  217. d = &reg.tbu; n = "tbu";
  218. break;
  219. case 22:
  220. d = &reg.dec; n = "dec";
  221. break;
  222. case 8:
  223. d = &reg.lr; n = "lr";
  224. break;
  225. case 9:
  226. d = &reg.ctr; n = "ctr";
  227. break;
  228. default:
  229. d = 0; sprint(n = buf, "spr%d", rd);
  230. break;
  231. }
  232. if(getxo(ir) == 339) {
  233. if(trace)
  234. itrace("%s\tr%d,%s", ci->name, rd, n);
  235. reg.r[rd] = *d;
  236. } else {
  237. if(trace)
  238. itrace("%s\t%s,r%d", ci->name, n, rd);
  239. *d = reg.r[rd];
  240. }
  241. }
  242. static void
  243. setcr(int d, long r)
  244. {
  245. int c;
  246. c = 0;
  247. if(reg.xer & XER_SO)
  248. c |= 1;
  249. if(r == 0)
  250. c |= 2;
  251. else if(r > 0)
  252. c |= 4;
  253. else
  254. c |= 8;
  255. reg.cr = (reg.cr & ~mkCR(d, 0xF)) | mkCR(d, c);
  256. }
  257. void
  258. addi(ulong ir)
  259. {
  260. int rd, ra;
  261. long imm;
  262. getairr(ir);
  263. if(trace) {
  264. if(ra)
  265. itrace("%s\tr%d,r%d,$0x%lux", ci->name, rd, ra, imm);
  266. else
  267. itrace("li\tr%d,$0x%lux", rd, imm);
  268. }
  269. if(ra)
  270. imm += reg.r[ra];
  271. reg.r[rd] = imm;
  272. }
  273. void
  274. addis(ulong ir)
  275. {
  276. int rd, ra;
  277. long imm;
  278. getairr(ir);
  279. if(trace) {
  280. if(ra)
  281. itrace("%s\tr%d,r%d,$0x%lux", ci->name, rd, ra, imm);
  282. else
  283. itrace("lis\tr%d,$0x%lux", rd, imm);
  284. }
  285. imm <<= 16;
  286. if(ra)
  287. imm += reg.r[ra];
  288. reg.r[rd] = imm;
  289. }
  290. void
  291. and(ulong ir)
  292. {
  293. int rs, ra, rb;
  294. getlrrr(ir);
  295. reg.r[ra] = reg.r[rs] & reg.r[rb];
  296. if(trace)
  297. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  298. if(ir & 1)
  299. setcr(0, reg.r[ra]);
  300. }
  301. void
  302. andc(ulong ir)
  303. {
  304. int rs, ra, rb;
  305. getlrrr(ir);
  306. reg.r[ra] = reg.r[rs] & ~reg.r[rb];
  307. if(trace)
  308. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  309. if(ir & 1)
  310. setcr(0, reg.r[ra]);
  311. }
  312. void
  313. andicc(ulong ir)
  314. {
  315. int rs, ra;
  316. ulong imm;
  317. getlirr(ir);
  318. reg.r[ra] = reg.r[rs] & imm;
  319. if(trace)
  320. itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
  321. setcr(0, reg.r[ra]);
  322. }
  323. void
  324. andiscc(ulong ir)
  325. {
  326. int rs, ra;
  327. ulong imm;
  328. getlirr(ir);
  329. reg.r[ra] = reg.r[rs] & (imm<<16);
  330. if(trace)
  331. itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
  332. setcr(0, reg.r[ra]);
  333. }
  334. void
  335. cmpli(ulong ir)
  336. {
  337. int rd, ra;
  338. ulong c;
  339. ulong imm, v;
  340. getairr(ir);
  341. imm &= 0xFFFF;
  342. if(rd & 3)
  343. undef(ir);
  344. rd >>= 2;
  345. v = reg.r[ra];
  346. c = 0;
  347. if(reg.xer & XER_SO)
  348. c |= CRSO;
  349. if(v < imm)
  350. c |= CRLT;
  351. else if(v == imm)
  352. c |= CREQ;
  353. else
  354. c |= CRGT;
  355. c >>= 28;
  356. reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
  357. if(trace)
  358. itrace("%s\tcrf%d,r%d,0x%lux [cr=#%x]", ci->name, rd, ra, imm, c);
  359. }
  360. void
  361. cmp(ulong ir)
  362. {
  363. int rd, ra, rb;
  364. ulong c;
  365. long va, vb;
  366. getarrr(ir);
  367. if(rd & 3)
  368. undef(ir);
  369. rd >>= 2;
  370. c = 0;
  371. if(reg.xer & XER_SO)
  372. c |= CRSO;
  373. va = reg.r[ra];
  374. vb = reg.r[rb];
  375. if(va < vb)
  376. c |= CRLT;
  377. else if(va == vb)
  378. c |= CREQ;
  379. else
  380. c |= CRGT;
  381. c >>= 28;
  382. reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
  383. if(trace)
  384. itrace("%s\tcrf%d,r%d,r%d [cr=#%x]", ci->name, rd, ra, rb, c);
  385. }
  386. void
  387. cmpi(ulong ir)
  388. {
  389. int rd, ra;
  390. ulong c;
  391. long imm, v;
  392. getairr(ir);
  393. if(rd & 3)
  394. undef(ir);
  395. rd >>= 2;
  396. v = reg.r[ra];
  397. c = 0;
  398. if(reg.xer & XER_SO)
  399. c |= CRSO;
  400. if(v < imm)
  401. c |= CRLT;
  402. else if(v == imm)
  403. c |= CREQ;
  404. else
  405. c |= CRGT;
  406. c >>= 28;
  407. reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
  408. if(trace)
  409. itrace("%s\tcrf%d,r%d,0x%lux [cr=#%x]", ci->name, rd, ra, imm, c);
  410. }
  411. void
  412. cmpl(ulong ir)
  413. {
  414. int rd, ra, rb;
  415. ulong c;
  416. ulong va, vb;
  417. getarrr(ir);
  418. if(rd & 3)
  419. undef(ir);
  420. rd >>= 2;
  421. c = 0;
  422. if(reg.xer & XER_SO)
  423. c |= CRSO;
  424. va = reg.r[ra];
  425. vb = reg.r[rb];
  426. if(va < vb)
  427. c |= CRLT;
  428. else if(va == vb)
  429. c |= CREQ;
  430. else
  431. c |= CRGT;
  432. c >>= 28;
  433. reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, c);
  434. if(trace)
  435. itrace("%s\tcrf%d,r%d,r%d [cr=#%x]", ci->name, rd, ra, rb, c);
  436. }
  437. void
  438. cntlzw(ulong ir)
  439. {
  440. int rs, ra, rb, n;
  441. getlrrr(ir);
  442. if(rb)
  443. undef(ir);
  444. for(n=0; n<32 && (reg.r[rs] & (1L<<(31-n))) == 0; n++)
  445. ;
  446. reg.r[ra] = n;
  447. if(trace)
  448. itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs);
  449. if(ir & 1)
  450. setcr(0, reg.r[ra]);
  451. }
  452. void
  453. eqv(ulong ir)
  454. {
  455. int rs, ra, rb;
  456. getlrrr(ir);
  457. reg.r[ra] = ~(reg.r[rs] ^ reg.r[rb]);
  458. if(trace)
  459. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  460. if(ir & 1)
  461. setcr(0, reg.r[ra]);
  462. }
  463. void
  464. extsb(ulong ir)
  465. {
  466. int rs, ra, rb;
  467. getlrrr(ir);
  468. if(rb)
  469. undef(ir);
  470. reg.r[ra] = (schar)reg.r[rs];
  471. if(trace)
  472. itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs);
  473. if(ir & 1)
  474. setcr(0, reg.r[ra]);
  475. }
  476. void
  477. extsh(ulong ir)
  478. {
  479. int rs, ra, rb;
  480. getlrrr(ir);
  481. if(rb)
  482. undef(ir);
  483. reg.r[ra] = (short)reg.r[rs];
  484. if(trace)
  485. itrace("%s%s\tr%d,r%d", ci->name, ir&1?".":"", ra, rs);
  486. if(ir & 1)
  487. setcr(0, reg.r[ra]);
  488. }
  489. void
  490. add(ulong ir)
  491. {
  492. int rd, ra, rb;
  493. uvlong r;
  494. getarrr(ir);
  495. r = (uvlong)(ulong)reg.r[ra] + reg.r[rb];
  496. if(ir & OE) {
  497. reg.xer &= ~XER_OV;
  498. if(r >> 16)
  499. reg.xer |= XER_SO | XER_OV;
  500. }
  501. reg.r[rd] = (ulong)r;
  502. if(ir & Rc)
  503. setcr(0, reg.r[rd]);
  504. if(trace)
  505. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
  506. }
  507. void
  508. addc(ulong ir)
  509. {
  510. int rd, ra, rb;
  511. ulong v;
  512. uvlong r;
  513. getarrr(ir);
  514. r = (uvlong)(ulong)reg.r[ra] + reg.r[rb];
  515. v = r>>32;
  516. reg.xer &= ~XER_CA;
  517. if(v)
  518. reg.xer |= XER_CA;
  519. if(ir & OE) {
  520. reg.xer &= ~XER_OV;
  521. if(v>>1)
  522. reg.xer |= XER_SO | XER_OV;
  523. }
  524. reg.r[rd] = (ulong)r;
  525. if(ir & Rc)
  526. setcr(0, reg.r[rd]);
  527. if(trace)
  528. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
  529. }
  530. void
  531. adde(ulong ir)
  532. {
  533. int rd, ra, rb;
  534. ulong v;
  535. uvlong r;
  536. getarrr(ir);
  537. r = (uvlong)(ulong)reg.r[ra] + reg.r[rb] + (reg.xer&XER_CA)!=0;
  538. v = r>>32;
  539. reg.xer &= ~XER_CA;
  540. if(v)
  541. reg.xer |= XER_CA;
  542. if(ir & OE) {
  543. reg.xer &= ~XER_OV;
  544. if(v>>1)
  545. reg.xer |= XER_SO | XER_OV;
  546. }
  547. reg.r[rd] = (ulong)r;
  548. if(ir & Rc)
  549. setcr(0, reg.r[rd]);
  550. if(trace)
  551. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
  552. }
  553. void
  554. addic(ulong ir)
  555. {
  556. int rd, ra;
  557. long imm;
  558. ulong v;
  559. uvlong r;
  560. getairr(ir);
  561. r = (uvlong)(ulong)reg.r[ra] + imm;
  562. v = r>>32;
  563. reg.xer &= ~XER_CA;
  564. if(v)
  565. reg.xer |= XER_CA;
  566. reg.r[rd] = (ulong)r;
  567. if(trace)
  568. itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
  569. }
  570. void
  571. addiccc(ulong ir)
  572. {
  573. int rd, ra;
  574. long imm;
  575. ulong v;
  576. uvlong r;
  577. getairr(ir);
  578. r = (uvlong)(ulong)reg.r[ra] + imm;
  579. v = r>>32;
  580. reg.xer &= ~XER_CA;
  581. if(v)
  582. reg.xer |= XER_CA;
  583. reg.r[rd] = (ulong)r;
  584. setcr(0, reg.r[rd]);
  585. if(trace)
  586. itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
  587. }
  588. void
  589. addme(ulong ir)
  590. {
  591. int rd, ra, rb;
  592. ulong v;
  593. uvlong r;
  594. getarrr(ir);
  595. if(rb)
  596. undef(ir);
  597. r = (uvlong)(ulong)reg.r[ra] + 0xFFFFFFFF + (reg.xer&XER_CA)!=0;
  598. v = r>>32;
  599. reg.xer &= ~XER_CA;
  600. if(v)
  601. reg.xer |= XER_CA;
  602. if(ir & OE) {
  603. reg.xer &= ~XER_OV;
  604. if(v>>1)
  605. reg.xer |= XER_SO | XER_OV;
  606. }
  607. reg.r[rd] = (ulong)r;
  608. if(ir & Rc)
  609. setcr(0, reg.r[rd]);
  610. if(trace)
  611. itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
  612. }
  613. void
  614. addze(ulong ir)
  615. {
  616. int rd, ra, rb;
  617. ulong v;
  618. uvlong r;
  619. getarrr(ir);
  620. if(rb)
  621. undef(ir);
  622. r = (uvlong)(ulong)reg.r[ra] + (reg.xer&XER_CA)!=0;
  623. v = r>>32;
  624. reg.xer &= ~XER_CA;
  625. if(v)
  626. reg.xer |= XER_CA;
  627. if(ir & OE) {
  628. reg.xer &= ~XER_OV;
  629. if(v>>1)
  630. reg.xer |= XER_SO | XER_OV;
  631. }
  632. reg.r[rd] = (ulong)r;
  633. if(ir & Rc)
  634. setcr(0, reg.r[rd]);
  635. if(trace)
  636. itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
  637. }
  638. void
  639. divw(ulong ir)
  640. {
  641. int rd, ra, rb;
  642. getarrr(ir);
  643. if(reg.r[rb] != 0 && ((ulong)reg.r[ra] != 0x80000000 || reg.r[rb] != -1))
  644. reg.r[rd] = reg.r[ra]/reg.r[rb];
  645. else if(ir & OE)
  646. reg.xer |= XER_SO | XER_OV;
  647. if(ir & Rc)
  648. setcr(0, reg.r[rd]);
  649. if(trace)
  650. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
  651. }
  652. void
  653. divwu(ulong ir)
  654. {
  655. int rd, ra, rb;
  656. getarrr(ir);
  657. if(reg.r[rb] != 0)
  658. reg.r[rd] = (ulong)reg.r[ra]/(ulong)reg.r[rb];
  659. else if(ir & OE)
  660. reg.xer |= XER_SO | XER_OV;
  661. if(ir & Rc)
  662. setcr(0, reg.r[rd]);
  663. if(trace)
  664. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
  665. }
  666. void
  667. mcrxr(ulong ir)
  668. {
  669. int rd, ra, rb;
  670. getarrr(ir);
  671. if(rd & 3 || ra != 0 || rb != 0 || ir & Rc)
  672. undef(ir);
  673. rd >>= 2;
  674. reg.cr = (reg.cr & ~mkCR(rd, 0xF)) | mkCR(rd, reg.xer>>28);
  675. reg.xer &= ~(0xF<<28);
  676. }
  677. void
  678. mtcrf(ulong ir)
  679. {
  680. int rs, crm, i;
  681. ulong m;
  682. if(ir & ((1<<20)|(1<<11)|Rc))
  683. undef(ir);
  684. rs = (ir>>21)&0x1F;
  685. crm = (ir>>12)&0xFF;
  686. m = 0;
  687. for(i = 0x80; i; i >>= 1) {
  688. m <<= 4;
  689. if(crm & i)
  690. m |= 0xF;
  691. }
  692. reg.cr = (reg.cr & ~m) | (reg.r[rs] & m);
  693. }
  694. void
  695. mfcr(ulong ir)
  696. {
  697. int rd, ra, rb;
  698. getarrr(ir);
  699. if(ra != 0 || rb != 0 || ir & Rc)
  700. undef(ir);
  701. reg.r[rd] = reg.cr;
  702. }
  703. void
  704. mulhw(ulong ir)
  705. {
  706. int rd, ra, rb;
  707. getarrr(ir);
  708. reg.r[rd] = ((vlong)(long)reg.r[ra]*(long)reg.r[rb])>>32;
  709. if(ir & Rc)
  710. setcr(0, reg.r[rd]);
  711. if(trace)
  712. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb);
  713. /* BUG: doesn't set OV */
  714. }
  715. void
  716. mulhwu(ulong ir)
  717. {
  718. int rd, ra, rb;
  719. getarrr(ir);
  720. reg.r[rd] = ((uvlong)(ulong)reg.r[ra]*(ulong)reg.r[rb])>>32;
  721. if(ir & Rc)
  722. setcr(0, reg.r[rd]); /* not sure whether CR setting is signed or unsigned */
  723. if(trace)
  724. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb);
  725. /* BUG: doesn't set OV */
  726. }
  727. void
  728. mullw(ulong ir)
  729. {
  730. int rd, ra, rb;
  731. getarrr(ir);
  732. reg.r[rd] = (uvlong)(ulong)reg.r[ra]*(ulong)reg.r[rb];
  733. if(ir & Rc)
  734. setcr(0, reg.r[rd]);
  735. if(trace)
  736. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&Rc?".":"", rd, ra, rb);
  737. /* BUG: doesn't set OV */
  738. }
  739. void
  740. mulli(ulong ir)
  741. {
  742. int rd, ra;
  743. long imm;
  744. getairr(ir);
  745. reg.r[rd] = (uvlong)(ulong)reg.r[ra]*(ulong)imm;
  746. if(trace)
  747. itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
  748. }
  749. void
  750. nand(ulong ir)
  751. {
  752. int rs, ra, rb;
  753. getlrrr(ir);
  754. reg.r[ra] = ~(reg.r[rs] & reg.r[rb]);
  755. if(ir & Rc)
  756. setcr(0, reg.r[ra]);
  757. if(trace)
  758. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  759. }
  760. void
  761. neg(ulong ir)
  762. {
  763. int rd, ra, rb;
  764. getarrr(ir);
  765. if(rb)
  766. undef(ir);
  767. if(ir & OE)
  768. reg.xer &= ~XER_OV;
  769. if((ulong)reg.r[ra] == 0x80000000) {
  770. if(ir & OE)
  771. reg.xer |= XER_SO | XER_OV;
  772. reg.r[rd] = reg.r[ra];
  773. } else
  774. reg.r[rd] = -reg.r[ra];
  775. if(ir & Rc)
  776. setcr(0, reg.r[rd]);
  777. }
  778. void
  779. nor(ulong ir)
  780. {
  781. int rs, ra, rb;
  782. getlrrr(ir);
  783. reg.r[ra] = ~(reg.r[rs] | reg.r[rb]);
  784. if(ir & Rc)
  785. setcr(0, reg.r[ra]);
  786. if(trace)
  787. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  788. }
  789. void
  790. or(ulong ir)
  791. {
  792. int rs, ra, rb;
  793. getlrrr(ir);
  794. reg.r[ra] = reg.r[rs] | reg.r[rb];
  795. if(ir & Rc)
  796. setcr(0, reg.r[ra]);
  797. if(trace) {
  798. if(rs == rb)
  799. itrace("mr%s\tr%d,r%d", ir&1?".":"", ra, rs);
  800. else
  801. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  802. }
  803. }
  804. void
  805. orc(ulong ir)
  806. {
  807. int rs, ra, rb;
  808. getlrrr(ir);
  809. reg.r[ra] = reg.r[rs] | ~reg.r[rb];
  810. if(ir & Rc)
  811. setcr(0, reg.r[ra]);
  812. if(trace)
  813. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  814. }
  815. void
  816. ori(ulong ir)
  817. {
  818. int rs, ra;
  819. ulong imm;
  820. getlirr(ir);
  821. reg.r[ra] = reg.r[rs] | imm;
  822. if(trace)
  823. itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
  824. }
  825. void
  826. oris(ulong ir)
  827. {
  828. int rs, ra;
  829. ulong imm;
  830. getlirr(ir);
  831. reg.r[ra] = reg.r[rs] | (imm<<16);
  832. if(trace)
  833. itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
  834. }
  835. static ulong
  836. mkmask(int mb, int me)
  837. {
  838. int i;
  839. ulong v;
  840. if(mb > me)
  841. return mkmask(0, me) | mkmask(mb, 31);
  842. v = 0;
  843. for(i=mb; i<=me; i++)
  844. v |= 1L << (31-i); /* don't need a loop, but i'm lazy */
  845. return v;
  846. }
  847. static ulong
  848. rotl(ulong v, int sh)
  849. {
  850. if(sh == 0)
  851. return v;
  852. return (v<<sh) | (v>>(32-sh));
  853. }
  854. void
  855. rlwimi(ulong ir)
  856. {
  857. int rs, ra, rb, sh;
  858. ulong m;
  859. getlrrr(ir);
  860. sh = rb;
  861. m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F);
  862. reg.r[ra] = (reg.r[ra] & ~m) | (rotl(reg.r[rs], sh) & m);
  863. if(trace)
  864. itrace("%s\tr%d,r%d,%d,#%lux", ci->name, ra, rs, sh, m);
  865. if(ir & 1)
  866. setcr(0, reg.r[ra]);
  867. }
  868. void
  869. rlwinm(ulong ir)
  870. {
  871. int rs, ra, rb, sh;
  872. ulong m;
  873. getlrrr(ir);
  874. sh = rb;
  875. m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F);
  876. reg.r[ra] = rotl(reg.r[rs], sh) & m;
  877. if(trace)
  878. itrace("%s%s\tr%d,r%d,%d,#%lux", ci->name, ir&Rc?".":"", ra, rs, sh, m);
  879. if(ir & Rc)
  880. setcr(0, reg.r[ra]);
  881. }
  882. void
  883. rlwnm(ulong ir)
  884. {
  885. int rs, ra, rb, sh;
  886. ulong m;
  887. getlrrr(ir);
  888. sh = reg.r[rb] & 0x1F;
  889. m = mkmask((ir>>6)&0x1F, (ir>>1)&0x1F);
  890. reg.r[ra] = rotl(reg.r[rs], sh) & m;
  891. if(trace)
  892. itrace("%s\tr%d,r%d,r%d,#%lux", ci->name, ra, rs, rb, m);
  893. if(ir & 1)
  894. setcr(0, reg.r[ra]);
  895. }
  896. void
  897. slw(ulong ir)
  898. {
  899. int rs, ra, rb;
  900. long v;
  901. getlrrr(ir);
  902. v = reg.r[rb];
  903. if((v & 0x20) == 0) {
  904. v &= 0x1F;
  905. reg.r[ra] = (ulong)reg.r[rs] << v;
  906. } else
  907. reg.r[ra] = 0;
  908. if(ir & Rc)
  909. setcr(0, reg.r[ra]);
  910. if(trace)
  911. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  912. }
  913. void
  914. sraw(ulong ir)
  915. {
  916. int rs, ra, rb;
  917. long v;
  918. getlrrr(ir);
  919. v = reg.r[rb];
  920. if((v & 0x20) == 0) {
  921. v &= 0x1F;
  922. if(reg.r[rs]&SIGNBIT && v)
  923. reg.r[ra] = reg.r[rs]>>v | ~((1<<(32-v))-1);
  924. else
  925. reg.r[ra] = reg.r[rs]>>v;
  926. } else
  927. reg.r[ra] = reg.r[rs]&SIGNBIT? ~0: 0;
  928. if(ir & Rc)
  929. setcr(0, reg.r[ra]);
  930. if(trace)
  931. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  932. }
  933. void
  934. srawi(ulong ir)
  935. {
  936. int rs, ra, rb;
  937. long v;
  938. getlrrr(ir);
  939. v = rb;
  940. if((v & 0x20) == 0) {
  941. v &= 0x1F;
  942. if(reg.r[rs]&SIGNBIT && v)
  943. reg.r[ra] = reg.r[rs]>>v | ~((1<<(32-v))-1);
  944. else
  945. reg.r[ra] = reg.r[rs]>>v;
  946. } else
  947. reg.r[ra] = reg.r[rs]&SIGNBIT? ~0: 0;
  948. if(ir & Rc)
  949. setcr(0, reg.r[ra]);
  950. if(trace)
  951. itrace("%s%s\tr%d,r%d,$%d", ci->name, ir&1?".":"", ra, rs, v);
  952. }
  953. void
  954. srw(ulong ir)
  955. {
  956. int rs, ra, rb;
  957. long v;
  958. getlrrr(ir);
  959. v = reg.r[rb];
  960. if((v & 0x20) == 0)
  961. reg.r[ra] = (ulong)reg.r[rs] >> (v&0x1F);
  962. else
  963. reg.r[ra] = 0;
  964. if(ir & Rc)
  965. setcr(0, reg.r[ra]);
  966. if(trace)
  967. itrace("%s%s\tr%d,r%d,r%d", ci->name, ir&1?".":"", ra, rs, rb);
  968. }
  969. void
  970. subf(ulong ir)
  971. {
  972. int rd, ra, rb;
  973. uvlong r;
  974. getarrr(ir);
  975. r = (uvlong)((ulong)~reg.r[ra]) + reg.r[rb] + 1;
  976. if(ir & OE) {
  977. reg.xer &= ~XER_OV;
  978. if(r >> 16)
  979. reg.xer |= XER_SO | XER_OV;
  980. }
  981. reg.r[rd] = (ulong)r;
  982. if(ir & Rc)
  983. setcr(0, reg.r[rd]);
  984. if(trace)
  985. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
  986. }
  987. void
  988. subfc(ulong ir)
  989. {
  990. int rd, ra, rb;
  991. ulong v;
  992. uvlong r;
  993. getarrr(ir);
  994. r = (uvlong)((ulong)~reg.r[ra]) + reg.r[rb] + 1;
  995. v = r>>32;
  996. reg.xer &= ~XER_CA;
  997. if(v)
  998. reg.xer |= XER_CA;
  999. if(ir & OE) {
  1000. reg.xer &= ~XER_OV;
  1001. if(v>>1)
  1002. reg.xer |= XER_SO | XER_OV;
  1003. }
  1004. reg.r[rd] = (ulong)r;
  1005. if(ir & Rc)
  1006. setcr(0, reg.r[rd]);
  1007. if(trace)
  1008. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
  1009. }
  1010. void
  1011. subfe(ulong ir)
  1012. {
  1013. int rd, ra, rb;
  1014. ulong v;
  1015. uvlong r;
  1016. getarrr(ir);
  1017. r = (uvlong)((ulong)~reg.r[ra]) + reg.r[rb] + (reg.xer&XER_CA)!=0;
  1018. v = r>>32;
  1019. reg.xer &= ~XER_CA;
  1020. if(v)
  1021. reg.xer |= XER_CA;
  1022. if(ir & OE) {
  1023. reg.xer &= ~XER_OV;
  1024. if(v>>1)
  1025. reg.xer |= XER_SO | XER_OV;
  1026. }
  1027. reg.r[rd] = (ulong)r;
  1028. if(ir & Rc)
  1029. setcr(0, reg.r[rd]);
  1030. if(trace)
  1031. itrace("%s%s%s\tr%d,r%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra, rb);
  1032. }
  1033. void
  1034. subfic(ulong ir)
  1035. {
  1036. int rd, ra;
  1037. long imm;
  1038. ulong v;
  1039. uvlong r;
  1040. getairr(ir);
  1041. r = (uvlong)((ulong)~reg.r[ra]) + imm + 1;
  1042. v = r>>32;
  1043. reg.xer &= ~XER_CA;
  1044. if(v)
  1045. reg.xer |= XER_CA;
  1046. reg.r[rd] = (ulong)r;
  1047. if(trace)
  1048. itrace("%s\tr%d,r%d,$%ld", ci->name, rd, ra, imm);
  1049. }
  1050. void
  1051. subfme(ulong ir)
  1052. {
  1053. int rd, ra, rb;
  1054. ulong v;
  1055. uvlong r;
  1056. getarrr(ir);
  1057. if(rb)
  1058. undef(ir);
  1059. r = (uvlong)((ulong)~reg.r[ra]) + 0xFFFFFFFF + (reg.xer&XER_CA)!=0;
  1060. v = r>>32;
  1061. reg.xer &= ~XER_CA;
  1062. if(v)
  1063. reg.xer |= XER_CA;
  1064. if(ir & OE) {
  1065. reg.xer &= ~XER_OV;
  1066. if(v>>1)
  1067. reg.xer |= XER_SO | XER_OV;
  1068. }
  1069. reg.r[rd] = (ulong)r;
  1070. if(ir & Rc)
  1071. setcr(0, reg.r[rd]);
  1072. if(trace)
  1073. itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
  1074. }
  1075. void
  1076. subfze(ulong ir)
  1077. {
  1078. int rd, ra, rb;
  1079. ulong v;
  1080. uvlong r;
  1081. getarrr(ir);
  1082. if(rb)
  1083. undef(ir);
  1084. r = (uvlong)((ulong)~reg.r[ra]) + (reg.xer&XER_CA)!=0;
  1085. v = r>>32;
  1086. reg.xer &= ~XER_CA;
  1087. if(v)
  1088. reg.xer |= XER_CA;
  1089. if(ir & OE) {
  1090. reg.xer &= ~XER_OV;
  1091. if(v>>1)
  1092. reg.xer |= XER_SO | XER_OV;
  1093. }
  1094. reg.r[rd] = (ulong)r;
  1095. if(ir & Rc)
  1096. setcr(0, reg.r[rd]);
  1097. if(trace)
  1098. itrace("%s%s%s\tr%d,r%d", ci->name, ir&OE?"o":"", ir&1?".":"", rd, ra);
  1099. }
  1100. void
  1101. xor(ulong ir)
  1102. {
  1103. int rs, ra, rb;
  1104. getlrrr(ir);
  1105. reg.r[ra] = reg.r[rs] ^ reg.r[rb];
  1106. if(trace)
  1107. itrace("%s\tr%d,r%d,r%d", ci->name, ra, rs, rb);
  1108. }
  1109. void
  1110. xori(ulong ir)
  1111. {
  1112. int rs, ra;
  1113. ulong imm;
  1114. getlirr(ir);
  1115. reg.r[ra] = reg.r[rs] ^ imm;
  1116. if(trace)
  1117. itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
  1118. }
  1119. void
  1120. xoris(ulong ir)
  1121. {
  1122. int rs, ra;
  1123. ulong imm;
  1124. getlirr(ir);
  1125. reg.r[ra] = reg.r[rs] ^ (imm<<16);
  1126. if(trace)
  1127. itrace("%s\tr%d,r%d,$0x%lx", ci->name, ra, rs, imm);
  1128. }
  1129. void
  1130. lwz(ulong ir)
  1131. {
  1132. ulong ea;
  1133. int ra, rd, upd;
  1134. long imm;
  1135. getairr(ir);
  1136. ea = imm;
  1137. upd = (ir&(1L<<26))!=0;
  1138. if(ra) {
  1139. ea += reg.r[ra];
  1140. if(upd)
  1141. reg.r[ra] = ea;
  1142. } else {
  1143. if(upd)
  1144. undef(ir);
  1145. }
  1146. if(trace)
  1147. itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
  1148. reg.r[rd] = getmem_w(ea);
  1149. }
  1150. void
  1151. lwzx(ulong ir)
  1152. {
  1153. ulong ea;
  1154. int rb, ra, rd, upd;
  1155. getarrr(ir);
  1156. ea = reg.r[rb];
  1157. upd = getxo(ir)==55;
  1158. if(ra) {
  1159. ea += reg.r[ra];
  1160. if(upd)
  1161. reg.r[ra] = ea;
  1162. if(trace)
  1163. itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
  1164. } else {
  1165. if(upd)
  1166. undef(ir);
  1167. if(trace)
  1168. itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
  1169. }
  1170. reg.r[rd] = getmem_w(ea);
  1171. }
  1172. void
  1173. lwarx(ulong ir)
  1174. {
  1175. lwzx(ir);
  1176. }
  1177. void
  1178. lbz(ulong ir)
  1179. {
  1180. ulong ea;
  1181. int ra, rd, upd;
  1182. long imm;
  1183. getairr(ir);
  1184. ea = imm;
  1185. upd = (ir&(1L<<26))!=0;
  1186. if(ra) {
  1187. ea += reg.r[ra];
  1188. if(upd)
  1189. reg.r[ra] = ea;
  1190. } else {
  1191. if(upd)
  1192. undef(ir);
  1193. }
  1194. if(trace)
  1195. itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
  1196. reg.r[rd] = getmem_b(ea);
  1197. }
  1198. void
  1199. lbzx(ulong ir)
  1200. {
  1201. ulong ea;
  1202. int rb, ra, rd, upd;
  1203. getarrr(ir);
  1204. ea = reg.r[rb];
  1205. upd = getxo(ir)==119;
  1206. if(ra) {
  1207. ea += reg.r[ra];
  1208. if(upd)
  1209. reg.r[ra] = ea;
  1210. if(trace)
  1211. itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
  1212. } else {
  1213. if(upd)
  1214. undef(ir);
  1215. if(trace)
  1216. itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
  1217. }
  1218. reg.r[rd] = getmem_b(ea);
  1219. }
  1220. void
  1221. stw(ulong ir)
  1222. {
  1223. ulong ea;
  1224. int ra, rd, upd;
  1225. long imm;
  1226. getairr(ir);
  1227. ea = imm;
  1228. upd = (ir&(1L<<26))!=0;
  1229. if(ra) {
  1230. ea += reg.r[ra];
  1231. if(upd)
  1232. reg.r[ra] = ea;
  1233. } else {
  1234. if(upd)
  1235. undef(ir);
  1236. }
  1237. if(trace)
  1238. itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)",
  1239. ci->name, rd, imm, ra, ea, reg.r[rd], reg.r[rd]);
  1240. putmem_w(ea, reg.r[rd]);
  1241. }
  1242. void
  1243. stwx(ulong ir)
  1244. {
  1245. ulong ea;
  1246. int ra, rd, upd, rb;
  1247. getarrr(ir);
  1248. ea = reg.r[rb];
  1249. upd = getxo(ir)==183;
  1250. if(ra) {
  1251. ea += reg.r[ra];
  1252. if(upd)
  1253. reg.r[ra] = ea;
  1254. if(trace)
  1255. itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
  1256. ci->name, rd, ra, rb, ea, reg.r[rd], reg.r[rd]);
  1257. } else {
  1258. if(upd)
  1259. undef(ir);
  1260. if(trace)
  1261. itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
  1262. ci->name, rd, rb, ea, reg.r[rd], reg.r[rd]);
  1263. }
  1264. putmem_w(ea, reg.r[rd]);
  1265. }
  1266. void
  1267. stwcx(ulong ir)
  1268. {
  1269. ulong ea;
  1270. int ra, rd, rb;
  1271. if((ir & Rc) == 0)
  1272. undef(ir);
  1273. getarrr(ir);
  1274. ea = reg.r[rb];
  1275. if(ra) {
  1276. ea += reg.r[ra];
  1277. if(trace)
  1278. itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
  1279. ci->name, rd, ra, rb, ea, reg.r[rd], reg.r[rd]);
  1280. } else {
  1281. if(trace)
  1282. itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
  1283. ci->name, rd, rb, ea, reg.r[rd], reg.r[rd]);
  1284. }
  1285. putmem_w(ea, reg.r[rd]); /* assume a reservation exists; store succeeded */
  1286. setcr(0, 0);
  1287. }
  1288. void
  1289. stb(ulong ir)
  1290. {
  1291. ulong ea;
  1292. int ra, rd, upd, v;
  1293. long imm;
  1294. getairr(ir);
  1295. ea = imm;
  1296. upd = (ir&(1L<<26))!=0;
  1297. if(ra) {
  1298. ea += reg.r[ra];
  1299. if(upd)
  1300. reg.r[ra] = ea;
  1301. } else {
  1302. if(upd)
  1303. undef(ir);
  1304. }
  1305. v = reg.r[rd] & 0xFF;
  1306. if(trace)
  1307. itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)",
  1308. ci->name, rd, imm, ra, ea, v, v);
  1309. putmem_b(ea, v);
  1310. }
  1311. void
  1312. stbx(ulong ir)
  1313. {
  1314. ulong ea;
  1315. int ra, rd, upd, rb, v;
  1316. getarrr(ir);
  1317. ea = reg.r[rb];
  1318. upd = getxo(ir)==247;
  1319. v = reg.r[rd] & 0xFF;
  1320. if(ra) {
  1321. ea += reg.r[ra];
  1322. if(upd)
  1323. reg.r[ra] = ea;
  1324. if(trace)
  1325. itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
  1326. ci->name, rd, ra, rb, ea, v, v);
  1327. } else {
  1328. if(upd)
  1329. undef(ir);
  1330. if(trace)
  1331. itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
  1332. ci->name, rd, rb, ea, v, v);
  1333. }
  1334. putmem_b(ea, v);
  1335. }
  1336. void
  1337. lhz(ulong ir)
  1338. {
  1339. ulong ea;
  1340. int imm, ra, rd, upd;
  1341. getairr(ir);
  1342. ea = imm;
  1343. upd = (ir&(1L<<26))!=0;
  1344. if(ra) {
  1345. ea += reg.r[ra];
  1346. if(upd)
  1347. reg.r[ra] = ea;
  1348. } else {
  1349. if(upd)
  1350. undef(ir);
  1351. }
  1352. if(trace)
  1353. itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
  1354. reg.r[rd] = getmem_h(ea);
  1355. }
  1356. void
  1357. lhzx(ulong ir)
  1358. {
  1359. ulong ea;
  1360. int rb, ra, rd, upd;
  1361. getarrr(ir);
  1362. ea = reg.r[rb];
  1363. upd = getxo(ir)==311;
  1364. if(ra) {
  1365. ea += reg.r[ra];
  1366. if(upd)
  1367. reg.r[ra] = ea;
  1368. if(trace)
  1369. itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
  1370. } else {
  1371. if(upd)
  1372. undef(ir);
  1373. if(trace)
  1374. itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
  1375. }
  1376. reg.r[rd] = getmem_h(ea);
  1377. }
  1378. void
  1379. lha(ulong ir)
  1380. {
  1381. ulong ea;
  1382. int imm, ra, rd, upd;
  1383. getairr(ir);
  1384. ea = imm;
  1385. upd = (ir&(1L<<26))!=0;
  1386. if(ra) {
  1387. ea += reg.r[ra];
  1388. if(upd)
  1389. reg.r[ra] = ea;
  1390. } else {
  1391. if(upd)
  1392. undef(ir);
  1393. }
  1394. if(trace)
  1395. itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
  1396. reg.r[rd] = (short)getmem_h(ea);
  1397. }
  1398. void
  1399. lhax(ulong ir)
  1400. {
  1401. ulong ea;
  1402. int rb, ra, rd, upd;
  1403. getarrr(ir);
  1404. ea = reg.r[rb];
  1405. upd = getxo(ir)==311;
  1406. if(ra) {
  1407. ea += reg.r[ra];
  1408. if(upd)
  1409. reg.r[ra] = ea;
  1410. if(trace)
  1411. itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
  1412. } else {
  1413. if(upd)
  1414. undef(ir);
  1415. if(trace)
  1416. itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
  1417. }
  1418. reg.r[rd] = (short)getmem_h(ea);
  1419. }
  1420. void
  1421. lhbrx(ulong ir)
  1422. {
  1423. ulong ea;
  1424. int rb, ra, rd;
  1425. ulong v;
  1426. getarrr(ir);
  1427. ea = reg.r[rb];
  1428. if(ra) {
  1429. ea += reg.r[ra];
  1430. if(trace)
  1431. itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
  1432. } else {
  1433. if(trace)
  1434. itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
  1435. }
  1436. v = getmem_h(ea);
  1437. reg.r[rd] = ((v&0xFF)<<8)|(v&0xFF);
  1438. }
  1439. void
  1440. sth(ulong ir)
  1441. {
  1442. ulong ea;
  1443. int imm, ra, rd, upd, v;
  1444. getairr(ir);
  1445. ea = imm;
  1446. upd = (ir&(1L<<26))!=0;
  1447. if(ra) {
  1448. ea += reg.r[ra];
  1449. if(upd)
  1450. reg.r[ra] = ea;
  1451. } else {
  1452. if(upd)
  1453. undef(ir);
  1454. }
  1455. v = reg.r[rd] & 0xFFFF;
  1456. if(trace)
  1457. itrace("%s\tr%d,%ld(r%d) #%lux=#%lux (%ld)",
  1458. ci->name, rd, imm, ra, ea, v, v);
  1459. putmem_h(ea, v);
  1460. }
  1461. void
  1462. sthx(ulong ir)
  1463. {
  1464. ulong ea;
  1465. int ra, rd, upd, rb, v;
  1466. getarrr(ir);
  1467. ea = reg.r[rb];
  1468. upd = getxo(ir)==247;
  1469. v = reg.r[rd] & 0xFFFF;
  1470. if(ra) {
  1471. ea += reg.r[ra];
  1472. if(upd)
  1473. reg.r[ra] = ea;
  1474. if(trace)
  1475. itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
  1476. ci->name, rd, ra, rb, ea, v, v);
  1477. } else {
  1478. if(upd)
  1479. undef(ir);
  1480. if(trace)
  1481. itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
  1482. ci->name, rd, rb, ea, v, v);
  1483. }
  1484. putmem_h(ea, v);
  1485. }
  1486. void
  1487. sthbrx(ulong ir)
  1488. {
  1489. ulong ea;
  1490. int ra, rd, rb;
  1491. ulong v;
  1492. getarrr(ir);
  1493. ea = reg.r[rb];
  1494. v = reg.r[rd];
  1495. v = ((v&0xFF)<<8)|(v&0xFF);
  1496. if(ra) {
  1497. ea += reg.r[ra];
  1498. if(trace)
  1499. itrace("%s\tr%d,(r%d+r%d) #%lux=#%lux (%ld)",
  1500. ci->name, rd, ra, rb, ea, v, v);
  1501. } else {
  1502. if(trace)
  1503. itrace("%s\tr%d,(r%d) #%lux=#%lux (%ld)",
  1504. ci->name, rd, rb, ea, v, v);
  1505. }
  1506. putmem_h(ea, v);
  1507. }
  1508. void
  1509. lwbrx(ulong ir)
  1510. {
  1511. ulong ea;
  1512. int rb, ra, rd, i;
  1513. ulong v;
  1514. getarrr(ir);
  1515. if(ir & Rc)
  1516. undef(ir);
  1517. ea = reg.r[rb];
  1518. if(ra) {
  1519. ea += reg.r[ra];
  1520. if(trace)
  1521. itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
  1522. } else {
  1523. if(trace)
  1524. itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
  1525. }
  1526. v = 0;
  1527. for(i = 0; i < 4; i++)
  1528. v = v>>8 | getmem_b(ea++); /* assume unaligned load is allowed */
  1529. reg.r[rd] = v;
  1530. }
  1531. void
  1532. stwbrx(ulong ir)
  1533. {
  1534. ulong ea;
  1535. int rb, ra, rd, i;
  1536. ulong v;
  1537. getarrr(ir);
  1538. if(ir & Rc)
  1539. undef(ir);
  1540. ea = reg.r[rb];
  1541. if(ra) {
  1542. ea += reg.r[ra];
  1543. if(trace)
  1544. itrace("%s\tr%d,(r%d+r%d) ea=%lux", ci->name, rd, ra, rb, ea);
  1545. } else {
  1546. if(trace)
  1547. itrace("%s\tr%d,(r%d) ea=%lux", ci->name, rd, rb, ea);
  1548. }
  1549. v = 0;
  1550. for(i = 0; i < 4; i++) {
  1551. putmem_b(ea++, v & 0xFF); /* assume unaligned store is allowed */
  1552. v >>= 8;
  1553. }
  1554. }
  1555. void
  1556. lswi(ulong ir)
  1557. {
  1558. ulong ea;
  1559. int rb, ra, rd, n, i, r, b;
  1560. getarrr(ir);
  1561. if(ir & Rc)
  1562. undef(ir);
  1563. n = rb;
  1564. if(n == 0)
  1565. n = 32;
  1566. ea = 0;
  1567. if(ra) {
  1568. ea += reg.r[ra];
  1569. if(trace)
  1570. itrace("%s\tr%d,(r%d),%d ea=%lux", ci->name, rd, ra, n, ea);
  1571. } else {
  1572. if(trace)
  1573. itrace("%s\tr%d,(0),%d ea=0", ci->name, rd, n);
  1574. }
  1575. i = -1;
  1576. r = rd-1;
  1577. while(--n >= 0) {
  1578. if(i < 0) {
  1579. r = (r+1)&0x1F;
  1580. if(ra == 0 || r != ra)
  1581. reg.r[r] = 0;
  1582. i = 24;
  1583. }
  1584. b = getmem_b(ea++);
  1585. if(ra == 0 || r != ra)
  1586. reg.r[r] = (reg.r[r] & ~(0xFF<<i)) | (b << i);
  1587. i -= 8;
  1588. }
  1589. }
  1590. void
  1591. lswx(ulong ir)
  1592. {
  1593. ulong ea;
  1594. int rb, ra, rd, n, i, r, b;
  1595. getarrr(ir);
  1596. if(ir & Rc)
  1597. undef(ir);
  1598. n = reg.xer & 0x7F;
  1599. ea = reg.r[rb];
  1600. if(ra) {
  1601. ea += reg.r[ra];
  1602. if(trace)
  1603. itrace("%s\tr%d,(r%d+r%d) ea=%lux n=%d", ci->name, rd, ra, rb, ea, n);
  1604. } else {
  1605. if(trace)
  1606. itrace("%s\tr%d,(r%d) ea=%lux n=%d", ci->name, rd, rb, ea, n);
  1607. }
  1608. i = -1;
  1609. r = rd-1;
  1610. while(--n >= 0) {
  1611. if(i < 0) {
  1612. r = (r+1)&0x1F;
  1613. if((ra == 0 || r != ra) && r != rb)
  1614. reg.r[r] = 0;
  1615. i = 24;
  1616. }
  1617. b = getmem_b(ea++);
  1618. if((ra == 0 || r != ra) && r != rb)
  1619. reg.r[r] = (reg.r[r] & ~(0xFF<<i)) | (b << i);
  1620. i -= 8;
  1621. }
  1622. }
  1623. void
  1624. stswx(ulong ir)
  1625. {
  1626. ulong ea;
  1627. int rb, ra, rd, n, i, r;
  1628. getarrr(ir);
  1629. if(ir & Rc)
  1630. undef(ir);
  1631. n = reg.xer & 0x7F;
  1632. ea = reg.r[rb];
  1633. if(ra) {
  1634. ea += reg.r[ra];
  1635. if(trace)
  1636. itrace("%s\tr%d,(r%d+r%d) ea=%lux n=%d", ci->name, rd, ra, rb, ea, n);
  1637. } else {
  1638. if(trace)
  1639. itrace("%s\tr%d,(r%d) ea=%lux n=%d", ci->name, rd, rb, ea, n);
  1640. }
  1641. i = -1;
  1642. r = rd-1;
  1643. while(--n >= 0) {
  1644. if(i < 0) {
  1645. r = (r+1)&0x1F;
  1646. i = 24;
  1647. }
  1648. putmem_b(ea++, (reg.r[r]>>i)&0xFF);
  1649. i -= 8;
  1650. }
  1651. }
  1652. void
  1653. stswi(ulong ir)
  1654. {
  1655. ulong ea;
  1656. int rb, ra, rd, n, i, r;
  1657. getarrr(ir);
  1658. if(ir & Rc)
  1659. undef(ir);
  1660. n = rb;
  1661. if(n == 0)
  1662. n = 32;
  1663. ea = 0;
  1664. if(ra) {
  1665. ea += reg.r[ra];
  1666. if(trace)
  1667. itrace("%s\tr%d,(r%d),%d ea=%lux", ci->name, rd, ra, n, ea);
  1668. } else {
  1669. if(trace)
  1670. itrace("%s\tr%d,(0),%d ea=0", ci->name, rd, n);
  1671. }
  1672. i = -1;
  1673. r = rd-1;
  1674. while(--n >= 0) {
  1675. if(i < 0) {
  1676. r = (r+1)&0x1F;
  1677. i = 24;
  1678. }
  1679. putmem_b(ea++, (reg.r[r]>>i)&0xFF);
  1680. i -= 8;
  1681. }
  1682. }
  1683. void
  1684. lmw(ulong ir)
  1685. {
  1686. ulong ea;
  1687. int ra, rd, r;
  1688. long imm;
  1689. getairr(ir);
  1690. ea = imm;
  1691. if(ra)
  1692. ea += reg.r[ra];
  1693. if(trace)
  1694. itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
  1695. for(r = rd; r <= 31; r++) {
  1696. if(r != 0 && r != rd)
  1697. reg.r[rd] = getmem_w(ea);
  1698. ea += 4;
  1699. }
  1700. }
  1701. void
  1702. stmw(ulong ir)
  1703. {
  1704. ulong ea;
  1705. int ra, rd, r;
  1706. long imm;
  1707. getairr(ir);
  1708. ea = imm;
  1709. if(ra)
  1710. ea += reg.r[ra];
  1711. if(trace)
  1712. itrace("%s\tr%d,%ld(r%d) ea=%lux", ci->name, rd, imm, ra, ea);
  1713. for(r = rd; r <= 31; r++) {
  1714. putmem_w(ea, reg.r[rd]);
  1715. ea += 4;
  1716. }
  1717. }
  1718. void
  1719. twi(ulong ir)
  1720. {
  1721. int rd, ra;
  1722. long a, imm;
  1723. getairr(ir);
  1724. a = reg.r[ra];
  1725. if(trace)
  1726. itrace("twi\t#%.2x,r%d,$0x%lux (%ld)", rd, ra, imm, imm);
  1727. if(a < imm && rd&0x10 ||
  1728. a > imm && rd&0x08 ||
  1729. a == imm && rd&0x04 ||
  1730. (ulong)a < imm && rd&0x02 ||
  1731. (ulong)a > imm && rd&0x01) {
  1732. Bprint(bioout, "program_exception (trap type)\n");
  1733. longjmp(errjmp, 0);
  1734. }
  1735. }
  1736. void
  1737. tw(ulong ir)
  1738. {
  1739. int rd, ra, rb;
  1740. long a, b;
  1741. getarrr(ir);
  1742. a = reg.r[ra];
  1743. b = reg.r[rb];
  1744. if(trace)
  1745. itrace("tw\t#%.2x,r%d,r%d", rd, ra, rb);
  1746. if(a < b && rd&0x10 ||
  1747. a > b && rd&0x08 ||
  1748. a == b && rd&0x04 ||
  1749. (ulong)a < b && rd&0x02 ||
  1750. (ulong)a > b && rd&0x01) {
  1751. Bprint(bioout, "program_exception (trap type)\n");
  1752. longjmp(errjmp, 0);
  1753. }
  1754. }
  1755. void
  1756. sync(ulong ir)
  1757. {
  1758. USED(ir);
  1759. if(trace)
  1760. itrace("sync");
  1761. }
  1762. void
  1763. icbi(ulong ir)
  1764. {
  1765. int rd, ra, rb;
  1766. if(ir & Rc)
  1767. undef(ir);
  1768. getarrr(ir);
  1769. USED(rd);
  1770. if(trace)
  1771. itrace("%s\tr%d,r%d", ci->name, ra, rb);
  1772. }
  1773. void
  1774. dcbf(ulong ir)
  1775. {
  1776. int rd, ra, rb;
  1777. if(ir & Rc)
  1778. undef(ir);
  1779. getarrr(ir);
  1780. USED(rd);
  1781. if(trace)
  1782. itrace("%s\tr%d,r%d", ci->name, ra, rb);
  1783. }
  1784. void
  1785. dcbst(ulong ir)
  1786. {
  1787. int rd, ra, rb;
  1788. if(ir & Rc)
  1789. undef(ir);
  1790. getarrr(ir);
  1791. USED(rd);
  1792. if(trace)
  1793. itrace("%s\tr%d,r%d", ci->name, ra, rb);
  1794. }
  1795. void
  1796. dcbt(ulong ir)
  1797. {
  1798. int rd, ra, rb;
  1799. if(ir & Rc)
  1800. undef(ir);
  1801. getarrr(ir);
  1802. USED(rd);
  1803. if(trace)
  1804. itrace("%s\tr%d,r%d", ci->name, ra, rb);
  1805. }
  1806. void
  1807. dcbtst(ulong ir)
  1808. {
  1809. int rd, ra, rb;
  1810. if(ir & Rc)
  1811. undef(ir);
  1812. getarrr(ir);
  1813. USED(rd);
  1814. if(trace)
  1815. itrace("%s\tr%d,r%d", ci->name, ra, rb);
  1816. }
  1817. void
  1818. dcbz(ulong ir)
  1819. {
  1820. int rd, ra, rb;
  1821. if(ir & Rc)
  1822. undef(ir);
  1823. getarrr(ir);
  1824. USED(rd);
  1825. if(trace)
  1826. itrace("%s\tr%d,r%d", ci->name, ra, rb);
  1827. }