txt.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  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 = "68000";
  28. thechar = '1';
  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. else
  67. if(sj == 4)
  68. if(si == 1)
  69. txtp->postext = AEXTBL;
  70. else
  71. txtp->postext = AEXTWL;
  72. }
  73. sj = si;
  74. }
  75. if(sj == 1)
  76. txtp->movas = AMOVB;
  77. if(sj == 2)
  78. txtp->movas = AMOVW;
  79. if(sj == 4)
  80. txtp->movas = AMOVL;
  81. }
  82. for(i=0; i<ALLOP; i++)
  83. for(j=0; j<NTYPE; j++)
  84. opxt[i][j] = AGOK;
  85. oinit(OFUNC, ABSR, ATRAP, AGOK, AGOK, AGOK);
  86. oinit(OAS, AMOVB, AMOVW, AMOVL, AFMOVEF, AFMOVED);
  87. oinit(OFAS, AFMOVEB, AFMOVEW, AFMOVEL, AFMOVEF, AFMOVED);
  88. oinit(OADDR, AGOK, APEA, ALEA, AGOK, AGOK);
  89. oinit(OPREINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
  90. oinit(OPOSTINC, AADDB, AADDW, AADDL, AFADDF, AFADDD);
  91. oinit(OPREDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
  92. oinit(OPOSTDEC, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
  93. oinit(OADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
  94. oinit(OASADD, AADDB, AADDW, AADDL, AFADDF, AFADDD);
  95. oinit(OSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
  96. oinit(OASSUB, ASUBB, ASUBW, ASUBL, AFSUBF, AFSUBD);
  97. oinit(OMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
  98. oinit(OLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
  99. oinit(OASMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
  100. oinit(OASLMUL, AGOK, AMULSW, AMULSL, AFMULF, AFMULD);
  101. oinit(ODIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
  102. oinit(OLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
  103. oinit(OASDIV, AGOK, ADIVSW, ADIVSL, AFDIVF, AFDIVD);
  104. oinit(OASLDIV, AGOK, ADIVUW, ADIVUL, AFDIVF, AFDIVD);
  105. oinit(OMOD, AGOK, ADIVSW, ADIVSL, AFMODF, AFMODD);
  106. oinit(OASMOD, AGOK, ADIVSW, ADIVSL, AGOK, AGOK);
  107. oinit(OLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
  108. oinit(OASLMOD, AGOK, ADIVUW, ADIVUL, AGOK, AGOK);
  109. oinit(OAND, AANDB, AANDW, AANDL, AGOK, AGOK);
  110. oinit(OASAND, AANDB, AANDW, AANDL, AGOK, AGOK);
  111. oinit(OOR, AORB, AORW, AORL, AGOK, AGOK);
  112. oinit(OASOR, AORB, AORW, AORL, AGOK, AGOK);
  113. oinit(OXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
  114. oinit(OASXOR, AEORB, AEORW, AEORL, AGOK, AGOK);
  115. oinit(ONEG, ANEGB, ANEGW, ANEGL, AFNEGF, AFNEGD);
  116. oinit(OCOM, ANOTB, ANOTW, ANOTL, AGOK, AGOK);
  117. oinit(OTST, ATSTB, ATSTW, ATSTL, AFTSTF, AFTSTD);
  118. oinit(OEQ, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  119. oinit(ONE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  120. oinit(OGE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  121. oinit(OGT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  122. oinit(OLT, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  123. oinit(OLE, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  124. oinit(OLS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  125. oinit(OLO, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  126. oinit(OHS, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  127. oinit(OHI, ACMPB, ACMPW, ACMPL, AFCMPF, AFCMPD);
  128. oinit(OASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
  129. oinit(OASASHR, AASRB, AASRW, AASRL, AGOK, AGOK);
  130. oinit(OLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
  131. oinit(OASLSHR, ALSRB, ALSRW, ALSRL, AGOK, AGOK);
  132. oinit(OASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
  133. oinit(OASASHL, AASLB, AASLW, AASLL, AGOK, AGOK);
  134. oinit(OBIT, ABFEXTU, AGOK, AGOK, AGOK, AGOK);
  135. nstring = 0;
  136. mnstring = 0;
  137. nrathole = 0;
  138. nstatic = 0;
  139. pc = 0;
  140. breakpc = -1;
  141. continpc = -1;
  142. cases = C;
  143. firstp = P;
  144. lastp = P;
  145. tfield = types[TLONG];
  146. zprog.link = P;
  147. zprog.as = AGOK;
  148. zprog.from.type = 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 OCONST:
  310. a->displace = 0;
  311. if(typefd[n->type->etype]) {
  312. a->type = D_FCONST;
  313. a->dval = n->fconst;
  314. break;
  315. }
  316. a->type = D_CONST;
  317. a->offset = n->vconst;
  318. break;
  319. case OADD:
  320. l = n->left;
  321. if(l->addable == 20) {
  322. v = l->vconst;
  323. naddr(n->right, a, x);
  324. goto add;
  325. }
  326. l = n->right;
  327. if(l->addable == 20) {
  328. v = l->vconst;
  329. naddr(n->left, a, x);
  330. goto add;
  331. }
  332. goto bad;
  333. noadd:
  334. v = 0;
  335. add:
  336. switch(n->addable) {
  337. default:
  338. goto bad;
  339. case 2:
  340. a->displace += v;
  341. break;
  342. case 21:
  343. a->type &= D_MASK;
  344. a->type |= I_INDIR;
  345. break;
  346. case 1:
  347. case 12:
  348. a->offset += v;
  349. a->type &= D_MASK;
  350. a->type |= I_ADDR;
  351. break;
  352. case 10:
  353. case 11:
  354. case 20:
  355. a->type &= D_MASK;
  356. a->type |= I_DIR;
  357. break;
  358. }
  359. break;
  360. case OPREINC:
  361. case OPREDEC:
  362. case OPOSTINC:
  363. case OPOSTDEC:
  364. case OAS:
  365. case OASLMUL:
  366. case OASLDIV:
  367. case OASLMOD:
  368. case OASMUL:
  369. case OASDIV:
  370. case OASMOD:
  371. case OASXOR:
  372. case OASOR:
  373. case OASADD:
  374. case OASSUB:
  375. case OASLSHR:
  376. case OASASHR:
  377. case OASASHL:
  378. case OASAND:
  379. naddr(n->left, a, x);
  380. break;
  381. }
  382. }
  383. int
  384. regalloc(Type *t, int g)
  385. {
  386. if(t == T)
  387. return D_NONE;
  388. g &= D_MASK;
  389. if(typefd[t->etype]) {
  390. if(g >= D_F0 && g < D_F0+NREG) {
  391. fregused[g-D_F0]++;
  392. return g;
  393. }
  394. for(g=0; g<NREG; g++)
  395. if(fregused[g] == 0) {
  396. fregused[g]++;
  397. return g + D_F0;
  398. }
  399. } else {
  400. if(g >= D_R0 && g < D_R0+NREG) {
  401. regused[g-D_R0]++;
  402. return g;
  403. }
  404. for(g=0; g<NREG; g++)
  405. if(regused[g] == 0) {
  406. regused[g]++;
  407. return g + D_R0;
  408. }
  409. }
  410. diag(Z, "out of registers");
  411. return D_TOS;
  412. }
  413. int
  414. regaddr(int g)
  415. {
  416. if(g >= D_A0 && g < D_A0+NREG) {
  417. aregused[g-D_A0]++;
  418. return g;
  419. }
  420. for(g=0; g<NREG; g++)
  421. if(aregused[g] == 0) {
  422. aregused[g]++;
  423. return g + D_A0;
  424. }
  425. diag(Z, "out of addr registers");
  426. return D_TOS;
  427. }
  428. int
  429. regpair(int g)
  430. {
  431. if(g >= D_R0+1 && g < D_R0+NREG)
  432. if(!regused[g-D_R0-1]) {
  433. regused[g-D_R0-1]++;
  434. regused[g-D_R0]++;
  435. return g-1;
  436. }
  437. if(g >= D_R0 && g < D_R0+NREG-1)
  438. if(!regused[g-D_R0+1]) {
  439. regused[g-D_R0+1]++;
  440. regused[g-D_R0]++;
  441. return g;
  442. }
  443. for(g = 0; g < NREG-1; g++)
  444. if(!regused[g])
  445. if(!regused[g+1]) {
  446. regused[g]++;
  447. regused[g+1]++;
  448. return g + D_R0;
  449. }
  450. diag(Z, "out of register pairs");
  451. return D_TOS;
  452. }
  453. int
  454. regret(Type *t)
  455. {
  456. if(t == T)
  457. return D_NONE;
  458. if(typefd[t->etype])
  459. return D_F0;
  460. return D_R0;
  461. }
  462. void
  463. regfree(int g)
  464. {
  465. g &= D_MASK;
  466. if(g == D_TOS || g == D_TREE || g == D_NONE)
  467. return;
  468. if(g >= D_R0 && g < D_R0+NREG) {
  469. regused[g-D_R0]--;
  470. return;
  471. }
  472. if(g >= D_A0 && g < D_A0+NREG) {
  473. aregused[g-D_A0]--;
  474. return;
  475. }
  476. if(g >= D_F0 && g < D_F0+NREG) {
  477. fregused[g-D_F0]--;
  478. return;
  479. }
  480. diag(Z, "bad in regfree: %d", g);
  481. }
  482. void
  483. gmove(Type *tf, Type *tt, int gf, Node *f, int gt, Node *t)
  484. {
  485. int g, a, b;
  486. Prog *p1;
  487. tindex(tf, tt);
  488. if(txtp->preclr) {
  489. if(gf >= D_R0 && gf < D_R0+NREG)
  490. if(txtp->preclr < 0) {
  491. gmove(tt, tt, gf, f, gt, t);
  492. return;
  493. }
  494. g = regalloc(types[TLONG], gt);
  495. if(g == gf) {
  496. g = regalloc(types[TLONG], D_NONE);
  497. regfree(gf);
  498. }
  499. if(txtp->preclr > 0)
  500. gopcode(OAS, types[TLONG], D_CONST, nodconst(0), g, Z);
  501. gopcode(OAS, tf, gf, f, g, Z);
  502. if(g != gt)
  503. gopcode(OAS, tt, g, Z, gt, t);
  504. regfree(g);
  505. return;
  506. }
  507. a = txtp->postext;
  508. if(a != AGOK) {
  509. if(gf >= D_R0 && gf < D_R0+NREG)
  510. g = regalloc(types[TLONG], gf);
  511. else
  512. g = regalloc(types[TLONG], gt);
  513. if(g != gf)
  514. gopcode(OAS, tf, gf, f, g, Z);
  515. nextpc();
  516. p->as = a;
  517. p->to.type = g;
  518. if(debug['g'])
  519. print("%P\n", p);
  520. if(g != gt)
  521. gopcode(OAS, tt, g, Z, gt, t);
  522. regfree(g);
  523. return;
  524. }
  525. if((regbase[gf] != D_NONE && regbase[gf] == regbase[gt]) ||
  526. (gf == D_TREE && gt == D_TREE && f == t))
  527. return;
  528. if(typefd[tf->etype] || typefd[tt->etype]) {
  529. if(typeu[tf->etype] && typefd[tt->etype]) { /* unsign->float */
  530. a = regalloc(types[TLONG], D_NONE);
  531. gmove(tf, types[TLONG], gf, f, a, t);
  532. if(tf->etype == TULONG) {
  533. b = regalloc(types[TDOUBLE], D_NONE);
  534. gmove(types[TLONG], tt, a, t, b, t);
  535. gopcode(OTST, types[TLONG], D_NONE, Z, a, t);
  536. gbranch(OGE);
  537. p1 = p;
  538. gopcode(OASADD, types[TDOUBLE],
  539. D_CONST, nodconst(100), b, t);
  540. p->from.dval = 4294967296.;
  541. patch(p1, pc);
  542. gmove(types[TDOUBLE], tt, b, t, gt, t);
  543. regfree(b);
  544. } else
  545. gmove(types[TLONG], tt, a, t, gt, t);
  546. regfree(a);
  547. return;
  548. }
  549. if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
  550. a = regalloc(types[TLONG], D_NONE);
  551. gopcode(OAS, types[TLONG], D_FPCR, t, a, t);
  552. gopcode(OAS, types[TLONG], D_CONST, nodconst(16), D_FPCR, t);
  553. }
  554. if(gf < D_F0 || gf >= D_F0+NREG) {
  555. g = regalloc(types[TDOUBLE], gt);
  556. gopcode(OFAS, tf, gf, f, g, t);
  557. if(g != gt)
  558. gopcode(OFAS, tt, g, t, gt, t);
  559. regfree(g);
  560. } else
  561. gopcode(OFAS, tt, gf, f, gt, t);
  562. if(typefd[tf->etype] && !typefd[tt->etype]) { /* float->fix */
  563. gopcode(OAS, types[TLONG], a, t, D_FPCR, t);
  564. regfree(a);
  565. }
  566. return;
  567. }
  568. gopcode(OAS, tt, gf, f, gt, t);
  569. }
  570. void
  571. gopcode(int o, Type *ty, int gf, Node *f, int gt, Node *t)
  572. {
  573. int i, fidx, tidx;
  574. if(o == OAS)
  575. if(gf == gt)
  576. if(gf != D_TREE || f == t)
  577. return;
  578. fidx = D_NONE;
  579. tidx = D_NONE;
  580. i = 0;
  581. if(ty != T) {
  582. i = ty->etype;
  583. if(i >= NTYPE)
  584. i = 0;
  585. }
  586. nextpc();
  587. if(gf == D_TREE) {
  588. naddr(f, &p->from, fidx);
  589. } else {
  590. p->from.type = gf;
  591. if(gf == D_CONST) {
  592. p->from.offset = (long)(uintptr)f;
  593. if(typefd[i]) {
  594. p->from.type = D_FCONST;
  595. p->from.dval = (long)(uintptr)f;
  596. }
  597. }
  598. }
  599. p->as = opxt[o][i];
  600. if(gt == D_TREE) {
  601. naddr(t, &p->to, tidx);
  602. } else {
  603. p->to.type = gt;
  604. if(gt == D_CONST)
  605. p->to.offset = (long)(uintptr)t;
  606. }
  607. if(o == OBIT) {
  608. p->from.field = f->type->nbits;
  609. p->to.field = f->type->shift;
  610. if(p->from.field == 0)
  611. diag(Z, "BIT zero width bit field");
  612. }
  613. if(p->as == AMOVL || p->as == AMOVW || p->as == AMOVB)
  614. asopt();
  615. if(debug['g'])
  616. print("%P\n", p);
  617. if(p->as == AGOK)
  618. diag(Z, "GOK in gopcode: %s", onames[o]);
  619. if(fidx != D_NONE)
  620. regfree(fidx);
  621. if(tidx != D_NONE)
  622. regfree(tidx);
  623. }
  624. void
  625. asopt(void)
  626. {
  627. long v;
  628. int g;
  629. Prog *q;
  630. /*
  631. * mov $0, ...
  632. * ==>
  633. * clr , ...
  634. */
  635. v = 0;
  636. if(p->from.type == D_CONST) {
  637. v = p->from.offset;
  638. if(v == 0) {
  639. p->from.type = D_NONE;
  640. if(p->as == AMOVL)
  641. p->as = ACLRL;
  642. if(p->as == AMOVW)
  643. p->as = ACLRW;
  644. if(p->as == AMOVB)
  645. p->as = ACLRB;
  646. return;
  647. }
  648. }
  649. /*
  650. * mov ..., TOS
  651. * ==>
  652. * pea (...)
  653. */
  654. if(p->as == AMOVL && p->to.type == D_TOS)
  655. switch(p->from.type) {
  656. case D_CONST:
  657. p->from.type |= I_INDIR;
  658. p->to = p->from;
  659. p->from = zprog.from;
  660. p->as = APEA;
  661. return;
  662. case I_ADDR|D_EXTERN:
  663. case I_ADDR|D_STATIC:
  664. p->from.type &= ~I_ADDR;
  665. p->to = p->from;
  666. p->from = zprog.from;
  667. p->as = APEA;
  668. return;
  669. }
  670. /*
  671. * movL $Qx, ...
  672. * ==>
  673. * movL $Qx,R
  674. * movL R, ...
  675. */
  676. if(p->as == AMOVL && p->from.type == D_CONST)
  677. if(v >= -128 && v < 128)
  678. if(p->to.type < D_R0 || p->to.type >= D_R0+NREG) {
  679. g = regalloc(types[TLONG], D_NONE);
  680. q = p;
  681. nextpc();
  682. p->as = AMOVL;
  683. p->from.type = g;
  684. p->to = q->to;
  685. q->to = p->from;
  686. regfree(g);
  687. if(debug['g'])
  688. print("%P\n", q);
  689. return;
  690. }
  691. }
  692. void
  693. gbranch(int o)
  694. {
  695. int a;
  696. a = ABNE;
  697. switch(o) {
  698. case ORETURN: a = ARTS; break;
  699. case OGOTO: a = ABRA; break;
  700. case OEQ: a = ABEQ; break;
  701. case ONE: a = ABNE; break;
  702. case OLE: a = ABLE; break;
  703. case OLS: a = ABLS; break;
  704. case OLT: a = ABLT; break;
  705. case OLO: a = ABCS; break;
  706. case OGE: a = ABGE; break;
  707. case OHS: a = ABCC; break;
  708. case OGT: a = ABGT; break;
  709. case OHI: a = ABHI; break;
  710. case OBIT: a = ABCS; break;
  711. case OCASE: a = ABCASE; break;
  712. }
  713. nextpc();
  714. p->from.type = D_NONE;
  715. p->to.type = D_NONE;
  716. p->as = a;
  717. }
  718. void
  719. fpbranch(void)
  720. {
  721. int a;
  722. a = p->as;
  723. switch(a) {
  724. case ABEQ: a = AFBEQ; break;
  725. case ABNE: a = AFBNE; break;
  726. case ABLE: a = AFBLE; break;
  727. case ABLT: a = AFBLT; break;
  728. case ABGE: a = AFBGE; break;
  729. case ABGT: a = AFBGT; break;
  730. }
  731. p->as = a;
  732. }
  733. void
  734. patch(Prog *op, long pc)
  735. {
  736. op->to.offset = pc;
  737. op->to.type = D_BRANCH;
  738. }
  739. void
  740. gpseudo(int a, Sym *s, int g, long v)
  741. {
  742. nextpc();
  743. if(a == ADATA)
  744. pc--;
  745. p->as = a;
  746. p->to.type = g;
  747. p->to.offset = v;
  748. p->from.sym = s;
  749. p->from.type = D_EXTERN;
  750. if(s->class == CSTATIC)
  751. p->from.type = D_STATIC;
  752. }
  753. void
  754. gpseudotree(int a, Sym *s, Node *n)
  755. {
  756. nextpc();
  757. if(a == ADATA)
  758. pc--;
  759. p->as = a;
  760. naddr(n, &p->to, D_NONE);
  761. p->from.sym = s;
  762. p->from.type = D_EXTERN;
  763. if(s->class == CSTATIC)
  764. p->from.type = D_STATIC;
  765. }
  766. long
  767. exreg(Type *t)
  768. {
  769. long o;
  770. if(typechl[t->etype]) {
  771. if(exregoffset <= 5)
  772. return 0;
  773. o = exregoffset + D_R0;
  774. exregoffset--;
  775. return o;
  776. }
  777. if(t->etype == TIND) {
  778. if(exaregoffset <= 3)
  779. return 0;
  780. o = exaregoffset + D_A0;
  781. exaregoffset--;
  782. return o;
  783. }
  784. if(typefd[t->etype]) {
  785. if(exfregoffset <= 5)
  786. return 0;
  787. o = exfregoffset + D_F0;
  788. exfregoffset--;
  789. return o;
  790. }
  791. return 0;
  792. }
  793. schar ewidth[NTYPE] =
  794. {
  795. -1, /* [TXXX] */
  796. SZ_CHAR, /* [TCHAR] */
  797. SZ_CHAR, /* [TUCHAR] */
  798. SZ_SHORT, /* [TSHORT] */
  799. SZ_SHORT, /* [TUSHORT] */
  800. SZ_INT, /* [TINT] */
  801. SZ_INT, /* [TUINT] */
  802. SZ_LONG, /* [TLONG] */
  803. SZ_LONG, /* [TULONG] */
  804. SZ_VLONG, /* [TVLONG] */
  805. SZ_VLONG, /* [TUVLONG] */
  806. SZ_FLOAT, /* [TFLOAT] */
  807. SZ_DOUBLE, /* [TDOUBLE] */
  808. SZ_IND, /* [TIND] */
  809. 0, /* [TFUNC] */
  810. -1, /* [TARRAY] */
  811. 0, /* [TVOID] */
  812. -1, /* [TSTRUCT] */
  813. -1, /* [TUNION] */
  814. SZ_INT, /* [TENUM] */
  815. };
  816. long ncast[NTYPE] =
  817. {
  818. 0, /* [TXXX] */
  819. BCHAR|BUCHAR, /* [TCHAR] */
  820. BCHAR|BUCHAR, /* [TUCHAR] */
  821. BSHORT|BUSHORT, /* [TSHORT] */
  822. BSHORT|BUSHORT, /* [TUSHORT] */
  823. BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
  824. BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
  825. BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
  826. BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
  827. BVLONG|BUVLONG, /* [TVLONG] */
  828. BVLONG|BUVLONG, /* [TUVLONG] */
  829. BFLOAT, /* [TFLOAT] */
  830. BDOUBLE, /* [TDOUBLE] */
  831. BLONG|BULONG|BIND, /* [TIND] */
  832. 0, /* [TFUNC] */
  833. 0, /* [TARRAY] */
  834. 0, /* [TVOID] */
  835. BSTRUCT, /* [TSTRUCT] */
  836. BUNION, /* [TUNION] */
  837. 0, /* [TENUM] */
  838. };