txt.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. #include "gc.h"
  2. void
  3. tindex(Type *tf, Type *tt)
  4. {
  5. int i, j;
  6. j = 0;
  7. if(tt != T) {
  8. j = tt->etype;
  9. if(j >= NTYPE)
  10. j = 0;
  11. }
  12. i = 0;
  13. if(tf != T) {
  14. i = tf->etype;
  15. if(i >= NTYPE)
  16. if(typesu[i])
  17. i = j;
  18. else
  19. i = 0;
  20. }
  21. txtp = &txt[i][j];
  22. }
  23. void
  24. ginit(void)
  25. {
  26. int i, j, si, sj;
  27. thestring = "68020";
  28. thechar = '2';
  29. exregoffset = 7;
  30. exaregoffset = 5;
  31. exfregoffset = 7;
  32. listinit();
  33. for(i=0; i<NREG; i++) {
  34. regused[i] = 0;
  35. fregused[i] = 0;
  36. aregused[i] = 0;
  37. }
  38. regaddr(D_A0+6);
  39. regaddr(D_A0+7);
  40. for(i=0; i<sizeof(regbase); i++)
  41. regbase[i] = D_NONE;
  42. for(i=0; i<NREG; i++) {
  43. regbase[D_R0+i] = D_R0+i;
  44. regbase[D_A0+i] = D_A0+i;
  45. regbase[D_F0+i] = D_F0+i;
  46. }
  47. regbase[D_TOS] = D_TOS;
  48. for(i=0; i<NTYPE; i++)
  49. for(j=0; j<NTYPE; j++) {
  50. txtp = &txt[i][j];
  51. txtp->movas = AGOK;
  52. txtp->preclr = 0;
  53. txtp->postext = AGOK;
  54. if(!(typechlp[i] && typechlp[j]))
  55. continue;
  56. si = types[i]->width;
  57. sj = types[j]->width;
  58. if(sj < si)
  59. txtp->preclr = -1;
  60. if(sj > si) {
  61. if(typeu[i]) {
  62. txtp->preclr = 1;
  63. } else {
  64. if(sj == 2)
  65. txtp->postext = AEXTBW;
  66. if(sj == 4)
  67. if(si == 1)
  68. txtp->postext = AEXTBL;
  69. else
  70. txtp->postext = AEXTWL;
  71. }
  72. sj = si;
  73. }
  74. if(sj == 1)
  75. txtp->movas = AMOVB;
  76. if(sj == 2)
  77. txtp->movas = AMOVW;
  78. if(sj == 4)
  79. txtp->movas = AMOVL;
  80. }
  81. for(i=0; i<ALLOP; i++)
  82. for(j=0; j<NTYPE; j++)
  83. opxt[i][j] = AGOK;
  84. oinit(OFUNC, ABSR, ATRAP, AGOK, AGOK, AGOK);
  85. oinit(OAS, AMOVB, AMOVW, AMOVL, AFMOVEF, AFMOVED);
  86. oinit(OFAS, AFMOVEB, AFMOVEW, AFMOVEL, AFMOVEF, AFMOVED);
  87. oinit(OADDR, AGOK, APEA, ALEA, AGOK, AGOK);
  88. oinit(OPREINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
  89. oinit(OPOSTINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
  90. oinit(OPREDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
  91. oinit(OPOSTDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
  92. oinit(OADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
  93. oinit(OASADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
  94. oinit(OSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
  95. oinit(OASSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
  96. oinit(OMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
  97. oinit(OLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
  98. oinit(OASMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
  99. oinit(OASLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
  100. oinit(ODIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
  101. oinit(OLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
  102. oinit(OASDIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
  103. oinit(OASLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
  104. oinit(OMOD, AGOK, ADIVSW, ADIVSL, AFMODF, AFMODD);
  105. oinit(OASMOD, AGOK, ADIVSW, ADIVSL, AGOK, AGOK);
  106. oinit(OLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
  107. oinit(OASLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
  108. oinit(OAND, AANDB, AANDW, AANDL, AGOK, AGOK);
  109. oinit(OASAND, AANDB, AANDW, AANDL, AGOK, AGOK);
  110. oinit(OOR, AORB, AORW, AORL, AGOK, AGOK);
  111. oinit(OASOR, AORB, AORW, AORL, AGOK, AGOK);
  112. oinit(OXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
  113. oinit(OASXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
  114. oinit(ONEG, ANEGB, ANEGW, ANEGL, AFNEGF, AFNEGD);
  115. oinit(OCOM, ANOTB, ANOTW, ANOTL, AGOK, AGOK);
  116. oinit(OTST, ATSTB, ATSTW, ATSTL, AFTSTF, AFTSTD);
  117. oinit(OEQ, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  118. oinit(ONE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  119. oinit(OGE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  120. oinit(OGT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  121. oinit(OLT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  122. oinit(OLE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  123. oinit(OLS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  124. oinit(OLO, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  125. oinit(OHS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  126. oinit(OHI, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  127. oinit(OASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
  128. oinit(OASASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
  129. oinit(OLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
  130. oinit(OASLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
  131. oinit(OASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
  132. oinit(OASASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
  133. oinit(OBIT, ABFEXTU, AGOK, AGOK, AGOK, AGOK);
  134. nstring = 0;
  135. mnstring = 0;
  136. nrathole = 0;
  137. nstatic = 0;
  138. pc = 0;
  139. breakpc = -1;
  140. continpc = -1;
  141. cases = C;
  142. firstp = P;
  143. lastp = P;
  144. tfield = types[TLONG];
  145. zprog.link = P;
  146. zprog.as = AGOK;
  147. zprog.from.type = D_NONE;
  148. zprog.from.index = D_NONE;
  149. zprog.to = zprog.from;
  150. nodret = new(ONAME, Z, Z);
  151. nodret->sym = slookup(".ret");
  152. nodret->type = types[TIND];
  153. nodret->etype = types[TIND]->etype;
  154. nodret->class = CPARAM;
  155. nodret = new(OIND, nodret, Z);
  156. complex(nodret);
  157. symrathole = slookup(".rathole");
  158. symrathole->class = CGLOBL;
  159. symrathole->type = typ(TARRAY, types[TCHAR]);
  160. nodrat = new(ONAME, Z, Z);
  161. nodrat->sym = symrathole;
  162. nodrat->type = types[TIND];
  163. nodrat->etype = TVOID;
  164. nodrat->class = CGLOBL;
  165. complex(nodrat);
  166. nodrat->type = symrathole->type;
  167. com64init();
  168. symstatic = slookup(".static");
  169. symstatic->class = CSTATIC;
  170. symstatic->type = typ(TARRAY, types[TLONG]);
  171. }
  172. void
  173. gclean(void)
  174. {
  175. int i;
  176. Sym *s;
  177. regfree(D_A0+6);
  178. regfree(D_A0+7);
  179. for(i=0; i<NREG; i++) {
  180. if(regused[i])
  181. diag(Z, "missing R%d", i);
  182. if(aregused[i])
  183. diag(Z, "missing A%d", i);
  184. if(fregused[i])
  185. diag(Z, "missing F%d", i);
  186. }
  187. while(mnstring)
  188. outstring("", 1L);
  189. symstring->type->width = nstring;
  190. symstatic->type->width = nstatic;
  191. symrathole->type->width = nrathole;
  192. for(i=0; i<NHASH; i++)
  193. for(s = hash[i]; s != S; s = s->link) {
  194. if(s->type == T)
  195. continue;
  196. if(s->type->width == 0)
  197. continue;
  198. if(s->class != CGLOBL && s->class != CSTATIC)
  199. continue;
  200. if(s->type == types[TENUM])
  201. continue;
  202. gpseudo(AGLOBL, s, D_CONST, s->type->width);
  203. pc--;
  204. }
  205. nextpc();
  206. p->as = AEND;
  207. outcode();
  208. }
  209. void
  210. oinit(int o, int ab, int aw, int al, int af, int ad)
  211. {
  212. int i;
  213. i = o;
  214. if(i >= ALLOP) {
  215. diag(Z, "op(%d) >= ALLOP(%d)", i, ALLOP);
  216. errorexit();
  217. }
  218. opxt[i][TCHAR] = ab;
  219. opxt[i][TUCHAR] = ab;
  220. opxt[i][TSHORT] = aw;
  221. opxt[i][TUSHORT] = aw;
  222. opxt[i][TINT] = al;
  223. opxt[i][TUINT] = al;
  224. opxt[i][TLONG] = al;
  225. opxt[i][TULONG] = al;
  226. opxt[i][TIND] = al;
  227. opxt[i][TFLOAT] = af;
  228. opxt[i][TDOUBLE] = ad;
  229. }
  230. Prog*
  231. prg(void)
  232. {
  233. Prog *p;
  234. p = alloc(sizeof(*p));
  235. *p = zprog;
  236. return p;
  237. }
  238. void
  239. nextpc(void)
  240. {
  241. p = prg();
  242. pc++;
  243. p->lineno = nearln;
  244. if(firstp == P) {
  245. firstp = p;
  246. lastp = p;
  247. return;
  248. }
  249. lastp->link = p;
  250. lastp = p;
  251. }
  252. void
  253. gargs(Node *n)
  254. {
  255. long s;
  256. loop:
  257. if(n == Z)
  258. return;
  259. if(n->op == OLIST) {
  260. gargs(n->right);
  261. n = n->left;
  262. goto loop;
  263. }
  264. s = argoff;
  265. cgen(n, D_TOS, n);
  266. argoff = s + n->type->width;
  267. }
  268. void
  269. naddr(Node *n, Adr *a, int x)
  270. {
  271. Node *l;
  272. long v;
  273. switch(n->op) {
  274. default:
  275. bad:
  276. diag(n, "bad in naddr: %O", n->op);
  277. break;
  278. case OADDR:
  279. case OIND:
  280. naddr(n->left, a, x);
  281. goto noadd;
  282. case OREGISTER:
  283. a->sym = S;
  284. a->type = n->reg;
  285. a->offset = n->xoffset;
  286. a->displace = 0;
  287. break;
  288. case ONAME:
  289. a->etype = n->etype;
  290. a->displace = 0;
  291. a->sym = n->sym;
  292. a->offset = n->xoffset;
  293. a->type = D_STATIC;
  294. if(n->class == CSTATIC)
  295. break;
  296. if(n->class == CEXTERN || n->class == CGLOBL) {
  297. a->type = D_EXTERN;
  298. break;
  299. }
  300. if(n->class == CAUTO) {
  301. a->type = D_AUTO;
  302. break;
  303. }
  304. if(n->class == CPARAM) {
  305. a->type = D_PARAM;
  306. break;
  307. }
  308. goto bad;
  309. case OINDEX:
  310. naddr(n->left, a, x);
  311. switch(n->left->addable) {
  312. default:
  313. goto bad;
  314. case 1:
  315. case 12:
  316. a->index = x | I_INDEX1;
  317. a->type &= D_MASK;
  318. break;
  319. case 2:
  320. case 10:
  321. case 11:
  322. a->index = x | I_INDEX2;
  323. break;
  324. }
  325. a->scale = n->scale;
  326. break;
  327. case OCONST:
  328. a->displace = 0;
  329. if(typefd[n->type->etype]) {
  330. a->type = D_FCONST;
  331. a->dval = n->fconst;
  332. break;
  333. }
  334. a->type = D_CONST;
  335. a->offset = n->vconst;
  336. break;
  337. case OADD:
  338. l = n->left;
  339. if(l->addable == 20) {
  340. v = l->vconst;
  341. naddr(n->right, a, x);
  342. goto add;
  343. }
  344. l = n->right;
  345. if(l->addable == 20) {
  346. v = l->vconst;
  347. naddr(n->left, a, x);
  348. goto add;
  349. }
  350. goto bad;
  351. noadd:
  352. v = 0;
  353. add:
  354. switch(n->addable) {
  355. default:
  356. goto bad;
  357. case 2:
  358. a->displace += v;
  359. break;
  360. case 21:
  361. a->type &= D_MASK;
  362. a->type |= I_INDIR;
  363. break;
  364. case 1:
  365. case 12:
  366. a->offset += v;
  367. a->type &= D_MASK;
  368. a->type |= I_ADDR;
  369. break;
  370. case 13:
  371. a->index = D_NONE|I_INDEX3;
  372. case 10:
  373. case 11:
  374. case 20:
  375. a->type &= D_MASK;
  376. a->type |= I_DIR;
  377. break;
  378. }
  379. break;
  380. case OPREINC:
  381. case OPREDEC:
  382. case OPOSTINC:
  383. case OPOSTDEC:
  384. case OAS:
  385. case OASLMUL:
  386. case OASLDIV:
  387. case OASLMOD:
  388. case OASMUL:
  389. case OASDIV:
  390. case OASMOD:
  391. case OASXOR:
  392. case OASOR:
  393. case OASADD:
  394. case OASSUB:
  395. case OASLSHR:
  396. case OASASHR:
  397. case OASASHL:
  398. case OASAND:
  399. naddr(n->left, a, x);
  400. break;
  401. }
  402. }
  403. int
  404. regalloc(Type *t, int g)
  405. {
  406. if(t == T)
  407. return D_NONE;
  408. g &= D_MASK;
  409. if(typefd[t->etype]) {
  410. if(g >= D_F0 && g < D_F0+NREG) {
  411. fregused[g-D_F0]++;
  412. return g;
  413. }
  414. for(g=0; g<NREG; g++)
  415. if(fregused[g] == 0) {
  416. fregused[g]++;
  417. return g + D_F0;
  418. }
  419. } else {
  420. if(g >= D_R0 && g < D_R0+NREG) {
  421. regused[g-D_R0]++;
  422. return g;
  423. }
  424. for(g=0; g<NREG; g++)
  425. if(regused[g] == 0) {
  426. regused[g]++;
  427. return g + D_R0;
  428. }
  429. }
  430. diag(Z, "out of registers");
  431. return D_TOS;
  432. }
  433. int
  434. regaddr(int g)
  435. {
  436. if(g >= D_A0 && g < D_A0+NREG) {
  437. aregused[g-D_A0]++;
  438. return g;
  439. }
  440. for(g=0; g<NREG; g++)
  441. if(aregused[g] == 0) {
  442. aregused[g]++;
  443. return g + D_A0;
  444. }
  445. diag(Z, "out of addr registers");
  446. return D_TOS;
  447. }
  448. int
  449. regpair(int g)
  450. {
  451. if(g >= D_R0+1 && g < D_R0+NREG)
  452. if(!regused[g-D_R0-1]) {
  453. regused[g-D_R0-1]++;
  454. regused[g-D_R0]++;
  455. return g-1;
  456. }
  457. if(g >= D_R0 && g < D_R0+NREG-1)
  458. if(!regused[g-D_R0+1]) {
  459. regused[g-D_R0+1]++;
  460. regused[g-D_R0]++;
  461. return g;
  462. }
  463. for(g = 0; g < NREG-1; g++)
  464. if(!regused[g])
  465. if(!regused[g+1]) {
  466. regused[g]++;
  467. regused[g+1]++;
  468. return g + D_R0;
  469. }
  470. diag(Z, "out of register pairs");
  471. return D_TOS;
  472. }
  473. int
  474. regret(Type *t)
  475. {
  476. if(t == T)
  477. return D_NONE;
  478. if(typefd[t->etype])
  479. return D_F0;
  480. return D_R0;
  481. }
  482. void
  483. regfree(int g)
  484. {
  485. g &= D_MASK;
  486. if(g == D_TOS || g == D_TREE || g == D_NONE)
  487. return;
  488. if(g >= D_R0 && g < D_R0+NREG) {
  489. regused[g-D_R0]--;
  490. return;
  491. }
  492. if(g >= D_A0 && g < D_A0+NREG) {
  493. aregused[g-D_A0]--;
  494. return;
  495. }
  496. if(g >= D_F0 && g < D_F0+NREG) {
  497. fregused[g-D_F0]--;
  498. return;
  499. }
  500. diag(Z, "bad in regfree: %d", g);
  501. }
  502. void
  503. gmove(Type *tf, Type *tt, int gf, Node *f, int gt, Node *t)
  504. {
  505. int g, a, b;
  506. Prog *p1;
  507. tindex(tf, tt);
  508. if(txtp->preclr) {
  509. if(gf >= D_R0 && gf < D_R0+NREG)
  510. if(txtp->preclr < 0) {
  511. gmove(tt, tt, gf, f, gt, t);
  512. return;
  513. }
  514. g = regalloc(types[TLONG], gt);
  515. if(g == gf) {
  516. g = regalloc(types[TLONG], D_NONE);
  517. regfree(gf);
  518. }
  519. if(txtp->preclr > 0)
  520. gopcode(OAS, types[TLONG], D_CONST, nodconst(0), g, Z);
  521. gopcode(OAS, tf, gf, f, g, Z);
  522. if(g != gt)
  523. gopcode(OAS, tt, g, Z, gt, t);
  524. regfree(g);
  525. return;
  526. }
  527. a = txtp->postext;
  528. if(a != AGOK) {
  529. if(gf >= D_R0 && gf < D_R0+NREG)
  530. g = regalloc(types[TLONG], gf);
  531. else
  532. g = regalloc(types[TLONG], gt);
  533. if(g != gf)
  534. gopcode(OAS, tf, gf, f, g, Z);
  535. nextpc();
  536. p->as = a;
  537. p->to.type = g;
  538. if(debug['g'])
  539. print("%P\n", p);
  540. if(g != gt)
  541. gopcode(OAS, tt, g, Z, gt, t);
  542. regfree(g);
  543. return;
  544. }
  545. if((regbase[gf] != D_NONE && regbase[gf] == regbase[gt]) ||
  546. (gf == D_TREE && gt == D_TREE && f == t))
  547. return;
  548. if(typefd[tf->etype] || typefd[tt->etype]) {
  549. if(typeu[tf->etype] && typefd[tt->etype]) { /* unsign->float */
  550. a = regalloc(types[TLONG], D_NONE);
  551. gmove(tf, types[TLONG], gf, f, a, t);
  552. if(tf->etype == TULONG) {
  553. b = regalloc(types[TDOUBLE], D_NONE);
  554. gmove(types[TLONG], tt, a, t, b, t);
  555. gopcode(OTST, types[TLONG], D_NONE, Z, a, t);
  556. gbranch(OGE);
  557. p1 = p;
  558. gopcode(OASADD, types[TDOUBLE],
  559. D_CONST, nodconst(100), b, t);
  560. p->from.dval = 4294967296.;
  561. patch(p1, pc);
  562. gmove(types[TDOUBLE], tt, b, t, gt, t);
  563. regfree(b);
  564. } else
  565. gmove(types[TLONG], tt, a, t, gt, t);
  566. regfree(a);
  567. return;
  568. }
  569. if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
  570. a = regalloc(types[TLONG], D_NONE);
  571. gopcode(OAS, types[TLONG], D_FPCR, t, a, t);
  572. gopcode(OAS, types[TLONG], D_CONST, nodconst(16), D_FPCR, t);
  573. }
  574. if(gf < D_F0 || gf >= D_F0+NREG) {
  575. g = regalloc(types[TDOUBLE], gt);
  576. gopcode(OFAS, tf, gf, f, g, t);
  577. if(g != gt)
  578. gopcode(OFAS, tt, g, t, gt, t);
  579. regfree(g);
  580. } else
  581. gopcode(OFAS, tt, gf, f, gt, t);
  582. if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
  583. gopcode(OAS, types[TLONG], a, t, D_FPCR, t);
  584. regfree(a);
  585. }
  586. return;
  587. }
  588. gopcode(OAS, tt, gf, f, gt, t);
  589. }
  590. void
  591. gopcode(int o, Type *ty, int gf, Node *f, int gt, Node *t)
  592. {
  593. int i, fidx, tidx;
  594. long v;
  595. if(o == OAS)
  596. if(gf == gt)
  597. if(gf != D_TREE || f == t)
  598. return;
  599. fidx = D_NONE;
  600. if(gf == D_TREE) {
  601. if(f->op == OINDEX) {
  602. fidx = regalloc(types[TIND], fidx);
  603. cgen(f->right, fidx, f->right);
  604. }
  605. }
  606. tidx = D_NONE;
  607. if(gt == D_TREE) {
  608. if(t->op == OINDEX) {
  609. v = argoff;
  610. tidx = regalloc(types[TIND], tidx);
  611. cgen(t->right, tidx, t->right);
  612. if(gf == D_TOS)
  613. adjsp(v - argoff);
  614. }
  615. }
  616. i = 0;
  617. if(ty != T) {
  618. i = ty->etype;
  619. if(i >= NTYPE)
  620. i = 0;
  621. }
  622. nextpc();
  623. if(gf == D_TREE) {
  624. naddr(f, &p->from, fidx);
  625. } else {
  626. p->from.type = gf;
  627. if(gf == D_CONST) {
  628. p->from.offset = (long)f;
  629. if(typefd[i]) {
  630. p->from.type = D_FCONST;
  631. p->from.dval = (long)f;
  632. }
  633. }
  634. }
  635. p->as = opxt[o][i];
  636. if(gt == D_TREE) {
  637. naddr(t, &p->to, tidx);
  638. } else {
  639. p->to.type = gt;
  640. if(gt == D_CONST)
  641. p->to.offset = (long)t;
  642. }
  643. if(o == OBIT) {
  644. p->from.field = f->type->nbits;
  645. p->to.field = f->type->shift;
  646. if(p->from.field == 0)
  647. diag(Z, "BIT zero width bit field");
  648. }
  649. if(p->as == AMOVL || p->as == AMOVW || p->as == AMOVB)
  650. asopt();
  651. if(debug['g'])
  652. print("%P\n", p);
  653. if(p->as == AGOK)
  654. diag(Z, "GOK in gopcode: %s", onames[o]);
  655. if(fidx != D_NONE)
  656. regfree(fidx);
  657. if(tidx != D_NONE)
  658. regfree(tidx);
  659. }
  660. void
  661. asopt(void)
  662. {
  663. long v;
  664. int g;
  665. Prog *q;
  666. /*
  667. * mov $0, ...
  668. * ==>
  669. * clr , ...
  670. */
  671. v = 0;
  672. if(p->from.type == D_CONST) {
  673. v = p->from.offset;
  674. if(v == 0) {
  675. p->from.type = D_NONE;
  676. if(p->as == AMOVL)
  677. p->as = ACLRL;
  678. if(p->as == AMOVW)
  679. p->as = ACLRW;
  680. if(p->as == AMOVB)
  681. p->as = ACLRB;
  682. return;
  683. }
  684. }
  685. /*
  686. * mov ..., TOS
  687. * ==>
  688. * pea (...)
  689. */
  690. if(p->as == AMOVL && p->to.type == D_TOS && p->from.index == D_NONE)
  691. switch(p->from.type) {
  692. case D_CONST:
  693. p->from.type |= I_INDIR;
  694. p->to = p->from;
  695. p->from = zprog.from;
  696. p->as = APEA;
  697. return;
  698. case I_ADDR|D_EXTERN:
  699. case I_ADDR|D_STATIC:
  700. p->from.type &= ~I_ADDR;
  701. p->to = p->from;
  702. p->from = zprog.from;
  703. p->as = APEA;
  704. return;
  705. }
  706. /*
  707. * movL $Qx, ...
  708. * ==>
  709. * movL $Qx,R
  710. * movL R, ...
  711. */
  712. if(p->as == AMOVL && p->from.type == D_CONST)
  713. if(v >= -128 && v < 128)
  714. if(p->to.type < D_R0 || p->to.type >= D_R0+NREG) {
  715. g = regalloc(types[TLONG], D_NONE);
  716. q = p;
  717. nextpc();
  718. p->as = AMOVL;
  719. p->from.type = g;
  720. p->to = q->to;
  721. q->to = p->from;
  722. regfree(g);
  723. if(debug['g'])
  724. print("%P\n", q);
  725. return;
  726. }
  727. }
  728. void
  729. gbranch(int o)
  730. {
  731. int a;
  732. a = ABNE;
  733. switch(o) {
  734. case ORETURN: a = ARTS; break;
  735. case OGOTO: a = ABRA; break;
  736. case OEQ: a = ABEQ; break;
  737. case ONE: a = ABNE; break;
  738. case OLE: a = ABLE; break;
  739. case OLS: a = ABLS; break;
  740. case OLT: a = ABLT; break;
  741. case OLO: a = ABCS; break;
  742. case OGE: a = ABGE; break;
  743. case OHS: a = ABCC; break;
  744. case OGT: a = ABGT; break;
  745. case OHI: a = ABHI; break;
  746. case OBIT: a = ABCS; break;
  747. case OCASE: a = ABCASE; break;
  748. }
  749. nextpc();
  750. p->from.type = D_NONE;
  751. p->to.type = D_NONE;
  752. p->as = a;
  753. }
  754. void
  755. fpbranch(void)
  756. {
  757. int a;
  758. a = p->as;
  759. switch(a) {
  760. case ABEQ: a = AFBEQ; break;
  761. case ABNE: a = AFBNE; break;
  762. case ABLE: a = AFBLE; break;
  763. case ABLT: a = AFBLT; break;
  764. case ABGE: a = AFBGE; break;
  765. case ABGT: a = AFBGT; break;
  766. }
  767. p->as = a;
  768. }
  769. void
  770. patch(Prog *op, long pc)
  771. {
  772. op->to.offset = pc;
  773. op->to.type = D_BRANCH;
  774. }
  775. void
  776. gpseudo(int a, Sym *s, int g, long v)
  777. {
  778. nextpc();
  779. if(a == ADATA)
  780. pc--;
  781. p->as = a;
  782. if(g != D_TREE) {
  783. p->to.type = g;
  784. p->to.offset = v;
  785. } else
  786. naddr((Node*)v, &p->to, D_NONE);
  787. p->from.sym = s;
  788. p->from.type = D_EXTERN;
  789. if(s->class == CSTATIC)
  790. p->from.type = D_STATIC;
  791. }
  792. long
  793. exreg(Type *t)
  794. {
  795. long o;
  796. if(typechl[t->etype]) {
  797. if(exregoffset <= 5)
  798. return 0;
  799. o = exregoffset + D_R0;
  800. exregoffset--;
  801. return o;
  802. }
  803. if(t->etype == TIND) {
  804. if(exaregoffset <= 3)
  805. return 0;
  806. o = exaregoffset + D_A0;
  807. exaregoffset--;
  808. return o;
  809. }
  810. if(typefd[t->etype]) {
  811. if(exfregoffset <= 5)
  812. return 0;
  813. o = exfregoffset + D_F0;
  814. exfregoffset--;
  815. return o;
  816. }
  817. return 0;
  818. }
  819. schar ewidth[NTYPE] =
  820. {
  821. -1, /* [TXXX] */
  822. SZ_CHAR, /* [TCHAR] */
  823. SZ_CHAR, /* [TUCHAR] */
  824. SZ_SHORT, /* [TSHORT] */
  825. SZ_SHORT, /* [TUSHORT] */
  826. SZ_INT, /* [TINT] */
  827. SZ_INT, /* [TUINT] */
  828. SZ_LONG, /* [TLONG] */
  829. SZ_LONG, /* [TULONG] */
  830. SZ_VLONG, /* [TVLONG] */
  831. SZ_VLONG, /* [TUVLONG] */
  832. SZ_FLOAT, /* [TFLOAT] */
  833. SZ_DOUBLE, /* [TDOUBLE] */
  834. SZ_IND, /* [TIND] */
  835. 0, /* [TFUNC] */
  836. -1, /* [TARRAY] */
  837. 0, /* [TVOID] */
  838. -1, /* [TSTRUCT] */
  839. -1, /* [TUNION] */
  840. SZ_INT, /* [TENUM] */
  841. };
  842. long ncast[NTYPE] =
  843. {
  844. 0, /* [TXXX] */
  845. BCHAR|BUCHAR, /* [TCHAR] */
  846. BCHAR|BUCHAR, /* [TUCHAR] */
  847. BSHORT|BUSHORT, /* [TSHORT] */
  848. BSHORT|BUSHORT, /* [TUSHORT] */
  849. BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
  850. BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
  851. BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
  852. BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
  853. BVLONG|BUVLONG, /* [TVLONG] */
  854. BVLONG|BUVLONG, /* [TUVLONG] */
  855. BFLOAT, /* [TFLOAT] */
  856. BDOUBLE, /* [TDOUBLE] */
  857. BLONG|BULONG|BIND, /* [TIND] */
  858. 0, /* [TFUNC] */
  859. 0, /* [TARRAY] */
  860. 0, /* [TVOID] */
  861. BSTRUCT, /* [TSTRUCT] */
  862. BUNION, /* [TUNION] */
  863. 0, /* [TENUM] */
  864. };