cgen64.c 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654
  1. #include "gc.h"
  2. void
  3. zeroregm(Node *n)
  4. {
  5. gins(AMOVL, nodconst(0), n);
  6. }
  7. /* do we need to load the address of a vlong? */
  8. int
  9. vaddr(Node *n, int a)
  10. {
  11. switch(n->op) {
  12. case ONAME:
  13. if(a)
  14. return 1;
  15. return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);
  16. case OCONST:
  17. case OREGISTER:
  18. case OINDREG:
  19. return 1;
  20. }
  21. return 0;
  22. }
  23. long
  24. hi64v(Node *n)
  25. {
  26. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  27. return (long)(n->vconst) & ~0L;
  28. else
  29. return (long)((uvlong)n->vconst>>32) & ~0L;
  30. }
  31. long
  32. lo64v(Node *n)
  33. {
  34. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  35. return (long)((uvlong)n->vconst>>32) & ~0L;
  36. else
  37. return (long)(n->vconst) & ~0L;
  38. }
  39. Node *
  40. hi64(Node *n)
  41. {
  42. return nodconst(hi64v(n));
  43. }
  44. Node *
  45. lo64(Node *n)
  46. {
  47. return nodconst(lo64v(n));
  48. }
  49. static Node *
  50. anonreg(void)
  51. {
  52. Node *n;
  53. n = new(OREGISTER, Z, Z);
  54. n->reg = D_NONE;
  55. n->type = types[TLONG];
  56. return n;
  57. }
  58. static Node *
  59. regpair(Node *n, Node *t)
  60. {
  61. Node *r;
  62. if(n != Z && n->op == OREGPAIR)
  63. return n;
  64. r = new(OREGPAIR, anonreg(), anonreg());
  65. if(n != Z)
  66. r->type = n->type;
  67. else
  68. r->type = t->type;
  69. return r;
  70. }
  71. static void
  72. evacaxdx(Node *r)
  73. {
  74. Node nod1, nod2;
  75. if(r->reg == D_AX || r->reg == D_DX) {
  76. reg[D_AX]++;
  77. reg[D_DX]++;
  78. /*
  79. * this is just an optim that should
  80. * check for spill
  81. */
  82. r->type = types[TULONG];
  83. regalloc(&nod1, r, Z);
  84. nodreg(&nod2, Z, r->reg);
  85. gins(AMOVL, &nod2, &nod1);
  86. regfree(r);
  87. r->reg = nod1.reg;
  88. reg[D_AX]--;
  89. reg[D_DX]--;
  90. }
  91. }
  92. /* lazy instantiation of register pair */
  93. static int
  94. instpair(Node *n, Node *l)
  95. {
  96. int r;
  97. r = 0;
  98. if(n->left->reg == D_NONE) {
  99. if(l != Z) {
  100. n->left->reg = l->reg;
  101. r = 1;
  102. }
  103. else
  104. regalloc(n->left, n->left, Z);
  105. }
  106. if(n->right->reg == D_NONE)
  107. regalloc(n->right, n->right, Z);
  108. return r;
  109. }
  110. static void
  111. zapreg(Node *n)
  112. {
  113. if(n->reg != D_NONE) {
  114. //prtree(n, "zapreg");
  115. regfree(n);
  116. n->reg = D_NONE;
  117. }
  118. }
  119. static void
  120. freepair(Node *n)
  121. {
  122. regfree(n->left);
  123. regfree(n->right);
  124. }
  125. /* n is not OREGPAIR, nn is */
  126. void
  127. loadpair(Node *n, Node *nn)
  128. {
  129. Node nod;
  130. instpair(nn, Z);
  131. if(n->op == OCONST) {
  132. gins(AMOVL, lo64(n), nn->left);
  133. n->xoffset += SZ_LONG;
  134. gins(AMOVL, hi64(n), nn->right);
  135. n->xoffset -= SZ_LONG;
  136. return;
  137. }
  138. if(!vaddr(n, 0)) {
  139. /* steal the right register for the laddr */
  140. nod = regnode;
  141. nod.reg = nn->right->reg;
  142. lcgen(n, &nod);
  143. n = &nod;
  144. regind(n, n);
  145. n->xoffset = 0;
  146. }
  147. gins(AMOVL, n, nn->left);
  148. n->xoffset += SZ_LONG;
  149. gins(AMOVL, n, nn->right);
  150. n->xoffset -= SZ_LONG;
  151. }
  152. /* n is OREGPAIR, nn is not */
  153. static void
  154. storepair(Node *n, Node *nn, int f)
  155. {
  156. Node nod;
  157. if(!vaddr(nn, 0)) {
  158. reglcgen(&nod, nn, Z);
  159. nn = &nod;
  160. }
  161. gins(AMOVL, n->left, nn);
  162. nn->xoffset += SZ_LONG;
  163. gins(AMOVL, n->right, nn);
  164. nn->xoffset -= SZ_LONG;
  165. if(nn == &nod)
  166. regfree(&nod);
  167. if(f)
  168. freepair(n);
  169. }
  170. enum
  171. {
  172. /* 4 only, see WW */
  173. WNONE = 0,
  174. WCONST,
  175. WADDR,
  176. WHARD,
  177. };
  178. static int
  179. whatof(Node *n, int a)
  180. {
  181. if(n->op == OCONST)
  182. return WCONST;
  183. return !vaddr(n, a) ? WHARD : WADDR;
  184. }
  185. /* can upgrade an extern to addr for AND */
  186. static int
  187. reduxv(Node *n)
  188. {
  189. return lo64v(n) == 0 || hi64v(n) == 0;
  190. }
  191. int
  192. cond(int op)
  193. {
  194. switch(op) {
  195. case OANDAND:
  196. case OOROR:
  197. case ONOT:
  198. return 1;
  199. case OEQ:
  200. case ONE:
  201. case OLE:
  202. case OLT:
  203. case OGE:
  204. case OGT:
  205. case OHI:
  206. case OHS:
  207. case OLO:
  208. case OLS:
  209. return 1;
  210. }
  211. return 0;
  212. }
  213. /*
  214. * for a func operand call it and then return
  215. * the safe node
  216. */
  217. static Node *
  218. vfunc(Node *n, Node *nn)
  219. {
  220. Node *t;
  221. if(n->op != OFUNC)
  222. return n;
  223. t = new(0, Z, Z);
  224. if(nn == Z || nn == nodret)
  225. nn = n;
  226. regsalloc(t, nn);
  227. sugen(n, t, 8);
  228. return t;
  229. }
  230. /* try to steal a reg */
  231. static int
  232. getreg(Node **np, Node *t, int r)
  233. {
  234. Node *n, *p;
  235. n = *np;
  236. if(n->reg == r) {
  237. p = new(0, Z, Z);
  238. regalloc(p, n, Z);
  239. gins(AMOVL, n, p);
  240. *t = *n;
  241. *np = p;
  242. return 1;
  243. }
  244. return 0;
  245. }
  246. static Node *
  247. snarfreg(Node *n, Node *t, int r, Node *d, Node *c)
  248. {
  249. if(n == Z || n->op != OREGPAIR || (!getreg(&n->left, t, r) && !getreg(&n->right, t, r))) {
  250. if(nodreg(t, Z, r)) {
  251. regalloc(c, d, Z);
  252. gins(AMOVL, t, c);
  253. reg[r]++;
  254. return c;
  255. }
  256. reg[r]++;
  257. }
  258. return Z;
  259. }
  260. enum
  261. {
  262. Vstart = OEND,
  263. Vgo,
  264. Vamv,
  265. Vmv,
  266. Vzero,
  267. Vop,
  268. Vopx,
  269. Vins,
  270. Vins0,
  271. Vinsl,
  272. Vinsr,
  273. Vinsla,
  274. Vinsra,
  275. Vinsx,
  276. Vmul,
  277. Vshll,
  278. VT,
  279. VF,
  280. V_l_lo_f,
  281. V_l_hi_f,
  282. V_l_lo_t,
  283. V_l_hi_t,
  284. V_l_lo_u,
  285. V_l_hi_u,
  286. V_r_lo_f,
  287. V_r_hi_f,
  288. V_r_lo_t,
  289. V_r_hi_t,
  290. V_r_lo_u,
  291. V_r_hi_u,
  292. Vspazz,
  293. Vend,
  294. V_T0,
  295. V_T1,
  296. V_F0,
  297. V_F1,
  298. V_a0,
  299. V_a1,
  300. V_f0,
  301. V_f1,
  302. V_p0,
  303. V_p1,
  304. V_p2,
  305. V_p3,
  306. V_p4,
  307. V_s0,
  308. V_s1,
  309. V_s2,
  310. V_s3,
  311. V_s4,
  312. C00,
  313. C01,
  314. C31,
  315. C32,
  316. O_l_lo,
  317. O_l_hi,
  318. O_r_lo,
  319. O_r_hi,
  320. O_t_lo,
  321. O_t_hi,
  322. O_l,
  323. O_r,
  324. O_l_rp,
  325. O_r_rp,
  326. O_t_rp,
  327. O_r0,
  328. O_r1,
  329. O_Zop,
  330. O_a0,
  331. O_a1,
  332. V_C0,
  333. V_C1,
  334. V_S0,
  335. V_S1,
  336. VOPS = 5,
  337. VLEN = 5,
  338. VARGS = 2,
  339. S00 = 0,
  340. Sc0,
  341. Sc1,
  342. Sc2,
  343. Sac3,
  344. Sac4,
  345. S10,
  346. SAgen = 0,
  347. SAclo,
  348. SAc32,
  349. SAchi,
  350. SAdgen,
  351. SAdclo,
  352. SAdc32,
  353. SAdchi,
  354. B0c = 0,
  355. Bca,
  356. Bac,
  357. T0i = 0,
  358. Tii,
  359. Bop0 = 0,
  360. Bop1,
  361. };
  362. /*
  363. * _testv:
  364. * CMPL lo,$0
  365. * JNE true
  366. * CMPL hi,$0
  367. * JNE true
  368. * GOTO false
  369. * false:
  370. * GOTO code
  371. * true:
  372. * GOTO patchme
  373. * code:
  374. */
  375. static uchar testi[][VLEN] =
  376. {
  377. {Vop, ONE, O_l_lo, C00},
  378. {V_s0, Vop, ONE, O_l_hi, C00},
  379. {V_s1, Vgo, V_s2, Vgo, V_s3},
  380. {VF, V_p0, V_p1, VT, V_p2},
  381. {Vgo, V_p3},
  382. {VT, V_p0, V_p1, VF, V_p2},
  383. {Vend},
  384. };
  385. /* shift left general case */
  386. static uchar shll00[][VLEN] =
  387. {
  388. {Vop, OGE, O_r, C32},
  389. {V_s0, Vinsl, ASHLL, O_r, O_l_rp},
  390. {Vins, ASHLL, O_r, O_l_lo, Vgo},
  391. {V_p0, V_s0},
  392. {Vins, ASHLL, O_r, O_l_lo},
  393. {Vins, AMOVL, O_l_lo, O_l_hi},
  394. {Vzero, O_l_lo, V_p0, Vend},
  395. };
  396. /* shift left rp, const < 32 */
  397. static uchar shllc0[][VLEN] =
  398. {
  399. {Vinsl, ASHLL, O_r, O_l_rp},
  400. {Vshll, O_r, O_l_lo, Vend},
  401. };
  402. /* shift left rp, const == 32 */
  403. static uchar shllc1[][VLEN] =
  404. {
  405. {Vins, AMOVL, O_l_lo, O_l_hi},
  406. {Vzero, O_l_lo, Vend},
  407. };
  408. /* shift left rp, const > 32 */
  409. static uchar shllc2[][VLEN] =
  410. {
  411. {Vshll, O_r, O_l_lo},
  412. {Vins, AMOVL, O_l_lo, O_l_hi},
  413. {Vzero, O_l_lo, Vend},
  414. };
  415. /* shift left addr, const == 32 */
  416. static uchar shllac3[][VLEN] =
  417. {
  418. {Vins, AMOVL, O_l_lo, O_t_hi},
  419. {Vzero, O_t_lo, Vend},
  420. };
  421. /* shift left addr, const > 32 */
  422. static uchar shllac4[][VLEN] =
  423. {
  424. {Vins, AMOVL, O_l_lo, O_t_hi},
  425. {Vshll, O_r, O_t_hi},
  426. {Vzero, O_t_lo, Vend},
  427. };
  428. /* shift left of constant */
  429. static uchar shll10[][VLEN] =
  430. {
  431. {Vop, OGE, O_r, C32},
  432. {V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
  433. {Vins, AMOVL, O_l_hi, O_t_hi},
  434. {Vinsl, ASHLL, O_r, O_t_rp},
  435. {Vins, ASHLL, O_r, O_t_lo, Vgo},
  436. {V_p0, V_s0},
  437. {Vins, AMOVL, O_l_lo, O_t_hi},
  438. {V_l_lo_t, Vins, ASHLL, O_r, O_t_hi},
  439. {Vzero, O_t_lo, V_p0, Vend},
  440. };
  441. static uchar (*shlltab[])[VLEN] =
  442. {
  443. shll00,
  444. shllc0,
  445. shllc1,
  446. shllc2,
  447. shllac3,
  448. shllac4,
  449. shll10,
  450. };
  451. /* shift right general case */
  452. static uchar shrl00[][VLEN] =
  453. {
  454. {Vop, OGE, O_r, C32},
  455. {V_s0, Vinsr, ASHRL, O_r, O_l_rp},
  456. {Vins, O_a0, O_r, O_l_hi, Vgo},
  457. {V_p0, V_s0},
  458. {Vins, O_a0, O_r, O_l_hi},
  459. {Vins, AMOVL, O_l_hi, O_l_lo},
  460. {V_T1, Vzero, O_l_hi},
  461. {V_F1, Vins, ASARL, C31, O_l_hi},
  462. {V_p0, Vend},
  463. };
  464. /* shift right rp, const < 32 */
  465. static uchar shrlc0[][VLEN] =
  466. {
  467. {Vinsr, ASHRL, O_r, O_l_rp},
  468. {Vins, O_a0, O_r, O_l_hi, Vend},
  469. };
  470. /* shift right rp, const == 32 */
  471. static uchar shrlc1[][VLEN] =
  472. {
  473. {Vins, AMOVL, O_l_hi, O_l_lo},
  474. {V_T1, Vzero, O_l_hi},
  475. {V_F1, Vins, ASARL, C31, O_l_hi},
  476. {Vend},
  477. };
  478. /* shift right rp, const > 32 */
  479. static uchar shrlc2[][VLEN] =
  480. {
  481. {Vins, O_a0, O_r, O_l_hi},
  482. {Vins, AMOVL, O_l_hi, O_l_lo},
  483. {V_T1, Vzero, O_l_hi},
  484. {V_F1, Vins, ASARL, C31, O_l_hi},
  485. {Vend},
  486. };
  487. /* shift right addr, const == 32 */
  488. static uchar shrlac3[][VLEN] =
  489. {
  490. {Vins, AMOVL, O_l_hi, O_t_lo},
  491. {V_T1, Vzero, O_t_hi},
  492. {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
  493. {V_F1, Vins, ASARL, C31, O_t_hi},
  494. {Vend},
  495. };
  496. /* shift right addr, const > 32 */
  497. static uchar shrlac4[][VLEN] =
  498. {
  499. {Vins, AMOVL, O_l_hi, O_t_lo},
  500. {Vins, O_a0, O_r, O_t_lo},
  501. {V_T1, Vzero, O_t_hi},
  502. {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
  503. {V_F1, Vins, ASARL, C31, O_t_hi},
  504. {Vend},
  505. };
  506. /* shift right of constant */
  507. static uchar shrl10[][VLEN] =
  508. {
  509. {Vop, OGE, O_r, C32},
  510. {V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
  511. {Vins, AMOVL, O_l_hi, O_t_hi},
  512. {Vinsr, ASHRL, O_r, O_t_rp},
  513. {Vins, O_a0, O_r, O_t_hi, Vgo},
  514. {V_p0, V_s0},
  515. {Vins, AMOVL, O_l_hi, O_t_lo},
  516. {V_l_hi_t, Vins, O_a0, O_r, O_t_lo},
  517. {V_l_hi_u, V_S1},
  518. {V_T1, Vzero, O_t_hi, V_p0},
  519. {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
  520. {V_F1, Vins, ASARL, C31, O_t_hi},
  521. {Vend},
  522. };
  523. static uchar (*shrltab[])[VLEN] =
  524. {
  525. shrl00,
  526. shrlc0,
  527. shrlc1,
  528. shrlc2,
  529. shrlac3,
  530. shrlac4,
  531. shrl10,
  532. };
  533. /* shift asop left general case */
  534. static uchar asshllgen[][VLEN] =
  535. {
  536. {V_a0, V_a1},
  537. {Vop, OGE, O_r, C32},
  538. {V_s0, Vins, AMOVL, O_l_lo, O_r0},
  539. {Vins, AMOVL, O_l_hi, O_r1},
  540. {Vinsla, ASHLL, O_r, O_r0},
  541. {Vins, ASHLL, O_r, O_r0},
  542. {Vins, AMOVL, O_r1, O_l_hi},
  543. {Vins, AMOVL, O_r0, O_l_lo, Vgo},
  544. {V_p0, V_s0},
  545. {Vins, AMOVL, O_l_lo, O_r0},
  546. {Vzero, O_l_lo},
  547. {Vins, ASHLL, O_r, O_r0},
  548. {Vins, AMOVL, O_r0, O_l_hi, V_p0},
  549. {V_f0, V_f1, Vend},
  550. };
  551. /* shift asop left, const < 32 */
  552. static uchar asshllclo[][VLEN] =
  553. {
  554. {V_a0, V_a1},
  555. {Vins, AMOVL, O_l_lo, O_r0},
  556. {Vins, AMOVL, O_l_hi, O_r1},
  557. {Vinsla, ASHLL, O_r, O_r0},
  558. {Vshll, O_r, O_r0},
  559. {Vins, AMOVL, O_r1, O_l_hi},
  560. {Vins, AMOVL, O_r0, O_l_lo},
  561. {V_f0, V_f1, Vend},
  562. };
  563. /* shift asop left, const == 32 */
  564. static uchar asshllc32[][VLEN] =
  565. {
  566. {V_a0},
  567. {Vins, AMOVL, O_l_lo, O_r0},
  568. {Vzero, O_l_lo},
  569. {Vins, AMOVL, O_r0, O_l_hi},
  570. {V_f0, Vend},
  571. };
  572. /* shift asop left, const > 32 */
  573. static uchar asshllchi[][VLEN] =
  574. {
  575. {V_a0},
  576. {Vins, AMOVL, O_l_lo, O_r0},
  577. {Vzero, O_l_lo},
  578. {Vshll, O_r, O_r0},
  579. {Vins, AMOVL, O_r0, O_l_hi},
  580. {V_f0, Vend},
  581. };
  582. /* shift asop dest left general case */
  583. static uchar asdshllgen[][VLEN] =
  584. {
  585. {Vop, OGE, O_r, C32},
  586. {V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
  587. {Vins, AMOVL, O_l_hi, O_t_hi},
  588. {Vinsl, ASHLL, O_r, O_t_rp},
  589. {Vins, ASHLL, O_r, O_t_lo},
  590. {Vins, AMOVL, O_t_hi, O_l_hi},
  591. {Vins, AMOVL, O_t_lo, O_l_lo, Vgo},
  592. {V_p0, V_s0},
  593. {Vins, AMOVL, O_l_lo, O_t_hi},
  594. {Vzero, O_l_lo},
  595. {Vins, ASHLL, O_r, O_t_hi},
  596. {Vzero, O_t_lo},
  597. {Vins, AMOVL, O_t_hi, O_l_hi, V_p0},
  598. {Vend},
  599. };
  600. /* shift asop dest left, const < 32 */
  601. static uchar asdshllclo[][VLEN] =
  602. {
  603. {Vins, AMOVL, O_l_lo, O_t_lo},
  604. {Vins, AMOVL, O_l_hi, O_t_hi},
  605. {Vinsl, ASHLL, O_r, O_t_rp},
  606. {Vshll, O_r, O_t_lo},
  607. {Vins, AMOVL, O_t_hi, O_l_hi},
  608. {Vins, AMOVL, O_t_lo, O_l_lo},
  609. {Vend},
  610. };
  611. /* shift asop dest left, const == 32 */
  612. static uchar asdshllc32[][VLEN] =
  613. {
  614. {Vins, AMOVL, O_l_lo, O_t_hi},
  615. {Vzero, O_t_lo},
  616. {Vins, AMOVL, O_t_hi, O_l_hi},
  617. {Vins, AMOVL, O_t_lo, O_l_lo},
  618. {Vend},
  619. };
  620. /* shift asop dest, const > 32 */
  621. static uchar asdshllchi[][VLEN] =
  622. {
  623. {Vins, AMOVL, O_l_lo, O_t_hi},
  624. {Vzero, O_t_lo},
  625. {Vshll, O_r, O_t_hi},
  626. {Vins, AMOVL, O_t_lo, O_l_lo},
  627. {Vins, AMOVL, O_t_hi, O_l_hi},
  628. {Vend},
  629. };
  630. static uchar (*asshlltab[])[VLEN] =
  631. {
  632. asshllgen,
  633. asshllclo,
  634. asshllc32,
  635. asshllchi,
  636. asdshllgen,
  637. asdshllclo,
  638. asdshllc32,
  639. asdshllchi,
  640. };
  641. /* shift asop right general case */
  642. static uchar asshrlgen[][VLEN] =
  643. {
  644. {V_a0, V_a1},
  645. {Vop, OGE, O_r, C32},
  646. {V_s0, Vins, AMOVL, O_l_lo, O_r0},
  647. {Vins, AMOVL, O_l_hi, O_r1},
  648. {Vinsra, ASHRL, O_r, O_r0},
  649. {Vinsx, Bop0, O_r, O_r1},
  650. {Vins, AMOVL, O_r0, O_l_lo},
  651. {Vins, AMOVL, O_r1, O_l_hi, Vgo},
  652. {V_p0, V_s0},
  653. {Vins, AMOVL, O_l_hi, O_r0},
  654. {Vinsx, Bop0, O_r, O_r0},
  655. {V_T1, Vzero, O_l_hi},
  656. {Vins, AMOVL, O_r0, O_l_lo},
  657. {V_F1, Vins, ASARL, C31, O_r0},
  658. {V_F1, Vins, AMOVL, O_r0, O_l_hi},
  659. {V_p0, V_f0, V_f1, Vend},
  660. };
  661. /* shift asop right, const < 32 */
  662. static uchar asshrlclo[][VLEN] =
  663. {
  664. {V_a0, V_a1},
  665. {Vins, AMOVL, O_l_lo, O_r0},
  666. {Vins, AMOVL, O_l_hi, O_r1},
  667. {Vinsra, ASHRL, O_r, O_r0},
  668. {Vinsx, Bop0, O_r, O_r1},
  669. {Vins, AMOVL, O_r0, O_l_lo},
  670. {Vins, AMOVL, O_r1, O_l_hi},
  671. {V_f0, V_f1, Vend},
  672. };
  673. /* shift asop right, const == 32 */
  674. static uchar asshrlc32[][VLEN] =
  675. {
  676. {V_a0},
  677. {Vins, AMOVL, O_l_hi, O_r0},
  678. {V_T1, Vzero, O_l_hi},
  679. {Vins, AMOVL, O_r0, O_l_lo},
  680. {V_F1, Vins, ASARL, C31, O_r0},
  681. {V_F1, Vins, AMOVL, O_r0, O_l_hi},
  682. {V_f0, Vend},
  683. };
  684. /* shift asop right, const > 32 */
  685. static uchar asshrlchi[][VLEN] =
  686. {
  687. {V_a0},
  688. {Vins, AMOVL, O_l_hi, O_r0},
  689. {V_T1, Vzero, O_l_hi},
  690. {Vinsx, Bop0, O_r, O_r0},
  691. {Vins, AMOVL, O_r0, O_l_lo},
  692. {V_F1, Vins, ASARL, C31, O_r0},
  693. {V_F1, Vins, AMOVL, O_r0, O_l_hi},
  694. {V_f0, Vend},
  695. };
  696. /* shift asop dest right general case */
  697. static uchar asdshrlgen[][VLEN] =
  698. {
  699. {Vop, OGE, O_r, C32},
  700. {V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
  701. {Vins, AMOVL, O_l_hi, O_t_hi},
  702. {Vinsr, ASHRL, O_r, O_t_rp},
  703. {Vinsx, Bop0, O_r, O_t_hi},
  704. {Vins, AMOVL, O_t_lo, O_l_lo},
  705. {Vins, AMOVL, O_t_hi, O_l_hi, Vgo},
  706. {V_p0, V_s0},
  707. {Vins, AMOVL, O_l_hi, O_t_lo},
  708. {V_T1, Vzero, O_t_hi},
  709. {Vinsx, Bop0, O_r, O_t_lo},
  710. {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
  711. {V_F1, Vins, ASARL, C31, O_t_hi},
  712. {Vins, AMOVL, O_t_hi, O_l_hi, V_p0},
  713. {Vend},
  714. };
  715. /* shift asop dest right, const < 32 */
  716. static uchar asdshrlclo[][VLEN] =
  717. {
  718. {Vins, AMOVL, O_l_lo, O_t_lo},
  719. {Vins, AMOVL, O_l_hi, O_t_hi},
  720. {Vinsr, ASHRL, O_r, O_t_rp},
  721. {Vinsx, Bop0, O_r, O_t_hi},
  722. {Vins, AMOVL, O_t_lo, O_l_lo},
  723. {Vins, AMOVL, O_t_hi, O_l_hi},
  724. {Vend},
  725. };
  726. /* shift asop dest right, const == 32 */
  727. static uchar asdshrlc32[][VLEN] =
  728. {
  729. {Vins, AMOVL, O_l_hi, O_t_lo},
  730. {V_T1, Vzero, O_t_hi},
  731. {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
  732. {V_F1, Vins, ASARL, C31, O_t_hi},
  733. {Vins, AMOVL, O_t_lo, O_l_lo},
  734. {Vins, AMOVL, O_t_hi, O_l_hi},
  735. {Vend},
  736. };
  737. /* shift asop dest, const > 32 */
  738. static uchar asdshrlchi[][VLEN] =
  739. {
  740. {Vins, AMOVL, O_l_hi, O_t_lo},
  741. {V_T1, Vzero, O_t_hi},
  742. {Vinsx, Bop0, O_r, O_t_lo},
  743. {V_T1, Vins, AMOVL, O_t_hi, O_l_hi},
  744. {V_T1, Vins, AMOVL, O_t_lo, O_l_lo},
  745. {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
  746. {V_F1, Vins, ASARL, C31, O_t_hi},
  747. {V_F1, Vins, AMOVL, O_t_lo, O_l_lo},
  748. {V_F1, Vins, AMOVL, O_t_hi, O_l_hi},
  749. {Vend},
  750. };
  751. static uchar (*asshrltab[])[VLEN] =
  752. {
  753. asshrlgen,
  754. asshrlclo,
  755. asshrlc32,
  756. asshrlchi,
  757. asdshrlgen,
  758. asdshrlclo,
  759. asdshrlc32,
  760. asdshrlchi,
  761. };
  762. static uchar shrlargs[] = { ASHRL, 1 };
  763. static uchar sarlargs[] = { ASARL, 0 };
  764. /* ++ -- */
  765. static uchar incdec[][VLEN] =
  766. {
  767. {Vinsx, Bop0, C01, O_l_lo},
  768. {Vinsx, Bop1, C00, O_l_hi, Vend},
  769. };
  770. /* ++ -- *p */
  771. static uchar incdecpre[][VLEN] =
  772. {
  773. {Vins, AMOVL, O_l_lo, O_t_lo},
  774. {Vins, AMOVL, O_l_hi, O_t_hi},
  775. {Vinsx, Bop0, C01, O_t_lo},
  776. {Vinsx, Bop1, C00, O_t_hi},
  777. {Vins, AMOVL, O_t_lo, O_l_lo},
  778. {Vins, AMOVL, O_t_hi, O_l_hi, Vend},
  779. };
  780. /* *p ++ -- */
  781. static uchar incdecpost[][VLEN] =
  782. {
  783. {Vins, AMOVL, O_l_lo, O_t_lo},
  784. {Vins, AMOVL, O_l_hi, O_t_hi},
  785. {Vinsx, Bop0, C01, O_l_lo},
  786. {Vinsx, Bop1, C00, O_l_hi, Vend},
  787. };
  788. /* binop rp, rp */
  789. static uchar binop00[][VLEN] =
  790. {
  791. {Vinsx, Bop0, O_r_lo, O_l_lo},
  792. {Vinsx, Bop1, O_r_hi, O_l_hi, Vend},
  793. {Vend},
  794. };
  795. /* binop rp, addr */
  796. static uchar binoptmp[][VLEN] =
  797. {
  798. {V_a0, Vins, AMOVL, O_r_lo, O_r0},
  799. {Vinsx, Bop0, O_r0, O_l_lo},
  800. {Vins, AMOVL, O_r_hi, O_r0},
  801. {Vinsx, Bop1, O_r0, O_l_hi},
  802. {V_f0, Vend},
  803. };
  804. /* binop t = *a op *b */
  805. static uchar binop11[][VLEN] =
  806. {
  807. {Vins, AMOVL, O_l_lo, O_t_lo},
  808. {Vinsx, Bop0, O_r_lo, O_t_lo},
  809. {Vins, AMOVL, O_l_hi, O_t_hi},
  810. {Vinsx, Bop1, O_r_hi, O_t_hi, Vend},
  811. };
  812. /* binop t = rp +- c */
  813. static uchar add0c[][VLEN] =
  814. {
  815. {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
  816. {V_r_lo_f, Vamv, Bop0, Bop1},
  817. {Vinsx, Bop1, O_r_hi, O_l_hi},
  818. {Vend},
  819. };
  820. /* binop t = rp & c */
  821. static uchar and0c[][VLEN] =
  822. {
  823. {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
  824. {V_r_lo_f, Vins, AMOVL, C00, O_l_lo},
  825. {V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},
  826. {V_r_hi_f, Vins, AMOVL, C00, O_l_hi},
  827. {Vend},
  828. };
  829. /* binop t = rp | c */
  830. static uchar or0c[][VLEN] =
  831. {
  832. {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
  833. {V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},
  834. {Vend},
  835. };
  836. /* binop t = c - rp */
  837. static uchar sub10[][VLEN] =
  838. {
  839. {V_a0, Vins, AMOVL, O_l_lo, O_r0},
  840. {Vinsx, Bop0, O_r_lo, O_r0},
  841. {Vins, AMOVL, O_l_hi, O_r_lo},
  842. {Vinsx, Bop1, O_r_hi, O_r_lo},
  843. {Vspazz, V_f0, Vend},
  844. };
  845. /* binop t = c + *b */
  846. static uchar addca[][VLEN] =
  847. {
  848. {Vins, AMOVL, O_r_lo, O_t_lo},
  849. {V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
  850. {V_l_lo_f, Vamv, Bop0, Bop1},
  851. {Vins, AMOVL, O_r_hi, O_t_hi},
  852. {Vinsx, Bop1, O_l_hi, O_t_hi},
  853. {Vend},
  854. };
  855. /* binop t = c & *b */
  856. static uchar andca[][VLEN] =
  857. {
  858. {V_l_lo_t, Vins, AMOVL, O_r_lo, O_t_lo},
  859. {V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
  860. {V_l_lo_f, Vzero, O_t_lo},
  861. {V_l_hi_t, Vins, AMOVL, O_r_hi, O_t_hi},
  862. {V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},
  863. {V_l_hi_f, Vzero, O_t_hi},
  864. {Vend},
  865. };
  866. /* binop t = c | *b */
  867. static uchar orca[][VLEN] =
  868. {
  869. {Vins, AMOVL, O_r_lo, O_t_lo},
  870. {V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
  871. {Vins, AMOVL, O_r_hi, O_t_hi},
  872. {V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},
  873. {Vend},
  874. };
  875. /* binop t = c - *b */
  876. static uchar subca[][VLEN] =
  877. {
  878. {Vins, AMOVL, O_l_lo, O_t_lo},
  879. {Vins, AMOVL, O_l_hi, O_t_hi},
  880. {Vinsx, Bop0, O_r_lo, O_t_lo},
  881. {Vinsx, Bop1, O_r_hi, O_t_hi},
  882. {Vend},
  883. };
  884. /* binop t = *a +- c */
  885. static uchar addac[][VLEN] =
  886. {
  887. {Vins, AMOVL, O_l_lo, O_t_lo},
  888. {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
  889. {V_r_lo_f, Vamv, Bop0, Bop1},
  890. {Vins, AMOVL, O_l_hi, O_t_hi},
  891. {Vinsx, Bop1, O_r_hi, O_t_hi},
  892. {Vend},
  893. };
  894. /* binop t = *a | c */
  895. static uchar orac[][VLEN] =
  896. {
  897. {Vins, AMOVL, O_l_lo, O_t_lo},
  898. {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
  899. {Vins, AMOVL, O_l_hi, O_t_hi},
  900. {V_r_hi_t, Vinsx, Bop1, O_r_hi, O_t_hi},
  901. {Vend},
  902. };
  903. /* binop t = *a & c */
  904. static uchar andac[][VLEN] =
  905. {
  906. {V_r_lo_t, Vins, AMOVL, O_l_lo, O_t_lo},
  907. {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
  908. {V_r_lo_f, Vzero, O_t_lo},
  909. {V_r_hi_t, Vins, AMOVL, O_l_hi, O_t_hi},
  910. {V_r_hi_t, Vinsx, Bop0, O_r_hi, O_t_hi},
  911. {V_r_hi_f, Vzero, O_t_hi},
  912. {Vend},
  913. };
  914. static uchar ADDargs[] = { AADDL, AADCL };
  915. static uchar ANDargs[] = { AANDL, AANDL };
  916. static uchar ORargs[] = { AORL, AORL };
  917. static uchar SUBargs[] = { ASUBL, ASBBL };
  918. static uchar XORargs[] = { AXORL, AXORL };
  919. static uchar (*ADDtab[])[VLEN] =
  920. {
  921. add0c, addca, addac,
  922. };
  923. static uchar (*ANDtab[])[VLEN] =
  924. {
  925. and0c, andca, andac,
  926. };
  927. static uchar (*ORtab[])[VLEN] =
  928. {
  929. or0c, orca, orac,
  930. };
  931. static uchar (*SUBtab[])[VLEN] =
  932. {
  933. add0c, subca, addac,
  934. };
  935. /* mul of const32 */
  936. static uchar mulc32[][VLEN] =
  937. {
  938. {V_a0, Vop, ONE, O_l_hi, C00},
  939. {V_s0, Vins, AMOVL, O_r_lo, O_r0},
  940. {Vins, AMULL, O_r0, O_Zop},
  941. {Vgo, V_p0, V_s0},
  942. {Vins, AMOVL, O_l_hi, O_r0},
  943. {Vmul, O_r_lo, O_r0},
  944. {Vins, AMOVL, O_r_lo, O_l_hi},
  945. {Vins, AMULL, O_l_hi, O_Zop},
  946. {Vins, AADDL, O_r0, O_l_hi},
  947. {V_f0, V_p0, Vend},
  948. };
  949. /* mul of const64 */
  950. static uchar mulc64[][VLEN] =
  951. {
  952. {V_a0, Vins, AMOVL, O_r_hi, O_r0},
  953. {Vop, OOR, O_l_hi, O_r0},
  954. {Vop, ONE, O_r0, C00},
  955. {V_s0, Vins, AMOVL, O_r_lo, O_r0},
  956. {Vins, AMULL, O_r0, O_Zop},
  957. {Vgo, V_p0, V_s0},
  958. {Vmul, O_r_lo, O_l_hi},
  959. {Vins, AMOVL, O_l_lo, O_r0},
  960. {Vmul, O_r_hi, O_r0},
  961. {Vins, AADDL, O_l_hi, O_r0},
  962. {Vins, AMOVL, O_r_lo, O_l_hi},
  963. {Vins, AMULL, O_l_hi, O_Zop},
  964. {Vins, AADDL, O_r0, O_l_hi},
  965. {V_f0, V_p0, Vend},
  966. };
  967. /* mul general */
  968. static uchar mull[][VLEN] =
  969. {
  970. {V_a0, Vins, AMOVL, O_r_hi, O_r0},
  971. {Vop, OOR, O_l_hi, O_r0},
  972. {Vop, ONE, O_r0, C00},
  973. {V_s0, Vins, AMOVL, O_r_lo, O_r0},
  974. {Vins, AMULL, O_r0, O_Zop},
  975. {Vgo, V_p0, V_s0},
  976. {Vins, AIMULL, O_r_lo, O_l_hi},
  977. {Vins, AMOVL, O_l_lo, O_r0},
  978. {Vins, AIMULL, O_r_hi, O_r0},
  979. {Vins, AADDL, O_l_hi, O_r0},
  980. {Vins, AMOVL, O_r_lo, O_l_hi},
  981. {Vins, AMULL, O_l_hi, O_Zop},
  982. {Vins, AADDL, O_r0, O_l_hi},
  983. {V_f0, V_p0, Vend},
  984. };
  985. /* cast rp l to rp t */
  986. static uchar castrp[][VLEN] =
  987. {
  988. {Vmv, O_l, O_t_lo},
  989. {VT, Vins, AMOVL, O_t_lo, O_t_hi},
  990. {VT, Vins, ASARL, C31, O_t_hi},
  991. {VF, Vzero, O_t_hi},
  992. {Vend},
  993. };
  994. /* cast rp l to addr t */
  995. static uchar castrpa[][VLEN] =
  996. {
  997. {VT, V_a0, Vmv, O_l, O_r0},
  998. {VT, Vins, AMOVL, O_r0, O_t_lo},
  999. {VT, Vins, ASARL, C31, O_r0},
  1000. {VT, Vins, AMOVL, O_r0, O_t_hi},
  1001. {VT, V_f0},
  1002. {VF, Vmv, O_l, O_t_lo},
  1003. {VF, Vzero, O_t_hi},
  1004. {Vend},
  1005. };
  1006. static uchar netab0i[][VLEN] =
  1007. {
  1008. {Vop, ONE, O_l_lo, O_r_lo},
  1009. {V_s0, Vop, ONE, O_l_hi, O_r_hi},
  1010. {V_s1, Vgo, V_s2, Vgo, V_s3},
  1011. {VF, V_p0, V_p1, VT, V_p2},
  1012. {Vgo, V_p3},
  1013. {VT, V_p0, V_p1, VF, V_p2},
  1014. {Vend},
  1015. };
  1016. static uchar netabii[][VLEN] =
  1017. {
  1018. {V_a0, Vins, AMOVL, O_l_lo, O_r0},
  1019. {Vop, ONE, O_r0, O_r_lo},
  1020. {V_s0, Vins, AMOVL, O_l_hi, O_r0},
  1021. {Vop, ONE, O_r0, O_r_hi},
  1022. {V_s1, Vgo, V_s2, Vgo, V_s3},
  1023. {VF, V_p0, V_p1, VT, V_p2},
  1024. {Vgo, V_p3},
  1025. {VT, V_p0, V_p1, VF, V_p2},
  1026. {V_f0, Vend},
  1027. };
  1028. static uchar cmptab0i[][VLEN] =
  1029. {
  1030. {Vopx, Bop0, O_l_hi, O_r_hi},
  1031. {V_s0, Vins0, AJNE},
  1032. {V_s1, Vopx, Bop1, O_l_lo, O_r_lo},
  1033. {V_s2, Vgo, V_s3, Vgo, V_s4},
  1034. {VT, V_p1, V_p3},
  1035. {VF, V_p0, V_p2},
  1036. {Vgo, V_p4},
  1037. {VT, V_p0, V_p2},
  1038. {VF, V_p1, V_p3},
  1039. {Vend},
  1040. };
  1041. static uchar cmptabii[][VLEN] =
  1042. {
  1043. {V_a0, Vins, AMOVL, O_l_hi, O_r0},
  1044. {Vopx, Bop0, O_r0, O_r_hi},
  1045. {V_s0, Vins0, AJNE},
  1046. {V_s1, Vins, AMOVL, O_l_lo, O_r0},
  1047. {Vopx, Bop1, O_r0, O_r_lo},
  1048. {V_s2, Vgo, V_s3, Vgo, V_s4},
  1049. {VT, V_p1, V_p3},
  1050. {VF, V_p0, V_p2},
  1051. {Vgo, V_p4},
  1052. {VT, V_p0, V_p2},
  1053. {VF, V_p1, V_p3},
  1054. {V_f0, Vend},
  1055. };
  1056. static uchar (*NEtab[])[VLEN] =
  1057. {
  1058. netab0i, netabii,
  1059. };
  1060. static uchar (*cmptab[])[VLEN] =
  1061. {
  1062. cmptab0i, cmptabii,
  1063. };
  1064. static uchar GEargs[] = { OGT, OHS };
  1065. static uchar GTargs[] = { OGT, OHI };
  1066. static uchar HIargs[] = { OHI, OHI };
  1067. static uchar HSargs[] = { OHI, OHS };
  1068. /* Big Generator */
  1069. static void
  1070. biggen(Node *l, Node *r, Node *t, int true, uchar code[][VLEN], uchar *a)
  1071. {
  1072. int i, j, g, oc, op, lo, ro, to, xo, *xp;
  1073. Type *lt;
  1074. Prog *pr[VOPS];
  1075. Node *ot, *tl, *tr, tmps[2];
  1076. uchar *c, (*cp)[VLEN], args[VARGS];
  1077. if(a != nil)
  1078. memmove(args, a, VARGS);
  1079. //print("biggen %d %d %d\n", args[0], args[1], args[2]);
  1080. //if(l) prtree(l, "l");
  1081. //if(r) prtree(r, "r");
  1082. //if(t) prtree(t, "t");
  1083. lo = ro = to = 0;
  1084. cp = code;
  1085. for (;;) {
  1086. c = *cp++;
  1087. g = 1;
  1088. i = 0;
  1089. //print("code %d %d %d %d %d\n", c[0], c[1], c[2], c[3], c[4]);
  1090. for(;;) {
  1091. switch(op = c[i]) {
  1092. case Vgo:
  1093. if(g)
  1094. gbranch(OGOTO);
  1095. i++;
  1096. break;
  1097. case Vamv:
  1098. i += 3;
  1099. if(i > VLEN) {
  1100. diag(l, "bad Vop");
  1101. return;
  1102. }
  1103. if(g)
  1104. args[c[i - 1]] = args[c[i - 2]];
  1105. break;
  1106. case Vzero:
  1107. i += 2;
  1108. if(i > VLEN) {
  1109. diag(l, "bad Vop");
  1110. return;
  1111. }
  1112. j = i - 1;
  1113. goto op;
  1114. case Vspazz: // nasty hack to save a reg in SUB
  1115. //print("spazz\n");
  1116. if(g) {
  1117. //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
  1118. ot = r->right;
  1119. r->right = r->left;
  1120. tl = new(0, Z, Z);
  1121. *tl = tmps[0];
  1122. r->left = tl;
  1123. tmps[0] = *ot;
  1124. //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
  1125. }
  1126. i++;
  1127. break;
  1128. case Vmv:
  1129. case Vmul:
  1130. case Vshll:
  1131. i += 3;
  1132. if(i > VLEN) {
  1133. diag(l, "bad Vop");
  1134. return;
  1135. }
  1136. j = i - 2;
  1137. goto op;
  1138. case Vins0:
  1139. i += 2;
  1140. if(i > VLEN) {
  1141. diag(l, "bad Vop");
  1142. return;
  1143. }
  1144. gins(c[i - 1], Z, Z);
  1145. break;
  1146. case Vop:
  1147. case Vopx:
  1148. case Vins:
  1149. case Vinsl:
  1150. case Vinsr:
  1151. case Vinsla:
  1152. case Vinsra:
  1153. case Vinsx:
  1154. i += 4;
  1155. if(i > VLEN) {
  1156. diag(l, "bad Vop");
  1157. return;
  1158. }
  1159. j = i - 2;
  1160. goto op;
  1161. op:
  1162. if(!g)
  1163. break;
  1164. tl = Z;
  1165. tr = Z;
  1166. for(; j < i; j++) {
  1167. switch(c[j]) {
  1168. case C00:
  1169. ot = nodconst(0);
  1170. break;
  1171. case C01:
  1172. ot = nodconst(1);
  1173. break;
  1174. case C31:
  1175. ot = nodconst(31);
  1176. break;
  1177. case C32:
  1178. ot = nodconst(32);
  1179. break;
  1180. case O_l:
  1181. case O_l_lo:
  1182. ot = l; xp = &lo; xo = 0;
  1183. goto op0;
  1184. case O_l_hi:
  1185. ot = l; xp = &lo; xo = SZ_LONG;
  1186. goto op0;
  1187. case O_r:
  1188. case O_r_lo:
  1189. ot = r; xp = &ro; xo = 0;
  1190. goto op0;
  1191. case O_r_hi:
  1192. ot = r; xp = &ro; xo = SZ_LONG;
  1193. goto op0;
  1194. case O_t_lo:
  1195. ot = t; xp = &to; xo = 0;
  1196. goto op0;
  1197. case O_t_hi:
  1198. ot = t; xp = &to; xo = SZ_LONG;
  1199. goto op0;
  1200. case O_l_rp:
  1201. ot = l;
  1202. break;
  1203. case O_r_rp:
  1204. ot = r;
  1205. break;
  1206. case O_t_rp:
  1207. ot = t;
  1208. break;
  1209. case O_r0:
  1210. case O_r1:
  1211. ot = &tmps[c[j] - O_r0];
  1212. break;
  1213. case O_Zop:
  1214. ot = Z;
  1215. break;
  1216. op0:
  1217. switch(ot->op) {
  1218. case OCONST:
  1219. if(xo)
  1220. ot = hi64(ot);
  1221. else
  1222. ot = lo64(ot);
  1223. break;
  1224. case OREGPAIR:
  1225. if(xo)
  1226. ot = ot->right;
  1227. else
  1228. ot = ot->left;
  1229. break;
  1230. case OREGISTER:
  1231. break;
  1232. default:
  1233. if(xo != *xp) {
  1234. ot->xoffset += xo - *xp;
  1235. *xp = xo;
  1236. }
  1237. }
  1238. break;
  1239. default:
  1240. diag(l, "bad V_lop");
  1241. return;
  1242. }
  1243. if(tl == nil)
  1244. tl = ot;
  1245. else
  1246. tr = ot;
  1247. }
  1248. if(op == Vzero) {
  1249. zeroregm(tl);
  1250. break;
  1251. }
  1252. oc = c[i - 3];
  1253. if(op == Vinsx || op == Vopx) {
  1254. //print("%d -> %d\n", oc, args[oc]);
  1255. oc = args[oc];
  1256. }
  1257. else {
  1258. switch(oc) {
  1259. case O_a0:
  1260. case O_a1:
  1261. oc = args[oc - O_a0];
  1262. break;
  1263. }
  1264. }
  1265. switch(op) {
  1266. case Vmul:
  1267. mulgen(tr->type, tl, tr);
  1268. break;
  1269. case Vmv:
  1270. gmove(tl, tr);
  1271. break;
  1272. case Vshll:
  1273. shiftit(tr->type, tl, tr);
  1274. break;
  1275. case Vop:
  1276. case Vopx:
  1277. gopcode(oc, types[TULONG], tl, tr);
  1278. break;
  1279. case Vins:
  1280. case Vinsx:
  1281. gins(oc, tl, tr);
  1282. break;
  1283. case Vinsl:
  1284. gins(oc, tl, tr->right);
  1285. p->from.index = tr->left->reg;
  1286. break;
  1287. case Vinsr:
  1288. gins(oc, tl, tr->left);
  1289. p->from.index = tr->right->reg;
  1290. break;
  1291. case Vinsla:
  1292. gins(oc, tl, tr + 1);
  1293. p->from.index = tr->reg;
  1294. break;
  1295. case Vinsra:
  1296. gins(oc, tl, tr);
  1297. p->from.index = (tr + 1)->reg;
  1298. break;
  1299. }
  1300. break;
  1301. case VT:
  1302. g = true;
  1303. i++;
  1304. break;
  1305. case VF:
  1306. g = !true;
  1307. i++;
  1308. break;
  1309. case V_T0: case V_T1:
  1310. g = args[op - V_T0];
  1311. i++;
  1312. break;
  1313. case V_F0: case V_F1:
  1314. g = !args[op - V_F0];
  1315. i++;
  1316. break;
  1317. case V_C0: case V_C1:
  1318. if(g)
  1319. args[op - V_C0] = 0;
  1320. i++;
  1321. break;
  1322. case V_S0: case V_S1:
  1323. if(g)
  1324. args[op - V_S0] = 1;
  1325. i++;
  1326. break;
  1327. case V_l_lo_f:
  1328. g = lo64v(l) == 0;
  1329. i++;
  1330. break;
  1331. case V_l_hi_f:
  1332. g = hi64v(l) == 0;
  1333. i++;
  1334. break;
  1335. case V_l_lo_t:
  1336. g = lo64v(l) != 0;
  1337. i++;
  1338. break;
  1339. case V_l_hi_t:
  1340. g = hi64v(l) != 0;
  1341. i++;
  1342. break;
  1343. case V_l_lo_u:
  1344. g = lo64v(l) >= 0;
  1345. i++;
  1346. break;
  1347. case V_l_hi_u:
  1348. g = hi64v(l) >= 0;
  1349. i++;
  1350. break;
  1351. case V_r_lo_f:
  1352. g = lo64v(r) == 0;
  1353. i++;
  1354. break;
  1355. case V_r_hi_f:
  1356. g = hi64v(r) == 0;
  1357. i++;
  1358. break;
  1359. case V_r_lo_t:
  1360. g = lo64v(r) != 0;
  1361. i++;
  1362. break;
  1363. case V_r_hi_t:
  1364. g = hi64v(r) != 0;
  1365. i++;
  1366. break;
  1367. case V_r_lo_u:
  1368. g = lo64v(r) >= 0;
  1369. i++;
  1370. break;
  1371. case V_r_hi_u:
  1372. g = hi64v(r) >= 0;
  1373. i++;
  1374. break;
  1375. case Vend:
  1376. goto out;
  1377. case V_a0: case V_a1:
  1378. if(g) {
  1379. lt = l->type;
  1380. l->type = types[TULONG];
  1381. regalloc(&tmps[op - V_a0], l, Z);
  1382. l->type = lt;
  1383. }
  1384. i++;
  1385. break;
  1386. case V_f0: case V_f1:
  1387. if(g)
  1388. regfree(&tmps[op - V_f0]);
  1389. i++;
  1390. break;
  1391. case V_p0: case V_p1: case V_p2: case V_p3: case V_p4:
  1392. if(g)
  1393. patch(pr[op - V_p0], pc);
  1394. i++;
  1395. break;
  1396. case V_s0: case V_s1: case V_s2: case V_s3: case V_s4:
  1397. if(g)
  1398. pr[op - V_s0] = p;
  1399. i++;
  1400. break;
  1401. default:
  1402. diag(l, "bad biggen: %d", op);
  1403. return;
  1404. }
  1405. if(i == VLEN || c[i] == 0)
  1406. break;
  1407. }
  1408. }
  1409. out:
  1410. if(lo)
  1411. l->xoffset -= lo;
  1412. if(ro)
  1413. r->xoffset -= ro;
  1414. if(to)
  1415. t->xoffset -= to;
  1416. }
  1417. int
  1418. cgen64(Node *n, Node *nn)
  1419. {
  1420. Type *dt;
  1421. uchar *args, (*cp)[VLEN], (**optab)[VLEN];
  1422. int li, ri, lri, dr, si, m, op, sh, cmp, true;
  1423. Node *c, *d, *l, *r, *t, *s, nod1, nod2, nod3, nod4, nod5;
  1424. if(debug['g']) {
  1425. prtree(nn, "cgen64 lhs");
  1426. prtree(n, "cgen64");
  1427. print("AX = %d\n", reg[D_AX]);
  1428. }
  1429. cmp = 0;
  1430. sh = 0;
  1431. switch(n->op) {
  1432. case ONEG:
  1433. d = regpair(nn, n);
  1434. sugen(n->left, d, 8);
  1435. gins(ANOTL, Z, d->right);
  1436. gins(ANEGL, Z, d->left);
  1437. gins(ASBBL, nodconst(-1), d->right);
  1438. break;
  1439. case OCOM:
  1440. if(!vaddr(n->left, 0) || !vaddr(nn, 0))
  1441. d = regpair(nn, n);
  1442. else
  1443. return 0;
  1444. sugen(n->left, d, 8);
  1445. gins(ANOTL, Z, d->left);
  1446. gins(ANOTL, Z, d->right);
  1447. break;
  1448. case OADD:
  1449. optab = ADDtab;
  1450. args = ADDargs;
  1451. goto twoop;
  1452. case OAND:
  1453. optab = ANDtab;
  1454. args = ANDargs;
  1455. goto twoop;
  1456. case OOR:
  1457. optab = ORtab;
  1458. args = ORargs;
  1459. goto twoop;
  1460. case OSUB:
  1461. optab = SUBtab;
  1462. args = SUBargs;
  1463. goto twoop;
  1464. case OXOR:
  1465. optab = ORtab;
  1466. args = XORargs;
  1467. goto twoop;
  1468. case OASHL:
  1469. sh = 1;
  1470. args = nil;
  1471. optab = shlltab;
  1472. goto twoop;
  1473. case OLSHR:
  1474. sh = 1;
  1475. args = shrlargs;
  1476. optab = shrltab;
  1477. goto twoop;
  1478. case OASHR:
  1479. sh = 1;
  1480. args = sarlargs;
  1481. optab = shrltab;
  1482. goto twoop;
  1483. case OEQ:
  1484. cmp = 1;
  1485. args = nil;
  1486. optab = nil;
  1487. goto twoop;
  1488. case ONE:
  1489. cmp = 1;
  1490. args = nil;
  1491. optab = nil;
  1492. goto twoop;
  1493. case OLE:
  1494. cmp = 1;
  1495. args = nil;
  1496. optab = nil;
  1497. goto twoop;
  1498. case OLT:
  1499. cmp = 1;
  1500. args = nil;
  1501. optab = nil;
  1502. goto twoop;
  1503. case OGE:
  1504. cmp = 1;
  1505. args = nil;
  1506. optab = nil;
  1507. goto twoop;
  1508. case OGT:
  1509. cmp = 1;
  1510. args = nil;
  1511. optab = nil;
  1512. goto twoop;
  1513. case OHI:
  1514. cmp = 1;
  1515. args = nil;
  1516. optab = nil;
  1517. goto twoop;
  1518. case OHS:
  1519. cmp = 1;
  1520. args = nil;
  1521. optab = nil;
  1522. goto twoop;
  1523. case OLO:
  1524. cmp = 1;
  1525. args = nil;
  1526. optab = nil;
  1527. goto twoop;
  1528. case OLS:
  1529. cmp = 1;
  1530. args = nil;
  1531. optab = nil;
  1532. goto twoop;
  1533. twoop:
  1534. dr = nn != Z && nn->op == OREGPAIR;
  1535. l = vfunc(n->left, nn);
  1536. if(sh)
  1537. r = n->right;
  1538. else
  1539. r = vfunc(n->right, nn);
  1540. li = l->op == ONAME || l->op == OINDREG || l->op == OCONST;
  1541. ri = r->op == ONAME || r->op == OINDREG || r->op == OCONST;
  1542. #define IMM(l, r) ((l) | ((r) << 1))
  1543. lri = IMM(li, ri);
  1544. /* find out what is so easy about some operands */
  1545. if(li)
  1546. li = whatof(l, sh | cmp);
  1547. if(ri)
  1548. ri = whatof(r, cmp);
  1549. if(sh)
  1550. goto shift;
  1551. if(cmp)
  1552. goto cmp;
  1553. /* evaluate hard subexps, stealing nn if possible. */
  1554. switch(lri) {
  1555. case IMM(0, 0):
  1556. bin00:
  1557. if(l->complex > r->complex) {
  1558. if(dr)
  1559. t = nn;
  1560. else
  1561. t = regpair(Z, n);
  1562. sugen(l, t, 8);
  1563. l = t;
  1564. t = regpair(Z, n);
  1565. sugen(r, t, 8);
  1566. r = t;
  1567. }
  1568. else {
  1569. t = regpair(Z, n);
  1570. sugen(r, t, 8);
  1571. r = t;
  1572. if(dr)
  1573. t = nn;
  1574. else
  1575. t = regpair(Z, n);
  1576. sugen(l, t, 8);
  1577. l = t;
  1578. }
  1579. break;
  1580. case IMM(0, 1):
  1581. if(dr)
  1582. t = nn;
  1583. else
  1584. t = regpair(Z, n);
  1585. sugen(l, t, 8);
  1586. l = t;
  1587. break;
  1588. case IMM(1, 0):
  1589. if(n->op == OSUB && l->op == OCONST && hi64v(l) == 0) {
  1590. lri = IMM(0, 0);
  1591. goto bin00;
  1592. }
  1593. if(dr)
  1594. t = nn;
  1595. else
  1596. t = regpair(Z, n);
  1597. sugen(r, t, 8);
  1598. r = t;
  1599. break;
  1600. case IMM(1, 1):
  1601. break;
  1602. }
  1603. #define WW(l, r) ((l) | ((r) << 2))
  1604. d = Z;
  1605. dt = nn->type;
  1606. nn->type = types[TLONG];
  1607. switch(lri) {
  1608. case IMM(0, 0):
  1609. biggen(l, r, Z, 0, binop00, args);
  1610. break;
  1611. case IMM(0, 1):
  1612. switch(ri) {
  1613. case WNONE:
  1614. diag(r, "bad whatof\n");
  1615. break;
  1616. case WCONST:
  1617. biggen(l, r, Z, 0, optab[B0c], args);
  1618. break;
  1619. case WHARD:
  1620. reglcgen(&nod2, r, Z);
  1621. r = &nod2;
  1622. /* fall thru */
  1623. case WADDR:
  1624. biggen(l, r, Z, 0, binoptmp, args);
  1625. if(ri == WHARD)
  1626. regfree(r);
  1627. break;
  1628. }
  1629. break;
  1630. case IMM(1, 0):
  1631. if(n->op == OSUB) {
  1632. switch(li) {
  1633. case WNONE:
  1634. diag(l, "bad whatof\n");
  1635. break;
  1636. case WHARD:
  1637. reglcgen(&nod2, l, Z);
  1638. l = &nod2;
  1639. /* fall thru */
  1640. case WADDR:
  1641. case WCONST:
  1642. biggen(l, r, Z, 0, sub10, args);
  1643. break;
  1644. }
  1645. if(li == WHARD)
  1646. regfree(l);
  1647. }
  1648. else {
  1649. switch(li) {
  1650. case WNONE:
  1651. diag(l, "bad whatof\n");
  1652. break;
  1653. case WCONST:
  1654. biggen(r, l, Z, 0, optab[B0c], args);
  1655. break;
  1656. case WHARD:
  1657. reglcgen(&nod2, l, Z);
  1658. l = &nod2;
  1659. /* fall thru */
  1660. case WADDR:
  1661. biggen(r, l, Z, 0, binoptmp, args);
  1662. if(li == WHARD)
  1663. regfree(l);
  1664. break;
  1665. }
  1666. }
  1667. break;
  1668. case IMM(1, 1):
  1669. switch(WW(li, ri)) {
  1670. case WW(WCONST, WHARD):
  1671. if(r->op == ONAME && n->op == OAND && reduxv(l))
  1672. ri = WADDR;
  1673. break;
  1674. case WW(WHARD, WCONST):
  1675. if(l->op == ONAME && n->op == OAND && reduxv(r))
  1676. li = WADDR;
  1677. break;
  1678. }
  1679. if(li == WHARD) {
  1680. reglcgen(&nod3, l, Z);
  1681. l = &nod3;
  1682. }
  1683. if(ri == WHARD) {
  1684. reglcgen(&nod2, r, Z);
  1685. r = &nod2;
  1686. }
  1687. d = regpair(nn, n);
  1688. instpair(d, Z);
  1689. switch(WW(li, ri)) {
  1690. case WW(WCONST, WADDR):
  1691. case WW(WCONST, WHARD):
  1692. biggen(l, r, d, 0, optab[Bca], args);
  1693. break;
  1694. case WW(WADDR, WCONST):
  1695. case WW(WHARD, WCONST):
  1696. biggen(l, r, d, 0, optab[Bac], args);
  1697. break;
  1698. case WW(WADDR, WADDR):
  1699. case WW(WADDR, WHARD):
  1700. case WW(WHARD, WADDR):
  1701. case WW(WHARD, WHARD):
  1702. biggen(l, r, d, 0, binop11, args);
  1703. break;
  1704. default:
  1705. diag(r, "bad whatof pair %d %d\n", li, ri);
  1706. break;
  1707. }
  1708. if(li == WHARD)
  1709. regfree(l);
  1710. if(ri == WHARD)
  1711. regfree(r);
  1712. break;
  1713. }
  1714. nn->type = dt;
  1715. if(d != Z)
  1716. goto finished;
  1717. switch(lri) {
  1718. case IMM(0, 0):
  1719. freepair(r);
  1720. /* fall thru */;
  1721. case IMM(0, 1):
  1722. if(!dr)
  1723. storepair(l, nn, 1);
  1724. break;
  1725. case IMM(1, 0):
  1726. if(!dr)
  1727. storepair(r, nn, 1);
  1728. break;
  1729. case IMM(1, 1):
  1730. break;
  1731. }
  1732. return 1;
  1733. shift:
  1734. c = Z;
  1735. /* evaluate hard subexps, stealing nn if possible. */
  1736. /* must also secure CX. not as many optims as binop. */
  1737. switch(lri) {
  1738. case IMM(0, 0):
  1739. imm00:
  1740. if(l->complex + 1 > r->complex) {
  1741. if(dr)
  1742. t = nn;
  1743. else
  1744. t = regpair(Z, l);
  1745. sugen(l, t, 8);
  1746. l = t;
  1747. t = &nod1;
  1748. c = snarfreg(l, t, D_CX, r, &nod2);
  1749. cgen(r, t);
  1750. r = t;
  1751. }
  1752. else {
  1753. t = &nod1;
  1754. c = snarfreg(nn, t, D_CX, r, &nod2);
  1755. cgen(r, t);
  1756. r = t;
  1757. if(dr)
  1758. t = nn;
  1759. else
  1760. t = regpair(Z, l);
  1761. sugen(l, t, 8);
  1762. l = t;
  1763. }
  1764. break;
  1765. case IMM(0, 1):
  1766. imm01:
  1767. if(ri != WCONST) {
  1768. lri = IMM(0, 0);
  1769. goto imm00;
  1770. }
  1771. if(dr)
  1772. t = nn;
  1773. else
  1774. t = regpair(Z, n);
  1775. sugen(l, t, 8);
  1776. l = t;
  1777. break;
  1778. case IMM(1, 0):
  1779. imm10:
  1780. if(li != WCONST) {
  1781. lri = IMM(0, 0);
  1782. goto imm00;
  1783. }
  1784. t = &nod1;
  1785. c = snarfreg(nn, t, D_CX, r, &nod2);
  1786. cgen(r, t);
  1787. r = t;
  1788. break;
  1789. case IMM(1, 1):
  1790. if(ri != WCONST) {
  1791. lri = IMM(1, 0);
  1792. goto imm10;
  1793. }
  1794. if(li == WHARD) {
  1795. lri = IMM(0, 1);
  1796. goto imm01;
  1797. }
  1798. break;
  1799. }
  1800. d = Z;
  1801. switch(lri) {
  1802. case IMM(0, 0):
  1803. biggen(l, r, Z, 0, optab[S00], args);
  1804. break;
  1805. case IMM(0, 1):
  1806. switch(ri) {
  1807. case WNONE:
  1808. case WADDR:
  1809. case WHARD:
  1810. diag(r, "bad whatof\n");
  1811. break;
  1812. case WCONST:
  1813. m = r->vconst & 63;
  1814. s = nodconst(m);
  1815. if(m < 32)
  1816. cp = optab[Sc0];
  1817. else if(m == 32)
  1818. cp = optab[Sc1];
  1819. else
  1820. cp = optab[Sc2];
  1821. biggen(l, s, Z, 0, cp, args);
  1822. break;
  1823. }
  1824. break;
  1825. case IMM(1, 0):
  1826. /* left is const */
  1827. d = regpair(nn, n);
  1828. instpair(d, Z);
  1829. biggen(l, r, d, 0, optab[S10], args);
  1830. regfree(r);
  1831. break;
  1832. case IMM(1, 1):
  1833. d = regpair(nn, n);
  1834. instpair(d, Z);
  1835. switch(WW(li, ri)) {
  1836. case WW(WADDR, WCONST):
  1837. m = r->vconst & 63;
  1838. s = nodconst(m);
  1839. if(m < 32) {
  1840. loadpair(l, d);
  1841. l = d;
  1842. cp = optab[Sc0];
  1843. }
  1844. else if(m == 32)
  1845. cp = optab[Sac3];
  1846. else
  1847. cp = optab[Sac4];
  1848. biggen(l, s, d, 0, cp, args);
  1849. break;
  1850. default:
  1851. diag(r, "bad whatof pair %d %d\n", li, ri);
  1852. break;
  1853. }
  1854. break;
  1855. }
  1856. if(c != Z) {
  1857. gins(AMOVL, c, r);
  1858. regfree(c);
  1859. }
  1860. if(d != Z)
  1861. goto finished;
  1862. switch(lri) {
  1863. case IMM(0, 0):
  1864. regfree(r);
  1865. /* fall thru */
  1866. case IMM(0, 1):
  1867. if(!dr)
  1868. storepair(l, nn, 1);
  1869. break;
  1870. case IMM(1, 0):
  1871. regfree(r);
  1872. break;
  1873. case IMM(1, 1):
  1874. break;
  1875. }
  1876. return 1;
  1877. cmp:
  1878. op = n->op;
  1879. /* evaluate hard subexps */
  1880. switch(lri) {
  1881. case IMM(0, 0):
  1882. if(l->complex > r->complex) {
  1883. t = regpair(Z, l);
  1884. sugen(l, t, 8);
  1885. l = t;
  1886. t = regpair(Z, r);
  1887. sugen(r, t, 8);
  1888. r = t;
  1889. }
  1890. else {
  1891. t = regpair(Z, r);
  1892. sugen(r, t, 8);
  1893. r = t;
  1894. t = regpair(Z, l);
  1895. sugen(l, t, 8);
  1896. l = t;
  1897. }
  1898. break;
  1899. case IMM(1, 0):
  1900. t = r;
  1901. r = l;
  1902. l = t;
  1903. ri = li;
  1904. op = invrel[relindex(op)];
  1905. /* fall thru */
  1906. case IMM(0, 1):
  1907. t = regpair(Z, l);
  1908. sugen(l, t, 8);
  1909. l = t;
  1910. break;
  1911. case IMM(1, 1):
  1912. break;
  1913. }
  1914. true = 1;
  1915. optab = cmptab;
  1916. switch(op) {
  1917. case OEQ:
  1918. optab = NEtab;
  1919. true = 0;
  1920. break;
  1921. case ONE:
  1922. optab = NEtab;
  1923. break;
  1924. case OLE:
  1925. args = GTargs;
  1926. true = 0;
  1927. break;
  1928. case OGT:
  1929. args = GTargs;
  1930. break;
  1931. case OLS:
  1932. args = HIargs;
  1933. true = 0;
  1934. break;
  1935. case OHI:
  1936. args = HIargs;
  1937. break;
  1938. case OLT:
  1939. args = GEargs;
  1940. true = 0;
  1941. break;
  1942. case OGE:
  1943. args = GEargs;
  1944. break;
  1945. case OLO:
  1946. args = HSargs;
  1947. true = 0;
  1948. break;
  1949. case OHS:
  1950. args = HSargs;
  1951. break;
  1952. default:
  1953. diag(n, "bad cmp\n");
  1954. SET(optab);
  1955. }
  1956. switch(lri) {
  1957. case IMM(0, 0):
  1958. biggen(l, r, Z, true, optab[T0i], args);
  1959. break;
  1960. case IMM(0, 1):
  1961. case IMM(1, 0):
  1962. switch(ri) {
  1963. case WNONE:
  1964. diag(l, "bad whatof\n");
  1965. break;
  1966. case WCONST:
  1967. biggen(l, r, Z, true, optab[T0i], args);
  1968. break;
  1969. case WHARD:
  1970. reglcgen(&nod2, r, Z);
  1971. r = &nod2;
  1972. /* fall thru */
  1973. case WADDR:
  1974. biggen(l, r, Z, true, optab[T0i], args);
  1975. if(ri == WHARD)
  1976. regfree(r);
  1977. break;
  1978. }
  1979. break;
  1980. case IMM(1, 1):
  1981. if(li == WHARD) {
  1982. reglcgen(&nod3, l, Z);
  1983. l = &nod3;
  1984. }
  1985. if(ri == WHARD) {
  1986. reglcgen(&nod2, r, Z);
  1987. r = &nod2;
  1988. }
  1989. biggen(l, r, Z, true, optab[Tii], args);
  1990. if(li == WHARD)
  1991. regfree(l);
  1992. if(ri == WHARD)
  1993. regfree(r);
  1994. break;
  1995. }
  1996. switch(lri) {
  1997. case IMM(0, 0):
  1998. freepair(r);
  1999. /* fall thru */;
  2000. case IMM(0, 1):
  2001. case IMM(1, 0):
  2002. freepair(l);
  2003. break;
  2004. case IMM(1, 1):
  2005. break;
  2006. }
  2007. return 1;
  2008. case OASMUL:
  2009. case OASLMUL:
  2010. m = 0;
  2011. goto mulop;
  2012. case OMUL:
  2013. case OLMUL:
  2014. m = 1;
  2015. goto mulop;
  2016. mulop:
  2017. dr = nn != Z && nn->op == OREGPAIR;
  2018. l = vfunc(n->left, nn);
  2019. r = vfunc(n->right, nn);
  2020. if(r->op != OCONST) {
  2021. if(l->complex > r->complex) {
  2022. if(m) {
  2023. t = l;
  2024. l = r;
  2025. r = t;
  2026. }
  2027. else if(!vaddr(l, 1)) {
  2028. reglcgen(&nod5, l, Z);
  2029. l = &nod5;
  2030. evacaxdx(l);
  2031. }
  2032. }
  2033. t = regpair(Z, n);
  2034. sugen(r, t, 8);
  2035. r = t;
  2036. evacaxdx(r->left);
  2037. evacaxdx(r->right);
  2038. if(l->complex <= r->complex && !m && !vaddr(l, 1)) {
  2039. reglcgen(&nod5, l, Z);
  2040. l = &nod5;
  2041. evacaxdx(l);
  2042. }
  2043. }
  2044. if(dr)
  2045. t = nn;
  2046. else
  2047. t = regpair(Z, n);
  2048. //print("dr=%d ", dr); prtree(t, "t");
  2049. c = Z;
  2050. d = Z;
  2051. if(!nodreg(&nod1, t->left, D_AX)) {
  2052. if(t->left->reg != D_AX){
  2053. t->left->reg = D_AX;
  2054. reg[D_AX]++;
  2055. }else if(reg[D_AX] == 0)
  2056. fatal(Z, "vlong mul AX botch");
  2057. }
  2058. if(!nodreg(&nod2, t->right, D_DX)) {
  2059. if(t->right->reg != D_DX){
  2060. t->right->reg = D_DX;
  2061. reg[D_DX]++;
  2062. }else if(reg[D_DX] == 0)
  2063. fatal(Z, "vlong mul DX botch");
  2064. }
  2065. //prtree(t, "t1"); print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
  2066. if(m)
  2067. sugen(l, t, 8);
  2068. else
  2069. loadpair(l, t);
  2070. //prtree(t, "t2"); print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
  2071. if(t->left->reg != D_AX) {
  2072. c = &nod3;
  2073. regsalloc(c, t->left);
  2074. gmove(&nod1, c);
  2075. gmove(t->left, &nod1);
  2076. zapreg(t->left);
  2077. }
  2078. //print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
  2079. if(t->right->reg != D_DX) {
  2080. d = &nod4;
  2081. regsalloc(d, t->right);
  2082. gmove(&nod2, d);
  2083. if(t->right->reg == D_AX && c != nil){
  2084. /* need previous value of AX in DX */
  2085. gmove(c, &nod2);
  2086. }else
  2087. gmove(t->right, &nod2);
  2088. zapreg(t->right);
  2089. }
  2090. if(c != Z || d != Z) {
  2091. s = regpair(Z, n);
  2092. s->left = &nod1;
  2093. s->right = &nod2;
  2094. }
  2095. else
  2096. s = t;
  2097. reg[D_AX]++; /* don't allow biggen to allocate AX or DX (smashed by MUL) as temp */
  2098. reg[D_DX]++;
  2099. if(r->op == OCONST) {
  2100. if(hi64v(r) == 0)
  2101. biggen(s, r, Z, 0, mulc32, nil);
  2102. else
  2103. biggen(s, r, Z, 0, mulc64, nil);
  2104. }
  2105. else
  2106. biggen(s, r, Z, 0, mull, nil);
  2107. instpair(t, Z);
  2108. reg[D_AX]--;
  2109. reg[D_DX]--;
  2110. if(c != Z) {
  2111. gmove(&nod1, t->left);
  2112. gmove(&nod3, &nod1);
  2113. }
  2114. if(d != Z) {
  2115. gmove(&nod2, t->right);
  2116. gmove(&nod4, &nod2);
  2117. }
  2118. if(r->op == OREGPAIR)
  2119. freepair(r);
  2120. if(!m)
  2121. storepair(t, l, 0);
  2122. if(l == &nod5)
  2123. regfree(l);
  2124. if(!dr) {
  2125. if(nn != Z)
  2126. storepair(t, nn, 1);
  2127. else
  2128. freepair(t);
  2129. }
  2130. return 1;
  2131. case OASADD:
  2132. args = ADDargs;
  2133. goto vasop;
  2134. case OASAND:
  2135. args = ANDargs;
  2136. goto vasop;
  2137. case OASOR:
  2138. args = ORargs;
  2139. goto vasop;
  2140. case OASSUB:
  2141. args = SUBargs;
  2142. goto vasop;
  2143. case OASXOR:
  2144. args = XORargs;
  2145. goto vasop;
  2146. vasop:
  2147. l = n->left;
  2148. r = n->right;
  2149. dr = nn != Z && nn->op == OREGPAIR;
  2150. m = 0;
  2151. if(l->complex > r->complex) {
  2152. if(!vaddr(l, 1)) {
  2153. reglcgen(&nod1, l, Z);
  2154. l = &nod1;
  2155. }
  2156. if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
  2157. if(dr)
  2158. t = nn;
  2159. else
  2160. t = regpair(Z, r);
  2161. sugen(r, t, 8);
  2162. r = t;
  2163. m = 1;
  2164. }
  2165. }
  2166. else {
  2167. if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
  2168. if(dr)
  2169. t = nn;
  2170. else
  2171. t = regpair(Z, r);
  2172. sugen(r, t, 8);
  2173. r = t;
  2174. m = 1;
  2175. }
  2176. if(!vaddr(l, 1)) {
  2177. reglcgen(&nod1, l, Z);
  2178. l = &nod1;
  2179. }
  2180. }
  2181. if(nn != Z) {
  2182. if(n->op == OASSUB)
  2183. biggen(l, r, Z, 0, sub10, args);
  2184. else
  2185. biggen(r, l, Z, 0, binoptmp, args);
  2186. storepair(r, l, 0);
  2187. }
  2188. else {
  2189. if(m)
  2190. biggen(l, r, Z, 0, binop00, args);
  2191. else
  2192. biggen(l, r, Z, 0, binoptmp, args);
  2193. }
  2194. if(l == &nod1)
  2195. regfree(&nod1);
  2196. if(m) {
  2197. if(nn == Z)
  2198. freepair(r);
  2199. else if(!dr)
  2200. storepair(r, nn, 1);
  2201. }
  2202. return 1;
  2203. case OASASHL:
  2204. args = nil;
  2205. optab = asshlltab;
  2206. goto assh;
  2207. case OASLSHR:
  2208. args = shrlargs;
  2209. optab = asshrltab;
  2210. goto assh;
  2211. case OASASHR:
  2212. args = sarlargs;
  2213. optab = asshrltab;
  2214. goto assh;
  2215. assh:
  2216. c = Z;
  2217. l = n->left;
  2218. r = n->right;
  2219. if(r->op == OCONST) {
  2220. m = r->vconst & 63;
  2221. if(m < 32)
  2222. m = SAclo;
  2223. else if(m == 32)
  2224. m = SAc32;
  2225. else
  2226. m = SAchi;
  2227. }
  2228. else
  2229. m = SAgen;
  2230. if(l->complex > r->complex) {
  2231. if(!vaddr(l, 0)) {
  2232. reglcgen(&nod1, l, Z);
  2233. l = &nod1;
  2234. }
  2235. if(m == SAgen) {
  2236. t = &nod2;
  2237. if(l->reg == D_CX) {
  2238. regalloc(t, r, Z);
  2239. gmove(l, t);
  2240. l->reg = t->reg;
  2241. t->reg = D_CX;
  2242. }
  2243. else
  2244. c = snarfreg(nn, t, D_CX, r, &nod3);
  2245. cgen(r, t);
  2246. r = t;
  2247. }
  2248. }
  2249. else {
  2250. if(m == SAgen) {
  2251. t = &nod2;
  2252. c = snarfreg(nn, t, D_CX, r, &nod3);
  2253. cgen(r, t);
  2254. r = t;
  2255. }
  2256. if(!vaddr(l, 0)) {
  2257. reglcgen(&nod1, l, Z);
  2258. l = &nod1;
  2259. }
  2260. }
  2261. if(nn != Z) {
  2262. m += SAdgen - SAgen;
  2263. d = regpair(nn, n);
  2264. instpair(d, Z);
  2265. biggen(l, r, d, 0, optab[m], args);
  2266. if(l == &nod1) {
  2267. regfree(&nod1);
  2268. l = Z;
  2269. }
  2270. if(r == &nod2 && c == Z) {
  2271. regfree(&nod2);
  2272. r = Z;
  2273. }
  2274. if(d != nn)
  2275. storepair(d, nn, 1);
  2276. }
  2277. else
  2278. biggen(l, r, Z, 0, optab[m], args);
  2279. if(c != Z) {
  2280. gins(AMOVL, c, r);
  2281. regfree(c);
  2282. }
  2283. if(l == &nod1)
  2284. regfree(&nod1);
  2285. if(r == &nod2)
  2286. regfree(&nod2);
  2287. return 1;
  2288. case OPOSTINC:
  2289. args = ADDargs;
  2290. cp = incdecpost;
  2291. goto vinc;
  2292. case OPOSTDEC:
  2293. args = SUBargs;
  2294. cp = incdecpost;
  2295. goto vinc;
  2296. case OPREINC:
  2297. args = ADDargs;
  2298. cp = incdecpre;
  2299. goto vinc;
  2300. case OPREDEC:
  2301. args = SUBargs;
  2302. cp = incdecpre;
  2303. goto vinc;
  2304. vinc:
  2305. l = n->left;
  2306. if(!vaddr(l, 1)) {
  2307. reglcgen(&nod1, l, Z);
  2308. l = &nod1;
  2309. }
  2310. if(nn != Z) {
  2311. d = regpair(nn, n);
  2312. instpair(d, Z);
  2313. biggen(l, Z, d, 0, cp, args);
  2314. if(l == &nod1) {
  2315. regfree(&nod1);
  2316. l = Z;
  2317. }
  2318. if(d != nn)
  2319. storepair(d, nn, 1);
  2320. }
  2321. else
  2322. biggen(l, Z, Z, 0, incdec, args);
  2323. if(l == &nod1)
  2324. regfree(&nod1);
  2325. return 1;
  2326. case OCAST:
  2327. l = n->left;
  2328. if(typev[l->type->etype]) {
  2329. if(!vaddr(l, 1)) {
  2330. if(l->complex + 1 > nn->complex) {
  2331. d = regpair(Z, l);
  2332. sugen(l, d, 8);
  2333. if(!vaddr(nn, 1)) {
  2334. reglcgen(&nod1, nn, Z);
  2335. r = &nod1;
  2336. }
  2337. else
  2338. r = nn;
  2339. }
  2340. else {
  2341. if(!vaddr(nn, 1)) {
  2342. reglcgen(&nod1, nn, Z);
  2343. r = &nod1;
  2344. }
  2345. else
  2346. r = nn;
  2347. d = regpair(Z, l);
  2348. sugen(l, d, 8);
  2349. }
  2350. // d->left->type = r->type;
  2351. d->left->type = types[TLONG];
  2352. gmove(d->left, r);
  2353. freepair(d);
  2354. }
  2355. else {
  2356. if(nn->op != OREGISTER && !vaddr(nn, 1)) {
  2357. reglcgen(&nod1, nn, Z);
  2358. r = &nod1;
  2359. }
  2360. else
  2361. r = nn;
  2362. // l->type = r->type;
  2363. l->type = types[TLONG];
  2364. gmove(l, r);
  2365. }
  2366. if(r != nn)
  2367. regfree(r);
  2368. }
  2369. else {
  2370. if(typeu[l->type->etype] || cond(l->op))
  2371. si = TUNSIGNED;
  2372. else
  2373. si = TSIGNED;
  2374. regalloc(&nod1, l, Z);
  2375. cgen(l, &nod1);
  2376. if(nn->op == OREGPAIR) {
  2377. m = instpair(nn, &nod1);
  2378. biggen(&nod1, Z, nn, si == TSIGNED, castrp, nil);
  2379. }
  2380. else {
  2381. m = 0;
  2382. if(!vaddr(nn, si != TSIGNED)) {
  2383. dt = nn->type;
  2384. nn->type = types[TLONG];
  2385. reglcgen(&nod2, nn, Z);
  2386. nn->type = dt;
  2387. nn = &nod2;
  2388. }
  2389. dt = nn->type;
  2390. nn->type = types[TLONG];
  2391. biggen(&nod1, Z, nn, si == TSIGNED, castrpa, nil);
  2392. nn->type = dt;
  2393. if(nn == &nod2)
  2394. regfree(&nod2);
  2395. }
  2396. if(!m)
  2397. regfree(&nod1);
  2398. }
  2399. return 1;
  2400. default:
  2401. if(n->op == OREGPAIR) {
  2402. storepair(n, nn, 1);
  2403. return 1;
  2404. }
  2405. if(nn->op == OREGPAIR) {
  2406. loadpair(n, nn);
  2407. return 1;
  2408. }
  2409. return 0;
  2410. }
  2411. finished:
  2412. if(d != nn)
  2413. storepair(d, nn, 1);
  2414. return 1;
  2415. }
  2416. void
  2417. testv(Node *n, int true)
  2418. {
  2419. Type *t;
  2420. Node *nn, nod, *b;
  2421. if(machcap(Z)) {
  2422. b = &nod;
  2423. b->op = true ? ONE : OEQ;
  2424. b->left = n;
  2425. b->right = new(0, Z, Z);
  2426. *b->right = *nodconst(0);
  2427. b->right->type = n->type;
  2428. b->type = types[TLONG];
  2429. cgen64(b, Z);
  2430. return;
  2431. }
  2432. switch(n->op) {
  2433. case OINDREG:
  2434. case ONAME:
  2435. biggen(n, Z, Z, true, testi, nil);
  2436. break;
  2437. default:
  2438. n = vfunc(n, n);
  2439. if(n->addable >= INDEXED) {
  2440. t = n->type;
  2441. n->type = types[TLONG];
  2442. reglcgen(&nod, n, Z);
  2443. n->type = t;
  2444. n = &nod;
  2445. biggen(n, Z, Z, true, testi, nil);
  2446. if(n == &nod)
  2447. regfree(n);
  2448. }
  2449. else {
  2450. nn = regpair(Z, n);
  2451. sugen(n, nn, 8);
  2452. biggen(nn, Z, Z, true, testi, nil);
  2453. freepair(nn);
  2454. }
  2455. }
  2456. }