asmout.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "l.h"
  10. #define OPVCC(o,xo,oe,rc) (((o)<<26)|((xo)<<1)|((oe)<<10)|((rc)&1))
  11. #define OPCC(o,xo,rc) OPVCC((o),(xo),0,(rc))
  12. #define OP(o,xo) OPVCC((o),(xo),0,0)
  13. /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
  14. #define AOP_RRR(op,d,a,b) ((op)|(((d)&31L)<<21)|(((a)&31L)<<16)|(((b)&31L)<<11))
  15. #define AOP_IRR(op,d,a,simm) ((op)|(((d)&31L)<<21)|(((a)&31L)<<16)|((simm)&0xFFFF))
  16. #define LOP_RRR(op,a,s,b) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((b)&31L)<<11))
  17. #define LOP_IRR(op,a,s,uimm) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|((uimm)&0xFFFF))
  18. #define OP_BR(op,li,aa) ((op)|((li)&0x03FFFFFC)|((aa)<<1))
  19. #define OP_BC(op,bo,bi,bd,aa) ((op)|(((bo)&0x1F)<<21)|(((bi)&0x1F)<<16)|((bd)&0xFFFC)|((aa)<<1))
  20. #define OP_BCR(op,bo,bi) ((op)|(((bo)&0x1F)<<21)|(((bi)&0x1F)<<16))
  21. #define OP_RLW(op,a,s,sh,mb,me) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((sh)&31L)<<11)|\
  22. (((mb)&31L)<<6)|(((me)&31L)<<1))
  23. #define OP_ADD OPVCC(31,266,0,0)
  24. #define OP_ADDI OPVCC(14,0,0,0)
  25. #define OP_ADDIS OPVCC(15,0,0,0)
  26. #define OP_ANDI OPVCC(28,0,0,0)
  27. #define OP_EXTSB OPVCC(31,954,0,0)
  28. #define OP_EXTSH OPVCC(31,922,0,0)
  29. #define OP_MCRF OPVCC(19,0,0,0)
  30. #define OP_MCRFS OPVCC(63,64,0,0)
  31. #define OP_MCRXR OPVCC(31,512,0,0)
  32. #define OP_MFCR OPVCC(31,19,0,0)
  33. #define OP_MFFS OPVCC(63,583,0,0)
  34. #define OP_MFMSR OPVCC(31,83,0,0)
  35. #define OP_MFSPR OPVCC(31,339,0,0)
  36. #define OP_MFSR OPVCC(31,595,0,0)
  37. #define OP_MFSRIN OPVCC(31,659,0,0)
  38. #define OP_MTCRF OPVCC(31,144,0,0)
  39. #define OP_MTFSF OPVCC(63,711,0,0)
  40. #define OP_MTFSFI OPVCC(63,134,0,0)
  41. #define OP_MTMSR OPVCC(31,146,0,0)
  42. #define OP_MTSPR OPVCC(31,467,0,0)
  43. #define OP_MTSR OPVCC(31,210,0,0)
  44. #define OP_MTSRIN OPVCC(31,242,0,0)
  45. #define OP_MULLW OPVCC(31,235,0,0)
  46. #define OP_OR OPVCC(31,444,0,0)
  47. #define OP_ORI OPVCC(24,0,0,0)
  48. #define OP_RLWINM OPVCC(21,0,0,0)
  49. #define OP_SUBF OPVCC(31,40,0,0)
  50. #define oclass(v) ((v).class-1)
  51. int32_t oprrr(int), opirr(int), opload(int), opstore(int), oploadx(int), opstorex(int);
  52. int
  53. getmask(uint8_t *m, uint32_t v)
  54. {
  55. int i;
  56. m[0] = m[1] = 0;
  57. if(v != ~0L && v & (1<<31) && v & 1){ /* MB > ME */
  58. if(getmask(m, ~v)){
  59. i = m[0]; m[0] = m[1]+1; m[1] = i-1;
  60. return 1;
  61. }
  62. return 0;
  63. }
  64. for(i=0; i<32; i++)
  65. if(v & (1<<(31-i))){
  66. m[0] = i;
  67. do {
  68. m[1] = i;
  69. } while(++i<32 && (v & (1<<(31-i))) != 0);
  70. for(; i<32; i++)
  71. if(v & (1<<(31-i)))
  72. return 0;
  73. return 1;
  74. }
  75. return 0;
  76. }
  77. void
  78. maskgen(Prog *p, uint8_t *m, uint32_t v)
  79. {
  80. if(!getmask(m, v))
  81. diag("cannot generate mask #%lux\n%P", v, p);
  82. }
  83. static void
  84. reloc(Adr *a, int32_t pc, int sext)
  85. {
  86. if(a->name == D_EXTERN || a->name == D_STATIC)
  87. dynreloc(a->sym, pc, 1, 1, sext);
  88. }
  89. int
  90. asmout(Prog *p, Optab *o, int aflag)
  91. {
  92. int32_t o1, o2, o3, o4, o5, v, t;
  93. Prog *ct;
  94. int r, a;
  95. uint8_t mask[2];
  96. o1 = 0;
  97. o2 = 0;
  98. o3 = 0;
  99. o4 = 0;
  100. o5 = 0;
  101. switch(o->type) {
  102. default:
  103. if(aflag)
  104. return 0;
  105. diag("unknown type %d", o->type);
  106. if(!debug['a'])
  107. prasm(p);
  108. break;
  109. case 0: /* pseudo ops */
  110. if(aflag) {
  111. if(p->link) {
  112. if(p->as == ATEXT) {
  113. ct = curtext;
  114. o2 = autosize;
  115. curtext = p;
  116. autosize = p->to.offset + 4;
  117. o1 = asmout(p->link, oplook(p->link), aflag);
  118. curtext = ct;
  119. autosize = o2;
  120. } else
  121. o1 = asmout(p->link, oplook(p->link), aflag);
  122. }
  123. return o1;
  124. }
  125. break;
  126. case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
  127. if(p->to.reg == REGZERO && p->from.type == D_CONST) {
  128. v = regoff(&p->from);
  129. if(r0iszero && v != 0) {
  130. nerrors--;
  131. diag("literal operation on R0\n%P", p);
  132. }
  133. o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, v);
  134. break;
  135. }
  136. o1 = LOP_RRR(OP_OR, p->to.reg, p->from.reg, p->from.reg);
  137. break;
  138. case 2: /* int/cr/fp op Rb,[Ra],Rd */
  139. r = p->reg;
  140. if(r == NREG)
  141. r = p->to.reg;
  142. o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, p->from.reg);
  143. break;
  144. case 3: /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
  145. v = regoff(&p->from);
  146. r = p->from.reg;
  147. if(r == NREG)
  148. r = o->param;
  149. a = OP_ADDI;
  150. if(o->a1 == C_UCON) {
  151. a = OP_ADDIS;
  152. v >>= 16;
  153. }
  154. if(r0iszero && p->to.reg == 0 && (r != 0 || v != 0))
  155. diag("literal operation on R0\n%P", p);
  156. o1 = AOP_IRR(a, p->to.reg, r, v);
  157. break;
  158. case 4: /* add/mul $scon,[r1],r2 */
  159. v = regoff(&p->from);
  160. r = p->reg;
  161. if(r == NREG)
  162. r = p->to.reg;
  163. if(r0iszero && p->to.reg == 0)
  164. diag("literal operation on R0\n%P", p);
  165. o1 = AOP_IRR(opirr(p->as), p->to.reg, r, v);
  166. break;
  167. case 5: /* syscall */
  168. if(aflag)
  169. return 0;
  170. o1 = oprrr(p->as);
  171. break;
  172. case 6: /* logical op Rb,[Rs,]Ra; no literal */
  173. r = p->reg;
  174. if(r == NREG)
  175. r = p->to.reg;
  176. o1 = LOP_RRR(oprrr(p->as), p->to.reg, r, p->from.reg);
  177. break;
  178. case 7: /* mov r, soreg ==> stw o(r) */
  179. r = p->to.reg;
  180. if(r == NREG)
  181. r = o->param;
  182. v = regoff(&p->to);
  183. if(p->to.type == D_OREG && p->reg != NREG) {
  184. if(v)
  185. diag("illegal indexed instruction\n%P", p);
  186. o1 = AOP_RRR(opstorex(p->as), p->from.reg, p->reg, r);
  187. } else
  188. o1 = AOP_IRR(opstore(p->as), p->from.reg, r, v);
  189. break;
  190. case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
  191. r = p->from.reg;
  192. if(r == NREG)
  193. r = o->param;
  194. v = regoff(&p->from);
  195. if(p->from.type == D_OREG && p->reg != NREG) {
  196. if(v)
  197. diag("illegal indexed instruction\n%P", p);
  198. o1 = AOP_RRR(oploadx(p->as), p->to.reg, p->reg, r);
  199. } else
  200. o1 = AOP_IRR(opload(p->as), p->to.reg, r, v);
  201. break;
  202. case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
  203. r = p->from.reg;
  204. if(r == NREG)
  205. r = o->param;
  206. v = regoff(&p->from);
  207. if(p->from.type == D_OREG && p->reg != NREG) {
  208. if(v)
  209. diag("illegal indexed instruction\n%P", p);
  210. o1 = AOP_RRR(oploadx(p->as), p->to.reg, p->reg, r);
  211. } else
  212. o1 = AOP_IRR(opload(p->as), p->to.reg, r, v);
  213. o2 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
  214. break;
  215. case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
  216. r = p->reg;
  217. if(r == NREG)
  218. r = p->to.reg;
  219. o1 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, r);
  220. break;
  221. case 11: /* br/bl lbra */
  222. if(aflag)
  223. return 0;
  224. v = 0;
  225. if(p->cond == UP){
  226. if(p->to.sym->type != SUNDEF)
  227. diag("bad branch sym type");
  228. v = (uint32_t)p->to.sym->value >> (Roffset-2);
  229. dynreloc(p->to.sym, p->pc, 0, 0, 0);
  230. }
  231. else if(p->cond)
  232. v = p->cond->pc - p->pc;
  233. if(v & 03) {
  234. diag("odd branch target address\n%P", p);
  235. v &= ~03;
  236. }
  237. if(v < -(1L<<25) || v >= (1L<<25))
  238. diag("branch too far\n%P", p);
  239. o1 = OP_BR(opirr(p->as), v, 0);
  240. break;
  241. case 12: /* movb r,r (signed); extsb is on PowerPC but not POWER */
  242. o1 = LOP_RRR(OP_EXTSB, p->to.reg, p->from.reg, 0);
  243. break;
  244. case 13: /* mov[bh]z r,r; uses rlwinm not andi. to avoid changing CC */
  245. if(p->as == AMOVBZ)
  246. o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 24, 31);
  247. else if(p->as == AMOVH)
  248. o1 = LOP_RRR(OP_EXTSH, p->to.reg, p->from.reg, 0);
  249. else if(p->as == AMOVHZ)
  250. o1 = OP_RLW(OP_RLWINM, p->to.reg, p->from.reg, 0, 16, 31);
  251. else
  252. diag("internal: bad mov[bh]z\n%P", p);
  253. break;
  254. /*14 */
  255. case 17: /* bc bo,bi,lbra (same for now) */
  256. case 16: /* bc bo,bi,sbra */
  257. if(aflag)
  258. return 0;
  259. a = 0;
  260. if(p->from.type == D_CONST)
  261. a = regoff(&p->from);
  262. r = p->reg;
  263. if(r == NREG)
  264. r = 0;
  265. v = 0;
  266. if(p->cond)
  267. v = p->cond->pc - p->pc;
  268. if(v & 03) {
  269. diag("odd branch target address\n%P", p);
  270. v &= ~03;
  271. }
  272. if(v < -(1L<<16) || v >= (1L<<16))
  273. diag("branch too far\n%P", p);
  274. o1 = OP_BC(opirr(p->as), a, r, v, 0);
  275. break;
  276. case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
  277. if(aflag)
  278. return 0;
  279. if(p->as == ABC || p->as == ABCL)
  280. v = regoff(&p->to)&31L;
  281. else
  282. v = 20; /* unconditional */
  283. r = p->reg;
  284. if(r == NREG)
  285. r = 0;
  286. o1 = AOP_RRR(OP_MTSPR, p->to.reg, 0, 0) | ((D_LR&0x1f)<<16) | (((D_LR>>5)&0x1f)<<11);
  287. o2 = OPVCC(19, 16, 0, 0);
  288. if(p->as == ABL || p->as == ABCL)
  289. o2 |= 1;
  290. o2 = OP_BCR(o2, v, r);
  291. break;
  292. case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
  293. if(aflag)
  294. return 0;
  295. if(p->as == ABC || p->as == ABCL)
  296. v = regoff(&p->from)&31L;
  297. else
  298. v = 20; /* unconditional */
  299. r = p->reg;
  300. if(r == NREG)
  301. r = 0;
  302. switch(oclass(p->to)) {
  303. case C_CTR:
  304. o1 = OPVCC(19, 528, 0, 0);
  305. break;
  306. case C_LR:
  307. o1 = OPVCC(19, 16, 0, 0);
  308. break;
  309. default:
  310. diag("bad optab entry (18): %d\n%P", p->to.class, p);
  311. v = 0;
  312. }
  313. if(p->as == ABL || p->as == ABCL)
  314. o1 |= 1;
  315. o1 = OP_BCR(o1, v, r);
  316. break;
  317. case 19: /* mov $lcon,r ==> cau+or */
  318. v = regoff(&p->from);
  319. o1 = AOP_IRR(OP_ADDIS, p->to.reg, REGZERO, v>>16);
  320. o2 = LOP_IRR(OP_ORI, p->to.reg, p->to.reg, v);
  321. if(dlm)
  322. reloc(&p->from, p->pc, 0);
  323. break;
  324. case 20: /* add $ucon,,r */
  325. v = regoff(&p->from);
  326. r = p->reg;
  327. if(r == NREG)
  328. r = p->to.reg;
  329. if(p->as == AADD && (!r0iszero && p->reg == 0 || r0iszero && p->to.reg == 0))
  330. diag("literal operation on R0\n%P", p);
  331. o1 = AOP_IRR(opirr(p->as+AEND), p->to.reg, r, v>>16);
  332. break;
  333. case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
  334. v = regoff(&p->from);
  335. if(p->to.reg == REGTMP || p->reg == REGTMP)
  336. diag("cant synthesize large constant\n%P", p);
  337. o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
  338. o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, v);
  339. r = p->reg;
  340. if(r == NREG)
  341. r = p->to.reg;
  342. o3 = AOP_RRR(oprrr(p->as), p->to.reg, REGTMP, r);
  343. if(dlm)
  344. reloc(&p->from, p->pc, 0);
  345. break;
  346. case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */
  347. v = regoff(&p->from);
  348. if(p->to.reg == REGTMP || p->reg == REGTMP)
  349. diag("cant synthesize large constant\n%P", p);
  350. o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
  351. o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, v);
  352. r = p->reg;
  353. if(r == NREG)
  354. r = p->to.reg;
  355. o3 = LOP_RRR(oprrr(p->as), p->to.reg, REGTMP, r);
  356. if(dlm)
  357. reloc(&p->from, p->pc, 0);
  358. break;
  359. /*24*/
  360. case 26: /* mov $lsext/auto/oreg,,r2 ==> cau+add */
  361. v = regoff(&p->from);
  362. if(v & 0x8000L)
  363. v += 0x10000L;
  364. if(p->to.reg == REGTMP)
  365. diag("can't synthesize large constant\n%P", p);
  366. r = p->from.reg;
  367. if(r == NREG)
  368. r = o->param;
  369. o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
  370. o2 = AOP_IRR(OP_ADDI, p->to.reg, REGTMP, v);
  371. break;
  372. case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
  373. v = regoff(&p->from3);
  374. r = p->from.reg;
  375. o1 = AOP_IRR(opirr(p->as), p->to.reg, r, v);
  376. break;
  377. case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
  378. v = regoff(&p->from3);
  379. if(p->to.reg == REGTMP || p->from.reg == REGTMP)
  380. diag("can't synthesize large constant\n%P", p);
  381. o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
  382. o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, v);
  383. o3 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, REGTMP);
  384. if(dlm)
  385. reloc(&p->from3, p->pc, 0);
  386. break;
  387. /*29, 30, 31 */
  388. case 32: /* fmul frc,fra,frd */
  389. r = p->reg;
  390. if(r == NREG)
  391. r = p->to.reg;
  392. o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, 0)|((p->from.reg&31L)<<6);
  393. break;
  394. case 33: /* fabs [frb,]frd; fmr. frb,frd */
  395. r = p->from.reg;
  396. if(oclass(p->from) == C_NONE)
  397. r = p->to.reg;
  398. o1 = AOP_RRR(oprrr(p->as), p->to.reg, 0, r);
  399. break;
  400. case 34: /* FMADDx fra,frb,frc,frd (d=a*b+c) */
  401. o1 = AOP_RRR(oprrr(p->as), p->to.reg, p->from.reg, p->reg)|((p->from3.reg&31L)<<6);
  402. break;
  403. case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
  404. v = regoff(&p->to);
  405. if(v & 0x8000L)
  406. v += 0x10000L;
  407. r = p->to.reg;
  408. if(r == NREG)
  409. r = o->param;
  410. o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
  411. o2 = AOP_IRR(opstore(p->as), p->from.reg, REGTMP, v);
  412. break;
  413. case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
  414. v = regoff(&p->from);
  415. if(v & 0x8000L)
  416. v += 0x10000L;
  417. r = p->from.reg;
  418. if(r == NREG)
  419. r = o->param;
  420. o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
  421. o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
  422. break;
  423. case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
  424. v = regoff(&p->from);
  425. if(v & 0x8000L)
  426. v += 0x10000L;
  427. r = p->from.reg;
  428. if(r == NREG)
  429. r = o->param;
  430. o1 = AOP_IRR(OP_ADDIS, REGTMP, r, v>>16);
  431. o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
  432. o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
  433. break;
  434. case 40: /* word */
  435. if(aflag)
  436. return 0;
  437. o1 = regoff(&p->from);
  438. break;
  439. case 41: /* stswi */
  440. o1 = AOP_RRR(opirr(p->as), p->from.reg, p->to.reg, 0) | ((regoff(&p->from3)&0x7F)<<11);
  441. break;
  442. case 42: /* lswi */
  443. o1 = AOP_RRR(opirr(p->as), p->to.reg, p->from.reg, 0) | ((regoff(&p->from3)&0x7F)<<11);
  444. break;
  445. case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
  446. r = p->reg;
  447. if(r == NREG)
  448. r = 0;
  449. o1 = AOP_RRR(oprrr(p->as), 0, r, p->from.reg);
  450. break;
  451. case 44: /* indexed store */
  452. r = p->reg;
  453. if(r == NREG)
  454. r = 0;
  455. o1 = AOP_RRR(opstorex(p->as), p->from.reg, r, p->to.reg);
  456. break;
  457. case 45: /* indexed load */
  458. r = p->reg;
  459. if(r == NREG)
  460. r = 0;
  461. o1 = AOP_RRR(oploadx(p->as), p->to.reg, r, p->from.reg);
  462. break;
  463. case 46: /* plain op */
  464. o1 = oprrr(p->as);
  465. break;
  466. case 47: /* op Ra, Rd; also op [Ra,] Rd */
  467. r = p->from.reg;
  468. if(r == NREG)
  469. r = p->to.reg;
  470. o1 = AOP_RRR(oprrr(p->as), p->to.reg, r, 0);
  471. break;
  472. case 48: /* op Rs, Ra */
  473. r = p->from.reg;
  474. if(r == NREG)
  475. r = p->to.reg;
  476. o1 = LOP_RRR(oprrr(p->as), p->to.reg, r, 0);
  477. break;
  478. case 49: /* op Rb */
  479. o1 = AOP_RRR(oprrr(p->as), 0, 0, p->from.reg);
  480. break;
  481. /*50*/
  482. case 51: /* rem[u] r1[,r2],r3 */
  483. r = p->reg;
  484. if(r == NREG)
  485. r = p->to.reg;
  486. v = oprrr(p->as);
  487. t = v & ((1<<10)|1); /* OE|Rc */
  488. o1 = AOP_RRR(v&~t, REGTMP, r, p->from.reg);
  489. o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, p->from.reg);
  490. o3 = AOP_RRR(OP_SUBF|t, p->to.reg, REGTMP, r);
  491. break;
  492. case 52: /* mtfsbNx cr(n) */
  493. v = regoff(&p->from)&31L;
  494. o1 = AOP_RRR(oprrr(p->as), v, 0, 0);
  495. break;
  496. case 53: /* mffsX ,fr1 */
  497. o1 = AOP_RRR(OP_MFFS, p->to.reg, 0, 0);
  498. break;
  499. case 54: /* mov msr,r1; mov r1, msr*/
  500. if(oclass(p->from) == C_REG)
  501. o1 = AOP_RRR(OP_MTMSR, p->from.reg, 0, 0);
  502. else
  503. o1 = AOP_RRR(OP_MFMSR, p->to.reg, 0, 0);
  504. break;
  505. case 55: /* mov sreg,r1; mov r1,sreg */
  506. v = 0;
  507. if(p->from.type == D_SREG) {
  508. r = p->from.reg;
  509. o1 = OP_MFSR;
  510. if(r == NREG && p->reg != NREG) {
  511. r = 0;
  512. v = p->reg;
  513. o1 = OP_MFSRIN;
  514. }
  515. o1 = AOP_RRR(o1, p->to.reg, r&15L, v);
  516. } else {
  517. r = p->to.reg;
  518. o1 = OP_MTSR;
  519. if(r == NREG && p->reg != NREG) {
  520. r = 0;
  521. v = p->reg;
  522. o1 = OP_MTSRIN;
  523. }
  524. o1 = AOP_RRR(o1, p->from.reg, r&15L, v);
  525. }
  526. if(r == NREG)
  527. diag("illegal move indirect to/from segment register\n%P", p);
  528. break;
  529. case 56: /* sra $sh,[s,]a */
  530. v = regoff(&p->from);
  531. r = p->reg;
  532. if(r == NREG)
  533. r = p->to.reg;
  534. o1 = AOP_RRR(opirr(p->as), r, p->to.reg, v&31L);
  535. break;
  536. case 57: /* slw $sh,[s,]a -> rlwinm ... */
  537. v = regoff(&p->from);
  538. r = p->reg;
  539. if(r == NREG)
  540. r = p->to.reg;
  541. /*
  542. * Let user (gs) shoot himself in the foot.
  543. * qc has already complained.
  544. *
  545. if(v < 0 || v > 31)
  546. diag("illegal shift %ld\n%P", v, p);
  547. */
  548. if(v < 0)
  549. v = 0;
  550. else if(v > 32)
  551. v = 32;
  552. if(p->as == ASRW || p->as == ASRWCC) { /* shift right */
  553. mask[0] = v;
  554. mask[1] = 31;
  555. v = 32-v;
  556. } else {
  557. mask[0] = 0;
  558. mask[1] = 31-v;
  559. }
  560. o1 = OP_RLW(OP_RLWINM, p->to.reg, r, v, mask[0], mask[1]);
  561. if(p->as == ASLWCC || p->as == ASRWCC)
  562. o1 |= 1; /* Rc */
  563. break;
  564. case 58: /* logical $andcon,[s],a */
  565. v = regoff(&p->from);
  566. r = p->reg;
  567. if(r == NREG)
  568. r = p->to.reg;
  569. o1 = LOP_IRR(opirr(p->as), p->to.reg, r, v);
  570. break;
  571. case 59: /* or/and $ucon,,r */
  572. v = regoff(&p->from);
  573. r = p->reg;
  574. if(r == NREG)
  575. r = p->to.reg;
  576. o1 = LOP_IRR(opirr(p->as+AEND), p->to.reg, r, v>>16); /* oris, xoris, andis */
  577. break;
  578. case 60: /* tw to,a,b */
  579. r = regoff(&p->from)&31L;
  580. o1 = AOP_RRR(oprrr(p->as), r, p->reg, p->to.reg);
  581. break;
  582. case 61: /* tw to,a,$simm */
  583. r = regoff(&p->from)&31L;
  584. v = regoff(&p->to);
  585. o1 = AOP_IRR(opirr(p->as), r, p->reg, v);
  586. break;
  587. case 62: /* rlwmi $sh,s,$mask,a */
  588. v = regoff(&p->from);
  589. maskgen(p, mask, regoff(&p->from3));
  590. o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, v);
  591. o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
  592. break;
  593. case 63: /* rlwmi b,s,$mask,a */
  594. maskgen(p, mask, regoff(&p->from3));
  595. o1 = AOP_RRR(opirr(p->as), p->reg, p->to.reg, p->from.reg);
  596. o1 |= ((mask[0]&31L)<<6)|((mask[1]&31L)<<1);
  597. break;
  598. case 64: /* mtfsf fr[, $m] {,fpcsr} */
  599. if(p->from3.type != D_NONE)
  600. v = regoff(&p->from3)&255L;
  601. else
  602. v = 255;
  603. o1 = OP_MTFSF | (v<<17) | (p->from.reg<<11);
  604. break;
  605. case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
  606. if(p->to.reg == NREG)
  607. diag("must specify FPSCR(n)\n%P", p);
  608. o1 = OP_MTFSFI | ((p->to.reg&15L)<<23) | ((regoff(&p->from)&31L)<<12);
  609. break;
  610. case 66: /* mov spr,r1; mov r1,spr, also dcr */
  611. if(p->from.type == D_REG) {
  612. r = p->from.reg;
  613. v = p->to.offset;
  614. if(p->to.type == D_DCR) {
  615. if(p->to.reg != NREG) {
  616. o1 = OPVCC(31,387,0,0); /* mtdcrx */
  617. v = p->to.reg;
  618. }else
  619. o1 = OPVCC(31,451,0,0); /* mtdcr */
  620. }else
  621. o1 = OPVCC(31,467,0,0); /* mtspr */
  622. } else {
  623. r = p->to.reg;
  624. v = p->from.offset;
  625. if(p->from.type == D_DCR) {
  626. if(p->from.reg != NREG) {
  627. o1 = OPVCC(31,259,0,0); /* mfdcrx */
  628. v = p->from.reg;
  629. }else
  630. o1 = OPVCC(31,323,0,0); /* mfdcr */
  631. }else
  632. o1 = OPVCC(31,339,0,0); /* mfspr */
  633. }
  634. o1 = AOP_RRR(o1, r, 0, 0) | ((v&0x1f)<<16) | (((v>>5)&0x1f)<<11);
  635. break;
  636. case 67: /* mcrf crfD,crfS */
  637. if(p->from.type != D_CREG || p->from.reg == NREG ||
  638. p->to.type != D_CREG || p->to.reg == NREG)
  639. diag("illegal CR field number\n%P", p);
  640. o1 = AOP_RRR(OP_MCRF, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
  641. break;
  642. case 68: /* mfcr rD */
  643. if(p->from.type == D_CREG && p->from.reg != NREG)
  644. diag("must move whole CR to register\n%P", p);
  645. o1 = AOP_RRR(OP_MFCR, p->to.reg, 0, 0);
  646. break;
  647. case 69: /* mtcrf CRM,rS */
  648. if(p->from3.type != D_NONE) {
  649. if(p->to.reg != NREG)
  650. diag("can't use both mask and CR(n)\n%P", p);
  651. v = regoff(&p->from3) & 0xff;
  652. } else {
  653. if(p->to.reg == NREG)
  654. v = 0xff; /* CR */
  655. else
  656. v = 1<<(7-(p->to.reg&7)); /* CR(n) */
  657. }
  658. o1 = AOP_RRR(OP_MTCRF, p->from.reg, 0, 0) | (v<<12);
  659. break;
  660. case 70: /* [f]cmp r,r,cr*/
  661. if(p->reg == NREG)
  662. r = 0;
  663. else
  664. r = (p->reg&7)<<2;
  665. o1 = AOP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);
  666. break;
  667. case 71: /* cmp[l] r,i,cr*/
  668. if(p->reg == NREG)
  669. r = 0;
  670. else
  671. r = (p->reg&7)<<2;
  672. o1 = AOP_RRR(opirr(p->as), r, p->from.reg, 0) | (regoff(&p->to)&0xffff);
  673. break;
  674. case 72: /* mcrxr crfD */
  675. if(p->to.reg == NREG)
  676. diag("must move XER to CR(n)\n%P", p);
  677. o1 = AOP_RRR(OP_MCRXR, ((p->to.reg&7L)<<2), 0, 0);
  678. break;
  679. case 73: /* mcrfs crfD,crfS */
  680. if(p->from.type != D_FPSCR || p->from.reg == NREG ||
  681. p->to.type != D_CREG || p->to.reg == NREG)
  682. diag("illegal FPSCR/CR field number\n%P", p);
  683. o1 = AOP_RRR(OP_MCRFS, ((p->to.reg&7L)<<2), ((p->from.reg&7)<<2), 0);
  684. break;
  685. /* relocation operations */
  686. case 74:
  687. v = regoff(&p->to);
  688. o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
  689. o2 = AOP_IRR(opstore(p->as), p->from.reg, REGTMP, v);
  690. if(dlm)
  691. reloc(&p->to, p->pc, 1);
  692. break;
  693. case 75:
  694. v = regoff(&p->from);
  695. o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
  696. o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
  697. if(dlm)
  698. reloc(&p->from, p->pc, 1);
  699. break;
  700. case 76:
  701. v = regoff(&p->from);
  702. o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, v>>16);
  703. o2 = AOP_IRR(opload(p->as), p->to.reg, REGTMP, v);
  704. o3 = LOP_RRR(OP_EXTSB, p->to.reg, p->to.reg, 0);
  705. if(dlm)
  706. reloc(&p->from, p->pc, 1);
  707. break;
  708. }
  709. if(aflag)
  710. return o1;
  711. v = p->pc;
  712. switch(o->size) {
  713. default:
  714. if(debug['a'])
  715. Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
  716. break;
  717. case 4:
  718. if(debug['a'])
  719. Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
  720. lput(o1);
  721. break;
  722. case 8:
  723. if(debug['a'])
  724. Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
  725. lput(o1);
  726. lput(o2);
  727. break;
  728. case 12:
  729. if(debug['a'])
  730. Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
  731. lput(o1);
  732. lput(o2);
  733. lput(o3);
  734. break;
  735. case 16:
  736. if(debug['a'])
  737. Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
  738. v, o1, o2, o3, o4, p);
  739. lput(o1);
  740. lput(o2);
  741. lput(o3);
  742. lput(o4);
  743. break;
  744. case 20:
  745. if(debug['a'])
  746. Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
  747. v, o1, o2, o3, o4, o5, p);
  748. lput(o1);
  749. lput(o2);
  750. lput(o3);
  751. lput(o4);
  752. lput(o5);
  753. break;
  754. }
  755. return 0;
  756. }
  757. int32_t
  758. oprrr(int a)
  759. {
  760. switch(a) {
  761. case AADD: return OPVCC(31,266,0,0);
  762. case AADDCC: return OPVCC(31,266,0,1);
  763. case AADDV: return OPVCC(31,266,1,0);
  764. case AADDVCC: return OPVCC(31,266,1,1);
  765. case AADDC: return OPVCC(31,10,0,0);
  766. case AADDCCC: return OPVCC(31,10,0,1);
  767. case AADDCV: return OPVCC(31,10,1,0);
  768. case AADDCVCC: return OPVCC(31,10,1,1);
  769. case AADDE: return OPVCC(31,138,0,0);
  770. case AADDECC: return OPVCC(31,138,0,1);
  771. case AADDEV: return OPVCC(31,138,1,0);
  772. case AADDEVCC: return OPVCC(31,138,1,1);
  773. case AADDME: return OPVCC(31,234,0,0);
  774. case AADDMECC: return OPVCC(31,234,0,1);
  775. case AADDMEV: return OPVCC(31,234,1,0);
  776. case AADDMEVCC: return OPVCC(31,234,1,1);
  777. case AADDZE: return OPVCC(31,202,0,0);
  778. case AADDZECC: return OPVCC(31,202,0,1);
  779. case AADDZEV: return OPVCC(31,202,1,0);
  780. case AADDZEVCC: return OPVCC(31,202,1,1);
  781. case AAND: return OPVCC(31,28,0,0);
  782. case AANDCC: return OPVCC(31,28,0,1);
  783. case AANDN: return OPVCC(31,60,0,0);
  784. case AANDNCC: return OPVCC(31,60,0,1);
  785. case ACMP: return OPVCC(31,0,0,0);
  786. case ACMPU: return OPVCC(31,32,0,0);
  787. case ACNTLZW: return OPVCC(31,26,0,0);
  788. case ACNTLZWCC: return OPVCC(31,26,0,1);
  789. case ACRAND: return OPVCC(19,257,0,0);
  790. case ACRANDN: return OPVCC(19,129,0,0);
  791. case ACREQV: return OPVCC(19,289,0,0);
  792. case ACRNAND: return OPVCC(19,225,0,0);
  793. case ACRNOR: return OPVCC(19,33,0,0);
  794. case ACROR: return OPVCC(19,449,0,0);
  795. case ACRORN: return OPVCC(19,417,0,0);
  796. case ACRXOR: return OPVCC(19,193,0,0);
  797. case ADCBF: return OPVCC(31,86,0,0);
  798. case ADCBI: return OPVCC(31,470,0,0);
  799. case ADCBST: return OPVCC(31,54,0,0);
  800. case ADCBT: return OPVCC(31,278,0,0);
  801. case ADCBTST: return OPVCC(31,246,0,0);
  802. case ADCBZ: return OPVCC(31,1014,0,0);
  803. case AREM:
  804. case ADIVW: return OPVCC(31,491,0,0);
  805. case AREMCC:
  806. case ADIVWCC: return OPVCC(31,491,0,1);
  807. case AREMV:
  808. case ADIVWV: return OPVCC(31,491,1,0);
  809. case AREMVCC:
  810. case ADIVWVCC: return OPVCC(31,491,1,1);
  811. case AREMU:
  812. case ADIVWU: return OPVCC(31,459,0,0);
  813. case AREMUCC:
  814. case ADIVWUCC: return OPVCC(31,459,0,1);
  815. case AREMUV:
  816. case ADIVWUV: return OPVCC(31,459,1,0);
  817. case AREMUVCC:
  818. case ADIVWUVCC: return OPVCC(31,459,1,1);
  819. case AEIEIO: return OPVCC(31,854,0,0);
  820. case AEQV: return OPVCC(31,284,0,0);
  821. case AEQVCC: return OPVCC(31,284,0,1);
  822. case AEXTSB: return OPVCC(31,954,0,0);
  823. case AEXTSBCC: return OPVCC(31,954,0,1);
  824. case AEXTSH: return OPVCC(31,922,0,0);
  825. case AEXTSHCC: return OPVCC(31,922,0,1);
  826. case AFABS: return OPVCC(63,264,0,0);
  827. case AFABSCC: return OPVCC(63,264,0,1);
  828. case AFADD: return OPVCC(63,21,0,0);
  829. case AFADDCC: return OPVCC(63,21,0,1);
  830. case AFADDS: return OPVCC(59,21,0,0);
  831. case AFADDSCC: return OPVCC(59,21,0,1);
  832. case AFCMPO: return OPVCC(63,32,0,0);
  833. case AFCMPU: return OPVCC(63,0,0,0);
  834. case AFCTIW: return OPVCC(63,14,0,0);
  835. case AFCTIWCC: return OPVCC(63,14,0,1);
  836. case AFCTIWZ: return OPVCC(63,15,0,0);
  837. case AFCTIWZCC: return OPVCC(63,15,0,1);
  838. case AFDIV: return OPVCC(63,18,0,0);
  839. case AFDIVCC: return OPVCC(63,18,0,1);
  840. case AFDIVS: return OPVCC(59,18,0,0);
  841. case AFDIVSCC: return OPVCC(59,18,0,1);
  842. case AFMADD: return OPVCC(63,29,0,0);
  843. case AFMADDCC: return OPVCC(63,29,0,1);
  844. case AFMADDS: return OPVCC(59,29,0,0);
  845. case AFMADDSCC: return OPVCC(59,29,0,1);
  846. case AFMOVS:
  847. case AFMOVD: return OPVCC(63,72,0,0); /* load */
  848. case AFMOVDCC: return OPVCC(63,72,0,1);
  849. case AFMSUB: return OPVCC(63,28,0,0);
  850. case AFMSUBCC: return OPVCC(63,28,0,1);
  851. case AFMSUBS: return OPVCC(59,28,0,0);
  852. case AFMSUBSCC: return OPVCC(59,28,0,1);
  853. case AFMUL: return OPVCC(63,25,0,0);
  854. case AFMULCC: return OPVCC(63,25,0,1);
  855. case AFMULS: return OPVCC(59,25,0,0);
  856. case AFMULSCC: return OPVCC(59,25,0,1);
  857. case AFNABS: return OPVCC(63,136,0,0);
  858. case AFNABSCC: return OPVCC(63,136,0,1);
  859. case AFNEG: return OPVCC(63,40,0,0);
  860. case AFNEGCC: return OPVCC(63,40,0,1);
  861. case AFNMADD: return OPVCC(63,31,0,0);
  862. case AFNMADDCC: return OPVCC(63,31,0,1);
  863. case AFNMADDS: return OPVCC(59,31,0,0);
  864. case AFNMADDSCC: return OPVCC(59,31,0,1);
  865. case AFNMSUB: return OPVCC(63,30,0,0);
  866. case AFNMSUBCC: return OPVCC(63,30,0,1);
  867. case AFNMSUBS: return OPVCC(59,30,0,0);
  868. case AFNMSUBSCC: return OPVCC(59,30,0,1);
  869. case AFRES: return OPVCC(59,24,0,0);
  870. case AFRESCC: return OPVCC(59,24,0,1);
  871. case AFRSP: return OPVCC(63,12,0,0);
  872. case AFRSPCC: return OPVCC(63,12,0,1);
  873. case AFRSQRTE: return OPVCC(63,26,0,0);
  874. case AFRSQRTECC: return OPVCC(63,26,0,1);
  875. case AFSEL: return OPVCC(63,23,0,0);
  876. case AFSELCC: return OPVCC(63,23,0,1);
  877. case AFSQRT: return OPVCC(63,22,0,0);
  878. case AFSQRTCC: return OPVCC(63,22,0,1);
  879. case AFSQRTS: return OPVCC(59,22,0,0);
  880. case AFSQRTSCC: return OPVCC(59,22,0,1);
  881. case AFSUB: return OPVCC(63,20,0,0);
  882. case AFSUBCC: return OPVCC(63,20,0,1);
  883. case AFSUBS: return OPVCC(59,20,0,0);
  884. case AFSUBSCC: return OPVCC(59,20,0,1);
  885. /* fp2 */
  886. case AFPMUL: return OPVCC(0,8,0,0);
  887. case AFXMUL: return OPVCC(0,9,0,0);
  888. case AFXPMUL: return OPVCC(0,10,0,0);
  889. case AFXSMUL: return OPVCC(0,11,0,0);
  890. case AFPADD: return OPVCC(0,12,0,0);
  891. case AFPSUB: return OPVCC(0,13,0,0);
  892. case AFPRE: return OPVCC(0,14,0,0);
  893. case AFPRSQRTE: return OPVCC(0,15,0,0);
  894. case AFPMADD: return OPVCC(0,16,0,0);
  895. case AFXMADD: return OPVCC(0,17,0,0);
  896. case AFXCPMADD: return OPVCC(0,18,0,0);
  897. case AFXCSMADD: return OPVCC(0,19,0,0);
  898. case AFPNMADD: return OPVCC(0,20,0,0);
  899. case AFXNMADD: return OPVCC(0,21,0,0);
  900. case AFXCPNMADD: return OPVCC(0,22,0,0);
  901. case AFXCSNMADD: return OPVCC(0,23,0,0);
  902. case AFPMSUB: return OPVCC(0,24,0,0);
  903. case AFXMSUB: return OPVCC(0,25,0,0);
  904. case AFXCPMSUB: return OPVCC(0,26,0,0);
  905. case AFXCSMSUB: return OPVCC(0,27,0,0);
  906. case AFPNMSUB: return OPVCC(0,28,0,0);
  907. case AFXNMSUB: return OPVCC(0,29,0,0);
  908. case AFXCPNMSUB: return OPVCC(0,30,0,0);
  909. case AFXCSNMSUB: return OPVCC(0,31,0,0);
  910. case AFPABS: return OPVCC(0,96,0,0);
  911. case AFPNEG: return OPVCC(0,160,0,0);
  912. case AFPRSP: return OPVCC(0,192,0,0);
  913. case AFPNABS: return OPVCC(0,224,0,0);
  914. case AFSCMP: return OPVCC(0,320,0,0)|(3<<21);
  915. case AFSABS: return OPVCC(0,352,0,0);
  916. case AFSNEG: return OPVCC(0,416,0,0);
  917. case AFSNABS: return OPVCC(0,480,0,0);
  918. case AFPCTIW: return OPVCC(0,576,0,0);
  919. case AFPCTIWZ: return OPVCC(0,704,0,0);
  920. case AFPMOVD: return OPVCC(0,32,0,0); /* fpmr */
  921. case AFSMOVD: return OPVCC(0,288,0,0); /* fsmr */
  922. case AFXMOVD: return OPVCC(0,544,0,0); /* fxmr */
  923. case AFMOVSPD: return OPVCC(0,800,0,0); /* fsmtp */
  924. case AFMOVPSD: return OPVCC(0,928,0,0); /* fsmfp */
  925. case AFXCPNPMA: return OPVCC(4,24,0,0);
  926. case AFXCSNPMA: return OPVCC(4,25,0,0);
  927. case AFXCPNSMA: return OPVCC(4,26,0,0);
  928. case AFXCSNSMA: return OPVCC(4,27,0,0);
  929. case AFXCXNPMA: return OPVCC(4,29,0,0);
  930. case AFXCXNSMA: return OPVCC(4,30,0,0);
  931. case AFXCXMA: return OPVCC(4,28,0,0);
  932. case AFXCXNMS: return OPVCC(4,31,0,0);
  933. case AICBI: return OPVCC(31,982,0,0);
  934. case AISYNC: return OPVCC(19,150,0,0);
  935. case AMTFSB0: return OPVCC(63,70,0,0);
  936. case AMTFSB0CC: return OPVCC(63,70,0,1);
  937. case AMTFSB1: return OPVCC(63,38,0,0);
  938. case AMTFSB1CC: return OPVCC(63,38,0,1);
  939. case AMULHW: return OPVCC(31,75,0,0);
  940. case AMULHWCC: return OPVCC(31,75,0,1);
  941. case AMULHWU: return OPVCC(31,11,0,0);
  942. case AMULHWUCC: return OPVCC(31,11,0,1);
  943. case AMULLW: return OPVCC(31,235,0,0);
  944. case AMULLWCC: return OPVCC(31,235,0,1);
  945. case AMULLWV: return OPVCC(31,235,1,0);
  946. case AMULLWVCC: return OPVCC(31,235,1,1);
  947. /* the following group is only available on IBM embedded powerpc */
  948. case AMACCHW: return OPVCC(4,172,0,0);
  949. case AMACCHWCC: return OPVCC(4,172,0,1);
  950. case AMACCHWS: return OPVCC(4,236,0,0);
  951. case AMACCHWSCC: return OPVCC(4,236,0,1);
  952. case AMACCHWSU: return OPVCC(4,204,0,0);
  953. case AMACCHWSUCC: return OPVCC(4,204,0,1);
  954. case AMACCHWSUV: return OPVCC(4,204,1,0);
  955. case AMACCHWSUVCC: return OPVCC(4,204,1,1);
  956. case AMACCHWSV: return OPVCC(4,236,1,0);
  957. case AMACCHWSVCC: return OPVCC(4,236,1,1);
  958. case AMACCHWU: return OPVCC(4,140,0,0);
  959. case AMACCHWUCC: return OPVCC(4,140,0,1);
  960. case AMACCHWUV: return OPVCC(4,140,1,0);
  961. case AMACCHWUVCC: return OPVCC(4,140,1,1);
  962. case AMACCHWV: return OPVCC(4,172,1,0);
  963. case AMACCHWVCC: return OPVCC(4,172,1,1);
  964. case AMACHHW: return OPVCC(4,44,0,0);
  965. case AMACHHWCC: return OPVCC(4,44,0,1);
  966. case AMACHHWS: return OPVCC(4,108,0,0);
  967. case AMACHHWSCC: return OPVCC(4,108,0,1);
  968. case AMACHHWSU: return OPVCC(4,76,0,0);
  969. case AMACHHWSUCC: return OPVCC(4,76,0,1);
  970. case AMACHHWSUV: return OPVCC(4,76,1,0);
  971. case AMACHHWSUVCC: return OPVCC(4,76,1,1);
  972. case AMACHHWSV: return OPVCC(4,108,1,0);
  973. case AMACHHWSVCC: return OPVCC(4,108,1,1);
  974. case AMACHHWU: return OPVCC(4,12,0,0);
  975. case AMACHHWUCC: return OPVCC(4,12,0,1);
  976. case AMACHHWUV: return OPVCC(4,12,1,0);
  977. case AMACHHWUVCC: return OPVCC(4,12,1,1);
  978. case AMACHHWV: return OPVCC(4,44,1,0);
  979. case AMACHHWVCC: return OPVCC(4,44,1,1);
  980. case AMACLHW: return OPVCC(4,428,0,0);
  981. case AMACLHWCC: return OPVCC(4,428,0,1);
  982. case AMACLHWS: return OPVCC(4,492,0,0);
  983. case AMACLHWSCC: return OPVCC(4,492,0,1);
  984. case AMACLHWSU: return OPVCC(4,460,0,0);
  985. case AMACLHWSUCC: return OPVCC(4,460,0,1);
  986. case AMACLHWSUV: return OPVCC(4,460,1,0);
  987. case AMACLHWSUVCC: return OPVCC(4,460,1,1);
  988. case AMACLHWSV: return OPVCC(4,492,1,0);
  989. case AMACLHWSVCC: return OPVCC(4,492,1,1);
  990. case AMACLHWU: return OPVCC(4,396,0,0);
  991. case AMACLHWUCC: return OPVCC(4,396,0,1);
  992. case AMACLHWUV: return OPVCC(4,396,1,0);
  993. case AMACLHWUVCC: return OPVCC(4,396,1,1);
  994. case AMACLHWV: return OPVCC(4,428,1,0);
  995. case AMACLHWVCC: return OPVCC(4,428,1,1);
  996. case AMULCHW: return OPVCC(4,168,0,0);
  997. case AMULCHWCC: return OPVCC(4,168,0,1);
  998. case AMULCHWU: return OPVCC(4,136,0,0);
  999. case AMULCHWUCC: return OPVCC(4,136,0,1);
  1000. case AMULHHW: return OPVCC(4,40,0,0);
  1001. case AMULHHWCC: return OPVCC(4,40,0,1);
  1002. case AMULHHWU: return OPVCC(4,8,0,0);
  1003. case AMULHHWUCC: return OPVCC(4,8,0,1);
  1004. case AMULLHW: return OPVCC(4,424,0,0);
  1005. case AMULLHWCC: return OPVCC(4,424,0,1);
  1006. case AMULLHWU: return OPVCC(4,392,0,0);
  1007. case AMULLHWUCC: return OPVCC(4,392,0,1);
  1008. case ANMACCHW: return OPVCC(4,174,0,0);
  1009. case ANMACCHWCC: return OPVCC(4,174,0,1);
  1010. case ANMACCHWS: return OPVCC(4,238,0,0);
  1011. case ANMACCHWSCC: return OPVCC(4,238,0,1);
  1012. case ANMACCHWSV: return OPVCC(4,238,1,0);
  1013. case ANMACCHWSVCC: return OPVCC(4,238,1,1);
  1014. case ANMACCHWV: return OPVCC(4,174,1,0);
  1015. case ANMACCHWVCC: return OPVCC(4,174,1,1);
  1016. case ANMACHHW: return OPVCC(4,46,0,0);
  1017. case ANMACHHWCC: return OPVCC(4,46,0,1);
  1018. case ANMACHHWS: return OPVCC(4,110,0,0);
  1019. case ANMACHHWSCC: return OPVCC(4,110,0,1);
  1020. case ANMACHHWSV: return OPVCC(4,110,1,0);
  1021. case ANMACHHWSVCC: return OPVCC(4,110,1,1);
  1022. case ANMACHHWV: return OPVCC(4,46,1,0);
  1023. case ANMACHHWVCC: return OPVCC(4,46,1,1);
  1024. case ANMACLHW: return OPVCC(4,430,0,0);
  1025. case ANMACLHWCC: return OPVCC(4,430,0,1);
  1026. case ANMACLHWS: return OPVCC(4,494,0,0);
  1027. case ANMACLHWSCC: return OPVCC(4,494,0,1);
  1028. case ANMACLHWSV: return OPVCC(4,494,1,0);
  1029. case ANMACLHWSVCC: return OPVCC(4,494,1,1);
  1030. case ANMACLHWV: return OPVCC(4,430,1,0);
  1031. case ANMACLHWVCC: return OPVCC(4,430,1,1);
  1032. case ANAND: return OPVCC(31,476,0,0);
  1033. case ANANDCC: return OPVCC(31,476,0,1);
  1034. case ANEG: return OPVCC(31,104,0,0);
  1035. case ANEGCC: return OPVCC(31,104,0,1);
  1036. case ANEGV: return OPVCC(31,104,1,0);
  1037. case ANEGVCC: return OPVCC(31,104,1,1);
  1038. case ANOR: return OPVCC(31,124,0,0);
  1039. case ANORCC: return OPVCC(31,124,0,1);
  1040. case AOR: return OPVCC(31,444,0,0);
  1041. case AORCC: return OPVCC(31,444,0,1);
  1042. case AORN: return OPVCC(31,412,0,0);
  1043. case AORNCC: return OPVCC(31,412,0,1);
  1044. case ARFI: return OPVCC(19,50,0,0);
  1045. case ARFCI: return OPVCC(19,51,0,0);
  1046. case ARLWMI: return OPVCC(20,0,0,0);
  1047. case ARLWMICC: return OPVCC(20,0,0,1);
  1048. case ARLWNM: return OPVCC(23,0,0,0);
  1049. case ARLWNMCC: return OPVCC(23,0,0,1);
  1050. case ASYSCALL: return OPVCC(17,1,0,0);
  1051. case ASLW: return OPVCC(31,24,0,0);
  1052. case ASLWCC: return OPVCC(31,24,0,1);
  1053. case ASRAW: return OPVCC(31,792,0,0);
  1054. case ASRAWCC: return OPVCC(31,792,0,1);
  1055. case ASRW: return OPVCC(31,536,0,0);
  1056. case ASRWCC: return OPVCC(31,536,0,1);
  1057. case ASUB: return OPVCC(31,40,0,0);
  1058. case ASUBCC: return OPVCC(31,40,0,1);
  1059. case ASUBV: return OPVCC(31,40,1,0);
  1060. case ASUBVCC: return OPVCC(31,40,1,1);
  1061. case ASUBC: return OPVCC(31,8,0,0);
  1062. case ASUBCCC: return OPVCC(31,8,0,1);
  1063. case ASUBCV: return OPVCC(31,8,1,0);
  1064. case ASUBCVCC: return OPVCC(31,8,1,1);
  1065. case ASUBE: return OPVCC(31,136,0,0);
  1066. case ASUBECC: return OPVCC(31,136,0,1);
  1067. case ASUBEV: return OPVCC(31,136,1,0);
  1068. case ASUBEVCC: return OPVCC(31,136,1,1);
  1069. case ASUBME: return OPVCC(31,232,0,0);
  1070. case ASUBMECC: return OPVCC(31,232,0,1);
  1071. case ASUBMEV: return OPVCC(31,232,1,0);
  1072. case ASUBMEVCC: return OPVCC(31,232,1,1);
  1073. case ASUBZE: return OPVCC(31,200,0,0);
  1074. case ASUBZECC: return OPVCC(31,200,0,1);
  1075. case ASUBZEV: return OPVCC(31,200,1,0);
  1076. case ASUBZEVCC: return OPVCC(31,200,1,1);
  1077. case ASYNC: return OPVCC(31,598,0,0);
  1078. case ATLBIE: return OPVCC(31,306,0,0);
  1079. case ATW: return OPVCC(31,4,0,0);
  1080. case AXOR: return OPVCC(31,316,0,0);
  1081. case AXORCC: return OPVCC(31,316,0,1);
  1082. }
  1083. diag("bad r/r opcode %A", a);
  1084. return 0;
  1085. }
  1086. int32_t
  1087. opirr(int a)
  1088. {
  1089. switch(a) {
  1090. case AADD: return OPVCC(14,0,0,0);
  1091. case AADDC: return OPVCC(12,0,0,0);
  1092. case AADDCCC: return OPVCC(13,0,0,0);
  1093. case AADD+AEND: return OPVCC(15,0,0,0); /* ADDIS/CAU */
  1094. case AANDCC: return OPVCC(28,0,0,0);
  1095. case AANDCC+AEND: return OPVCC(29,0,0,0); /* ANDIS./ANDIU. */
  1096. case ABR: return OPVCC(18,0,0,0);
  1097. case ABL: return OPVCC(18,0,0,0) | 1;
  1098. case ABC: return OPVCC(16,0,0,0);
  1099. case ABCL: return OPVCC(16,0,0,0) | 1;
  1100. case ABEQ: return AOP_RRR(16<<26,12,2,0);
  1101. case ABGE: return AOP_RRR(16<<26,4,0,0);
  1102. case ABGT: return AOP_RRR(16<<26,12,1,0);
  1103. case ABLE: return AOP_RRR(16<<26,4,1,0);
  1104. case ABLT: return AOP_RRR(16<<26,12,0,0);
  1105. case ABNE: return AOP_RRR(16<<26,4,2,0);
  1106. case ABVC: return AOP_RRR(16<<26,4,3,0);
  1107. case ABVS: return AOP_RRR(16<<26,12,3,0);
  1108. case ACMP: return OPVCC(11,0,0,0);
  1109. case ACMPU: return OPVCC(10,0,0,0);
  1110. case ALSW: return OPVCC(31,597,0,0);
  1111. case AMULLW: return OPVCC(7,0,0,0);
  1112. case AOR: return OPVCC(24,0,0,0);
  1113. case AOR+AEND: return OPVCC(25,0,0,0); /* ORIS/ORIU */
  1114. case ARLWMI: return OPVCC(20,0,0,0); /* rlwimi */
  1115. case ARLWMICC: return OPVCC(20,0,0,1);
  1116. case ARLWNM: return OPVCC(21,0,0,0); /* rlwinm */
  1117. case ARLWNMCC: return OPVCC(21,0,0,1);
  1118. case ASRAW: return OPVCC(31,824,0,0);
  1119. case ASRAWCC: return OPVCC(31,824,0,1);
  1120. case ASTSW: return OPVCC(31,725,0,0);
  1121. case ASUBC: return OPVCC(8,0,0,0);
  1122. case ATW: return OPVCC(3,0,0,0);
  1123. case AXOR: return OPVCC(26,0,0,0); /* XORIL */
  1124. case AXOR+AEND: return OPVCC(27,0,0,0); /* XORIU */
  1125. }
  1126. diag("bad opcode i/r %A", a);
  1127. return 0;
  1128. }
  1129. /*
  1130. * load o(a),d
  1131. */
  1132. int32_t
  1133. opload(int a)
  1134. {
  1135. switch(a) {
  1136. case AMOVW: return OPVCC(32,0,0,0); /* lwz */
  1137. case AMOVWU: return OPVCC(33,0,0,0); /* lwzu */
  1138. case AMOVB:
  1139. case AMOVBZ: return OPVCC(34,0,0,0); /* load */
  1140. case AMOVBU:
  1141. case AMOVBZU: return OPVCC(35,0,0,0);
  1142. case AFMOVD: return OPVCC(50,0,0,0);
  1143. case AFMOVDU: return OPVCC(51,0,0,0);
  1144. case AFMOVS: return OPVCC(48,0,0,0);
  1145. case AFMOVSU: return OPVCC(49,0,0,0);
  1146. case AMOVH: return OPVCC(42,0,0,0);
  1147. case AMOVHU: return OPVCC(43,0,0,0);
  1148. case AMOVHZ: return OPVCC(40,0,0,0);
  1149. case AMOVHZU: return OPVCC(41,0,0,0);
  1150. case AMOVMW: return OPVCC(46,0,0,0); /* lmw */
  1151. }
  1152. diag("bad load opcode %A", a);
  1153. return 0;
  1154. }
  1155. /*
  1156. * indexed load a(b),d
  1157. */
  1158. int32_t
  1159. oploadx(int a)
  1160. {
  1161. switch(a) {
  1162. case AMOVW: return OPVCC(31,23,0,0); /* lwzx */
  1163. case AMOVWU: return OPVCC(31,55,0,0); /* lwzux */
  1164. case AMOVB:
  1165. case AMOVBZ: return OPVCC(31,87,0,0); /* lbzx */
  1166. case AMOVBU:
  1167. case AMOVBZU: return OPVCC(31,119,0,0); /* lbzux */
  1168. case AFMOVD: return OPVCC(31,599,0,0); /* lfdx */
  1169. case AFMOVDU: return OPVCC(31,631,0,0); /* lfdux */
  1170. case AFMOVS: return OPVCC(31,535,0,0); /* lfsx */
  1171. case AFMOVSU: return OPVCC(31,567,0,0); /* lfsux */
  1172. case AMOVH: return OPVCC(31,343,0,0); /* lhax */
  1173. case AMOVHU: return OPVCC(31,375,0,0); /* lhaux */
  1174. case AMOVHBR: return OPVCC(31,790,0,0); /* lhbrx */
  1175. case AMOVWBR: return OPVCC(31,534,0,0); /* lwbrx */
  1176. case AMOVHZ: return OPVCC(31,279,0,0); /* lhzx */
  1177. case AMOVHZU: return OPVCC(31,311,0,0); /* lhzux */
  1178. case AECIWX: return OPVCC(31,310,0,0); /* eciwx */
  1179. case ALWAR: return OPVCC(31,20,0,0); /* lwarx */
  1180. case ALSW: return OPVCC(31,533,0,0); /* lswx */
  1181. case AFSMOVS: return OPVCC(31,142,0,0); /* lfssx */
  1182. case AFSMOVSU: return OPVCC(31,174,0,0); /* lfssux */
  1183. case AFSMOVD: return OPVCC(31,206,0,0); /* lfsdx */
  1184. case AFSMOVDU: return OPVCC(31,238,0,0); /* lfsdux */
  1185. case AFXMOVS: return OPVCC(31,270,0,0); /* lfxsx */
  1186. case AFXMOVSU: return OPVCC(31,302,0,0); /* lfxsux */
  1187. case AFXMOVD: return OPVCC(31,334,0,0); /* lfxdx */
  1188. case AFXMOVDU: return OPVCC(31,366,0,0); /* lfxdux */
  1189. case AFPMOVS: return OPVCC(31,398,0,0); /* lfpsx */
  1190. case AFPMOVSU: return OPVCC(31,430,0,0); /* lfpsux */
  1191. case AFPMOVD: return OPVCC(31,462,0,0); /* lfpdx */
  1192. case AFPMOVDU: return OPVCC(31,494,0,0); /* lfpdux */
  1193. }
  1194. diag("bad loadx opcode %A", a);
  1195. return 0;
  1196. }
  1197. /*
  1198. * store s,o(d)
  1199. */
  1200. int32_t
  1201. opstore(int a)
  1202. {
  1203. switch(a) {
  1204. case AMOVB:
  1205. case AMOVBZ: return OPVCC(38,0,0,0); /* stb */
  1206. case AMOVBU:
  1207. case AMOVBZU: return OPVCC(39,0,0,0); /* stbu */
  1208. case AFMOVD: return OPVCC(54,0,0,0); /* stfd */
  1209. case AFMOVDU: return OPVCC(55,0,0,0); /* stfdu */
  1210. case AFMOVS: return OPVCC(52,0,0,0); /* stfs */
  1211. case AFMOVSU: return OPVCC(53,0,0,0); /* stfsu */
  1212. case AMOVHZ:
  1213. case AMOVH: return OPVCC(44,0,0,0); /* sth */
  1214. case AMOVHZU:
  1215. case AMOVHU: return OPVCC(45,0,0,0); /* sthu */
  1216. case AMOVMW: return OPVCC(47,0,0,0); /* stmw */
  1217. case ASTSW: return OPVCC(31,725,0,0); /* stswi */
  1218. case AMOVW: return OPVCC(36,0,0,0); /* stw */
  1219. case AMOVWU: return OPVCC(37,0,0,0); /* stwu */
  1220. }
  1221. diag("unknown store opcode %A", a);
  1222. return 0;
  1223. }
  1224. /*
  1225. * indexed store s,a(b)
  1226. */
  1227. int32_t
  1228. opstorex(int a)
  1229. {
  1230. switch(a) {
  1231. case AMOVB:
  1232. case AMOVBZ: return OPVCC(31,215,0,0); /* stbx */
  1233. case AMOVBU:
  1234. case AMOVBZU: return OPVCC(31,247,0,0); /* stbux */
  1235. case AFMOVD: return OPVCC(31,727,0,0); /* stfdx */
  1236. case AFMOVDU: return OPVCC(31,759,0,0); /* stfdux */
  1237. case AFMOVS: return OPVCC(31,663,0,0); /* stfsx */
  1238. case AFMOVSU: return OPVCC(31,695,0,0); /* stfsux */
  1239. case AMOVHZ:
  1240. case AMOVH: return OPVCC(31,407,0,0); /* sthx */
  1241. case AMOVHBR: return OPVCC(31,918,0,0); /* sthbrx */
  1242. case AMOVHZU:
  1243. case AMOVHU: return OPVCC(31,439,0,0); /* sthux */
  1244. case AMOVW: return OPVCC(31,151,0,0); /* stwx */
  1245. case AMOVWU: return OPVCC(31,183,0,0); /* stwux */
  1246. case ASTSW: return OPVCC(31,661,0,0); /* stswx */
  1247. case AMOVWBR: return OPVCC(31,662,0,0); /* stwbrx */
  1248. case ASTWCCC: return OPVCC(31,150,0,1); /* stwcx. */
  1249. case AECOWX: return OPVCC(31,438,0,0); /* ecowx */
  1250. case AFSMOVS: return OPVCC(31,654,0,0); /* stfssx */
  1251. /* case AFSMOVSU: return OPVCC(31,yy,0,0); */ /* stfssux not known */
  1252. /* case AFSMOVD: return OPVCC(31,yy,0,0); */ /* stfsdx not known */
  1253. case AFSMOVDU: return OPVCC(31,750,0,0); /* stfsdux */
  1254. case AFXMOVS: return OPVCC(31,782,0,0); /* stfxsx */
  1255. case AFXMOVSU: return OPVCC(31,814,0,0); /* stfxsux */
  1256. case AFXMOVD: return OPVCC(31,846,0,0); /* stfxdx */
  1257. case AFXMOVDU: return OPVCC(31,878,0,0); /* stfxdux */
  1258. case AFPMOVS: return OPVCC(31,910,0,0); /* stfpsx */
  1259. case AFPMOVSU: return OPVCC(31,942,0,0); /* stfpsux */
  1260. case AFPMOVD: return OPVCC(31,974,0,0); /* stfpdx */
  1261. case AFPMOVDU: return OPVCC(31,1006,0,0); /* stfpdux */
  1262. case AFPMOVIW: return OPVCC(31,526,0,0); /* stfpiwx */
  1263. }
  1264. diag("unknown storex opcode %A", a);
  1265. return 0;
  1266. }