txt.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446
  1. #include "gc.h"
  2. void
  3. ginit(void)
  4. {
  5. int i;
  6. Type *t;
  7. thechar = '8';
  8. thestring = "386";
  9. exregoffset = 0;
  10. exfregoffset = 0;
  11. listinit();
  12. nstring = 0;
  13. mnstring = 0;
  14. nrathole = 0;
  15. pc = 0;
  16. breakpc = -1;
  17. continpc = -1;
  18. cases = C;
  19. firstp = P;
  20. lastp = P;
  21. tfield = types[TLONG];
  22. typeswitch = typechlv;
  23. zprog.link = P;
  24. zprog.as = AGOK;
  25. zprog.from.type = D_NONE;
  26. zprog.from.index = D_NONE;
  27. zprog.from.scale = 0;
  28. zprog.to = zprog.from;
  29. regnode.op = OREGISTER;
  30. regnode.class = CEXREG;
  31. regnode.reg = REGTMP;
  32. regnode.complex = 0;
  33. regnode.addable = 11;
  34. regnode.type = types[TLONG];
  35. fregnode0 = regnode;
  36. fregnode0.reg = D_F0;
  37. fregnode0.type = types[TDOUBLE];
  38. fregnode1 = fregnode0;
  39. fregnode1.reg = D_F0+1;
  40. constnode.op = OCONST;
  41. constnode.class = CXXX;
  42. constnode.complex = 0;
  43. constnode.addable = 20;
  44. constnode.type = types[TLONG];
  45. fconstnode.op = OCONST;
  46. fconstnode.class = CXXX;
  47. fconstnode.complex = 0;
  48. fconstnode.addable = 20;
  49. fconstnode.type = types[TDOUBLE];
  50. nodsafe = new(ONAME, Z, Z);
  51. nodsafe->sym = slookup(".safe");
  52. nodsafe->type = types[TINT];
  53. nodsafe->etype = types[TINT]->etype;
  54. nodsafe->class = CAUTO;
  55. complex(nodsafe);
  56. t = typ(TARRAY, types[TCHAR]);
  57. symrathole = slookup(".rathole");
  58. symrathole->class = CGLOBL;
  59. symrathole->type = t;
  60. nodrat = new(ONAME, Z, Z);
  61. nodrat->sym = symrathole;
  62. nodrat->type = types[TIND];
  63. nodrat->etype = TVOID;
  64. nodrat->class = CGLOBL;
  65. complex(nodrat);
  66. nodrat->type = t;
  67. nodret = new(ONAME, Z, Z);
  68. nodret->sym = slookup(".ret");
  69. nodret->type = types[TIND];
  70. nodret->etype = TIND;
  71. nodret->class = CPARAM;
  72. nodret = new(OIND, nodret, Z);
  73. complex(nodret);
  74. com64init();
  75. for(i=0; i<nelem(reg); i++) {
  76. reg[i] = 1;
  77. if(i >= D_AX && i <= D_DI && i != D_SP)
  78. reg[i] = 0;
  79. }
  80. }
  81. void
  82. gclean(void)
  83. {
  84. int i;
  85. Sym *s;
  86. reg[D_SP]--;
  87. for(i=D_AX; i<=D_DI; i++)
  88. if(reg[i])
  89. diag(Z, "reg %R left allocated", i);
  90. while(mnstring)
  91. outstring("", 1L);
  92. symstring->type->width = nstring;
  93. symrathole->type->width = nrathole;
  94. for(i=0; i<NHASH; i++)
  95. for(s = hash[i]; s != S; s = s->link) {
  96. if(s->type == T)
  97. continue;
  98. if(s->type->width == 0)
  99. continue;
  100. if(s->class != CGLOBL && s->class != CSTATIC)
  101. continue;
  102. if(s->type == types[TENUM])
  103. continue;
  104. gpseudo(AGLOBL, s, nodconst(s->type->width));
  105. }
  106. nextpc();
  107. p->as = AEND;
  108. outcode();
  109. }
  110. void
  111. nextpc(void)
  112. {
  113. p = alloc(sizeof(*p));
  114. *p = zprog;
  115. p->lineno = nearln;
  116. pc++;
  117. if(firstp == P) {
  118. firstp = p;
  119. lastp = p;
  120. return;
  121. }
  122. lastp->link = p;
  123. lastp = p;
  124. }
  125. void
  126. gargs(Node *n, Node *tn1, Node *tn2)
  127. {
  128. long regs;
  129. Node fnxargs[20], *fnxp;
  130. regs = cursafe;
  131. fnxp = fnxargs;
  132. garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
  133. curarg = 0;
  134. fnxp = fnxargs;
  135. garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
  136. cursafe = regs;
  137. }
  138. int
  139. nareg(int notbp)
  140. {
  141. int i, n;
  142. n = 0;
  143. for(i=D_AX; i<=D_DI; i++)
  144. if(reg[i] == 0)
  145. n++;
  146. if(notbp && reg[D_BP] == 0)
  147. n--;
  148. return n;
  149. }
  150. void
  151. garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
  152. {
  153. Node nod;
  154. if(n == Z)
  155. return;
  156. if(n->op == OLIST) {
  157. garg1(n->left, tn1, tn2, f, fnxp);
  158. garg1(n->right, tn1, tn2, f, fnxp);
  159. return;
  160. }
  161. if(f == 0) {
  162. if(n->complex >= FNX) {
  163. regsalloc(*fnxp, n);
  164. nod = znode;
  165. nod.op = OAS;
  166. nod.left = *fnxp;
  167. nod.right = n;
  168. nod.type = n->type;
  169. cgen(&nod, Z);
  170. (*fnxp)++;
  171. }
  172. return;
  173. }
  174. if(typesu[n->type->etype] || typev[n->type->etype]) {
  175. regaalloc(tn2, n);
  176. if(n->complex >= FNX) {
  177. sugen(*fnxp, tn2, n->type->width);
  178. (*fnxp)++;
  179. } else
  180. sugen(n, tn2, n->type->width);
  181. return;
  182. }
  183. if(REGARG>=0 && curarg == 0 && typeilp[n->type->etype]) {
  184. regaalloc1(tn1, n);
  185. if(n->complex >= FNX) {
  186. cgen(*fnxp, tn1);
  187. (*fnxp)++;
  188. } else
  189. cgen(n, tn1);
  190. return;
  191. }
  192. if(vconst(n) == 0) {
  193. regaalloc(tn2, n);
  194. gmove(n, tn2);
  195. return;
  196. }
  197. regalloc(tn1, n, Z);
  198. if(n->complex >= FNX) {
  199. cgen(*fnxp, tn1);
  200. (*fnxp)++;
  201. } else
  202. cgen(n, tn1);
  203. regaalloc(tn2, n);
  204. gmove(tn1, tn2);
  205. regfree(tn1);
  206. }
  207. Node*
  208. nodconst(long v)
  209. {
  210. constnode.vconst = v;
  211. return &constnode;
  212. }
  213. Node*
  214. nodfconst(double d)
  215. {
  216. fconstnode.fconst = d;
  217. return &fconstnode;
  218. }
  219. int
  220. isreg(Node *n, int r)
  221. {
  222. if(n->op == OREGISTER)
  223. if(n->reg == r)
  224. return 1;
  225. return 0;
  226. }
  227. int
  228. nodreg(Node *n, Node *nn, int r)
  229. {
  230. *n = regnode;
  231. n->reg = r;
  232. if(reg[r] == 0)
  233. return 0;
  234. if(nn != Z) {
  235. n->type = nn->type;
  236. n->lineno = nn->lineno;
  237. if(nn->op == OREGISTER)
  238. if(nn->reg == r)
  239. return 0;
  240. }
  241. return 1;
  242. }
  243. void
  244. regret(Node *n, Node *nn)
  245. {
  246. int r;
  247. r = REGRET;
  248. if(typefd[nn->type->etype])
  249. r = FREGRET;
  250. nodreg(n, nn, r);
  251. reg[r]++;
  252. }
  253. void
  254. regalloc(Node *n, Node *tn, Node *o)
  255. {
  256. int i;
  257. switch(tn->type->etype) {
  258. case TCHAR:
  259. case TUCHAR:
  260. case TSHORT:
  261. case TUSHORT:
  262. case TINT:
  263. case TUINT:
  264. case TLONG:
  265. case TULONG:
  266. case TIND:
  267. if(o != Z && o->op == OREGISTER) {
  268. i = o->reg;
  269. if(i >= D_AX && i <= D_DI)
  270. goto out;
  271. }
  272. for(i=D_AX; i<=D_DI; i++)
  273. if(reg[i] == 0)
  274. goto out;
  275. diag(tn, "out of fixed registers");
  276. abort();
  277. goto err;
  278. case TFLOAT:
  279. case TDOUBLE:
  280. i = D_F0;
  281. goto out;
  282. case TVLONG:
  283. case TUVLONG:
  284. n->op = OREGPAIR;
  285. n->complex = 0; /* already in registers */
  286. n->addable = 11;
  287. n->type = tn->type;
  288. n->lineno = nearln;
  289. n->left = alloc(sizeof(Node));
  290. n->right = alloc(sizeof(Node));
  291. if(o != Z && o->op == OREGPAIR) {
  292. regalloc(n->left, &regnode, o->left);
  293. regalloc(n->right, &regnode, o->right);
  294. } else {
  295. regalloc(n->left, &regnode, Z);
  296. regalloc(n->right, &regnode, Z);
  297. }
  298. n->right->type = types[TULONG];
  299. if(tn->type->etype == TUVLONG)
  300. n->left->type = types[TULONG];
  301. return;
  302. }
  303. diag(tn, "unknown type in regalloc: %T", tn->type);
  304. err:
  305. i = 0;
  306. out:
  307. if(i)
  308. reg[i]++;
  309. nodreg(n, tn, i);
  310. //print("+ %R %d\n", i, reg[i]);
  311. }
  312. void
  313. regialloc(Node *n, Node *tn, Node *o)
  314. {
  315. Node nod;
  316. nod = *tn;
  317. nod.type = types[TIND];
  318. regalloc(n, &nod, o);
  319. }
  320. void
  321. regfree(Node *n)
  322. {
  323. int i;
  324. if(n->op == OREGPAIR) {
  325. regfree(n->left);
  326. regfree(n->right);
  327. return;
  328. }
  329. i = 0;
  330. if(n->op != OREGISTER && n->op != OINDREG)
  331. goto err;
  332. i = n->reg;
  333. if(i < 0 || i >= sizeof(reg))
  334. goto err;
  335. if(reg[i] <= 0)
  336. goto err;
  337. reg[i]--;
  338. //print("- %R %d\n", i, reg[i]);
  339. return;
  340. err:
  341. diag(n, "error in regfree: %R", i);
  342. }
  343. void
  344. regsalloc(Node *n, Node *nn)
  345. {
  346. cursafe = align(cursafe, nn->type, Aaut3);
  347. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  348. *n = *nodsafe;
  349. n->xoffset = -(stkoff + cursafe);
  350. n->type = nn->type;
  351. n->etype = nn->type->etype;
  352. n->lineno = nn->lineno;
  353. }
  354. void
  355. regaalloc1(Node *n, Node *nn)
  356. {
  357. USED(nn);
  358. if(REGARG < 0) {
  359. diag(n, "regaalloc1");
  360. return;
  361. }
  362. /* not reached
  363. nodreg(n, nn, REGARG);
  364. reg[REGARG]++;
  365. curarg = align(curarg, nn->type, Aarg1);
  366. curarg = align(curarg, nn->type, Aarg2);
  367. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  368. */
  369. }
  370. void
  371. regaalloc(Node *n, Node *nn)
  372. {
  373. curarg = align(curarg, nn->type, Aarg1);
  374. *n = *nn;
  375. n->op = OINDREG;
  376. n->reg = REGSP;
  377. n->xoffset = curarg;
  378. n->complex = 0;
  379. n->addable = 20;
  380. curarg = align(curarg, nn->type, Aarg2);
  381. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  382. }
  383. void
  384. regind(Node *n, Node *nn)
  385. {
  386. if(n->op != OREGISTER) {
  387. diag(n, "regind not OREGISTER");
  388. return;
  389. }
  390. n->op = OINDREG;
  391. n->type = nn->type;
  392. }
  393. void
  394. naddr(Node *n, Adr *a)
  395. {
  396. long v;
  397. a->type = D_NONE;
  398. if(n == Z)
  399. return;
  400. switch(n->op) {
  401. default:
  402. bad:
  403. diag(n, "bad in naddr: %O %D", n->op, a);
  404. //prtree(n, "naddr");
  405. break;
  406. case OREGISTER:
  407. a->type = n->reg;
  408. a->sym = S;
  409. break;
  410. case OEXREG:
  411. a->type = D_INDIR + D_GS;
  412. a->offset = n->reg - 1;
  413. a->etype = n->etype;
  414. break;
  415. case OIND:
  416. naddr(n->left, a);
  417. if(a->type >= D_AX && a->type <= D_DI)
  418. a->type += D_INDIR;
  419. else
  420. if(a->type == D_CONST)
  421. a->type = D_NONE+D_INDIR;
  422. else
  423. if(a->type == D_ADDR) {
  424. a->type = a->index;
  425. a->index = D_NONE;
  426. } else
  427. goto bad;
  428. break;
  429. case OINDEX:
  430. a->type = idx.ptr;
  431. if(n->left->op == OADDR || n->left->op == OCONST)
  432. naddr(n->left, a);
  433. if(a->type >= D_AX && a->type <= D_DI)
  434. a->type += D_INDIR;
  435. else
  436. if(a->type == D_CONST)
  437. a->type = D_NONE+D_INDIR;
  438. else
  439. if(a->type == D_ADDR) {
  440. a->type = a->index;
  441. a->index = D_NONE;
  442. } else
  443. goto bad;
  444. a->index = idx.reg;
  445. a->scale = n->scale;
  446. a->offset += n->xoffset;
  447. break;
  448. case OINDREG:
  449. a->type = n->reg+D_INDIR;
  450. a->sym = S;
  451. a->offset = n->xoffset;
  452. break;
  453. case ONAME:
  454. a->etype = n->etype;
  455. a->type = D_STATIC;
  456. a->sym = n->sym;
  457. a->offset = n->xoffset;
  458. if(n->class == CSTATIC)
  459. break;
  460. if(n->class == CEXTERN || n->class == CGLOBL) {
  461. a->type = D_EXTERN;
  462. break;
  463. }
  464. if(n->class == CAUTO) {
  465. a->type = D_AUTO;
  466. break;
  467. }
  468. if(n->class == CPARAM) {
  469. a->type = D_PARAM;
  470. break;
  471. }
  472. goto bad;
  473. case OCONST:
  474. if(typefd[n->type->etype]) {
  475. a->type = D_FCONST;
  476. a->dval = n->fconst;
  477. break;
  478. }
  479. a->sym = S;
  480. a->type = D_CONST;
  481. a->offset = n->vconst;
  482. break;
  483. case OADDR:
  484. naddr(n->left, a);
  485. if(a->type >= D_INDIR) {
  486. a->type -= D_INDIR;
  487. break;
  488. }
  489. if(a->type == D_EXTERN || a->type == D_STATIC ||
  490. a->type == D_AUTO || a->type == D_PARAM)
  491. if(a->index == D_NONE) {
  492. a->index = a->type;
  493. a->type = D_ADDR;
  494. break;
  495. }
  496. goto bad;
  497. case OADD:
  498. if(n->right->op == OCONST) {
  499. v = n->right->vconst;
  500. naddr(n->left, a);
  501. } else
  502. if(n->left->op == OCONST) {
  503. v = n->left->vconst;
  504. naddr(n->right, a);
  505. } else
  506. goto bad;
  507. a->offset += v;
  508. break;
  509. }
  510. }
  511. #define CASE(a,b) ((a<<8)|(b<<0))
  512. void
  513. gmove(Node *f, Node *t)
  514. {
  515. int ft, tt, a;
  516. Node nod, nod1;
  517. Prog *p1;
  518. ft = f->type->etype;
  519. tt = t->type->etype;
  520. if(debug['M'])
  521. print("gop: %O %O[%s],%O[%s]\n", OAS,
  522. f->op, tnames[ft], t->op, tnames[tt]);
  523. if(typefd[ft] && f->op == OCONST) {
  524. if(f->fconst == 0)
  525. gins(AFLDZ, Z, Z);
  526. else
  527. if(f->fconst == 1)
  528. gins(AFLD1, Z, Z);
  529. else
  530. gins(AFMOVD, f, &fregnode0);
  531. gmove(&fregnode0, t);
  532. return;
  533. }
  534. /*
  535. * load
  536. */
  537. if(f->op == ONAME || f->op == OINDREG ||
  538. f->op == OIND || f->op == OINDEX)
  539. switch(ft) {
  540. case TCHAR:
  541. a = AMOVBLSX;
  542. goto ld;
  543. case TUCHAR:
  544. a = AMOVBLZX;
  545. goto ld;
  546. case TSHORT:
  547. if(typefd[tt]) {
  548. gins(AFMOVW, f, &fregnode0);
  549. gmove(&fregnode0, t);
  550. return;
  551. }
  552. a = AMOVWLSX;
  553. goto ld;
  554. case TUSHORT:
  555. a = AMOVWLZX;
  556. goto ld;
  557. case TINT:
  558. case TUINT:
  559. case TLONG:
  560. case TULONG:
  561. case TIND:
  562. if(typefd[tt]) {
  563. gins(AFMOVL, f, &fregnode0);
  564. gmove(&fregnode0, t);
  565. return;
  566. }
  567. a = AMOVL;
  568. ld:
  569. regalloc(&nod, f, t);
  570. nod.type = types[TLONG];
  571. gins(a, f, &nod);
  572. gmove(&nod, t);
  573. regfree(&nod);
  574. return;
  575. case TFLOAT:
  576. gins(AFMOVF, f, t);
  577. return;
  578. case TDOUBLE:
  579. gins(AFMOVD, f, t);
  580. return;
  581. }
  582. /*
  583. * store
  584. */
  585. if(t->op == ONAME || t->op == OINDREG ||
  586. t->op == OIND || t->op == OINDEX)
  587. switch(tt) {
  588. case TCHAR:
  589. case TUCHAR:
  590. a = AMOVB; goto st;
  591. case TSHORT:
  592. case TUSHORT:
  593. a = AMOVW; goto st;
  594. case TINT:
  595. case TUINT:
  596. case TLONG:
  597. case TULONG:
  598. case TIND:
  599. a = AMOVL; goto st;
  600. st:
  601. if(f->op == OCONST) {
  602. gins(a, f, t);
  603. return;
  604. }
  605. regalloc(&nod, t, f);
  606. gmove(f, &nod);
  607. gins(a, &nod, t);
  608. regfree(&nod);
  609. return;
  610. case TFLOAT:
  611. gins(AFMOVFP, f, t);
  612. return;
  613. case TDOUBLE:
  614. gins(AFMOVDP, f, t);
  615. return;
  616. }
  617. /*
  618. * convert
  619. */
  620. switch(CASE(ft,tt)) {
  621. default:
  622. /*
  623. * integer to integer
  624. ********
  625. a = AGOK; break;
  626. case CASE( TCHAR, TCHAR):
  627. case CASE( TUCHAR, TCHAR):
  628. case CASE( TSHORT, TCHAR):
  629. case CASE( TUSHORT,TCHAR):
  630. case CASE( TINT, TCHAR):
  631. case CASE( TUINT, TCHAR):
  632. case CASE( TLONG, TCHAR):
  633. case CASE( TULONG, TCHAR):
  634. case CASE( TIND, TCHAR):
  635. case CASE( TCHAR, TUCHAR):
  636. case CASE( TUCHAR, TUCHAR):
  637. case CASE( TSHORT, TUCHAR):
  638. case CASE( TUSHORT,TUCHAR):
  639. case CASE( TINT, TUCHAR):
  640. case CASE( TUINT, TUCHAR):
  641. case CASE( TLONG, TUCHAR):
  642. case CASE( TULONG, TUCHAR):
  643. case CASE( TIND, TUCHAR):
  644. case CASE( TSHORT, TSHORT):
  645. case CASE( TUSHORT,TSHORT):
  646. case CASE( TINT, TSHORT):
  647. case CASE( TUINT, TSHORT):
  648. case CASE( TLONG, TSHORT):
  649. case CASE( TULONG, TSHORT):
  650. case CASE( TIND, TSHORT):
  651. case CASE( TSHORT, TUSHORT):
  652. case CASE( TUSHORT,TUSHORT):
  653. case CASE( TINT, TUSHORT):
  654. case CASE( TUINT, TUSHORT):
  655. case CASE( TLONG, TUSHORT):
  656. case CASE( TULONG, TUSHORT):
  657. case CASE( TIND, TUSHORT):
  658. case CASE( TINT, TINT):
  659. case CASE( TUINT, TINT):
  660. case CASE( TLONG, TINT):
  661. case CASE( TULONG, TINT):
  662. case CASE( TIND, TINT):
  663. case CASE( TINT, TUINT):
  664. case CASE( TUINT, TUINT):
  665. case CASE( TLONG, TUINT):
  666. case CASE( TULONG, TUINT):
  667. case CASE( TIND, TUINT):
  668. case CASE( TINT, TLONG):
  669. case CASE( TUINT, TLONG):
  670. case CASE( TLONG, TLONG):
  671. case CASE( TULONG, TLONG):
  672. case CASE( TIND, TLONG):
  673. case CASE( TINT, TULONG):
  674. case CASE( TUINT, TULONG):
  675. case CASE( TLONG, TULONG):
  676. case CASE( TULONG, TULONG):
  677. case CASE( TIND, TULONG):
  678. case CASE( TINT, TIND):
  679. case CASE( TUINT, TIND):
  680. case CASE( TLONG, TIND):
  681. case CASE( TULONG, TIND):
  682. case CASE( TIND, TIND):
  683. *****/
  684. a = AMOVL;
  685. break;
  686. case CASE( TSHORT, TINT):
  687. case CASE( TSHORT, TUINT):
  688. case CASE( TSHORT, TLONG):
  689. case CASE( TSHORT, TULONG):
  690. case CASE( TSHORT, TIND):
  691. a = AMOVWLSX;
  692. if(f->op == OCONST) {
  693. f->vconst &= 0xffff;
  694. if(f->vconst & 0x8000)
  695. f->vconst |= 0xffff0000;
  696. a = AMOVL;
  697. }
  698. break;
  699. case CASE( TUSHORT,TINT):
  700. case CASE( TUSHORT,TUINT):
  701. case CASE( TUSHORT,TLONG):
  702. case CASE( TUSHORT,TULONG):
  703. case CASE( TUSHORT,TIND):
  704. a = AMOVWLZX;
  705. if(f->op == OCONST) {
  706. f->vconst &= 0xffff;
  707. a = AMOVL;
  708. }
  709. break;
  710. case CASE( TCHAR, TSHORT):
  711. case CASE( TCHAR, TUSHORT):
  712. case CASE( TCHAR, TINT):
  713. case CASE( TCHAR, TUINT):
  714. case CASE( TCHAR, TLONG):
  715. case CASE( TCHAR, TULONG):
  716. case CASE( TCHAR, TIND):
  717. a = AMOVBLSX;
  718. if(f->op == OCONST) {
  719. f->vconst &= 0xff;
  720. if(f->vconst & 0x80)
  721. f->vconst |= 0xffffff00;
  722. a = AMOVL;
  723. }
  724. break;
  725. case CASE( TUCHAR, TSHORT):
  726. case CASE( TUCHAR, TUSHORT):
  727. case CASE( TUCHAR, TINT):
  728. case CASE( TUCHAR, TUINT):
  729. case CASE( TUCHAR, TLONG):
  730. case CASE( TUCHAR, TULONG):
  731. case CASE( TUCHAR, TIND):
  732. a = AMOVBLZX;
  733. if(f->op == OCONST) {
  734. f->vconst &= 0xff;
  735. a = AMOVL;
  736. }
  737. break;
  738. /*
  739. * float to fix
  740. */
  741. case CASE( TFLOAT, TCHAR):
  742. case CASE( TFLOAT, TUCHAR):
  743. case CASE( TFLOAT, TSHORT):
  744. case CASE( TFLOAT, TUSHORT):
  745. case CASE( TFLOAT, TINT):
  746. case CASE( TFLOAT, TLONG):
  747. case CASE( TFLOAT, TIND):
  748. case CASE( TDOUBLE,TCHAR):
  749. case CASE( TDOUBLE,TUCHAR):
  750. case CASE( TDOUBLE,TSHORT):
  751. case CASE( TDOUBLE,TUSHORT):
  752. case CASE( TDOUBLE,TINT):
  753. case CASE( TDOUBLE,TLONG):
  754. case CASE( TDOUBLE,TIND):
  755. if(fproundflg) {
  756. regsalloc(&nod, &regnode);
  757. gins(AFMOVLP, f, &nod);
  758. gmove(&nod, t);
  759. return;
  760. }
  761. regsalloc(&nod, &regnode);
  762. regsalloc(&nod1, &regnode);
  763. gins(AFSTCW, Z, &nod1);
  764. nod1.xoffset += 2;
  765. gins(AMOVW, nodconst(0xf7f), &nod1);
  766. gins(AFLDCW, &nod1, Z);
  767. gins(AFMOVLP, f, &nod);
  768. nod1.xoffset -= 2;
  769. gins(AFLDCW, &nod1, Z);
  770. gmove(&nod, t);
  771. return;
  772. /*
  773. * float to ulong
  774. */
  775. case CASE( TDOUBLE, TULONG):
  776. case CASE( TFLOAT, TULONG):
  777. case CASE( TDOUBLE, TUINT):
  778. case CASE( TFLOAT, TUINT):
  779. regsalloc(&nod, &regnode);
  780. gmove(f, &fregnode0);
  781. gins(AFADDD, nodfconst(-2147483648.), &fregnode0);
  782. gins(AFMOVLP, f, &nod);
  783. gins(ASUBL, nodconst(-2147483648), &nod);
  784. gmove(&nod, t);
  785. return;
  786. /*
  787. * ulong to float
  788. */
  789. case CASE( TULONG, TDOUBLE):
  790. case CASE( TULONG, TFLOAT):
  791. case CASE( TUINT, TDOUBLE):
  792. case CASE( TUINT, TFLOAT):
  793. regalloc(&nod, f, f);
  794. gmove(f, &nod);
  795. regsalloc(&nod1, &regnode);
  796. gmove(&nod, &nod1);
  797. gins(AFMOVL, &nod1, &fregnode0);
  798. gins(ACMPL, &nod, nodconst(0));
  799. gins(AJGE, Z, Z);
  800. p1 = p;
  801. gins(AFADDD, nodfconst(4294967296.), &fregnode0);
  802. patch(p1, pc);
  803. regfree(&nod);
  804. return;
  805. /*
  806. * fix to float
  807. */
  808. case CASE( TCHAR, TFLOAT):
  809. case CASE( TUCHAR, TFLOAT):
  810. case CASE( TSHORT, TFLOAT):
  811. case CASE( TUSHORT,TFLOAT):
  812. case CASE( TINT, TFLOAT):
  813. case CASE( TLONG, TFLOAT):
  814. case CASE( TIND, TFLOAT):
  815. case CASE( TCHAR, TDOUBLE):
  816. case CASE( TUCHAR, TDOUBLE):
  817. case CASE( TSHORT, TDOUBLE):
  818. case CASE( TUSHORT,TDOUBLE):
  819. case CASE( TINT, TDOUBLE):
  820. case CASE( TLONG, TDOUBLE):
  821. case CASE( TIND, TDOUBLE):
  822. regsalloc(&nod, &regnode);
  823. gmove(f, &nod);
  824. gins(AFMOVL, &nod, &fregnode0);
  825. return;
  826. /*
  827. * float to float
  828. */
  829. case CASE( TFLOAT, TFLOAT):
  830. case CASE( TDOUBLE,TFLOAT):
  831. case CASE( TFLOAT, TDOUBLE):
  832. case CASE( TDOUBLE,TDOUBLE):
  833. a = AFMOVD; break;
  834. }
  835. if(a == AMOVL || a == AFMOVD)
  836. if(samaddr(f, t))
  837. return;
  838. gins(a, f, t);
  839. }
  840. void
  841. doindex(Node *n)
  842. {
  843. Node nod, nod1;
  844. long v;
  845. if(debug['Y'])
  846. prtree(n, "index");
  847. if(n->left->complex >= FNX)
  848. print("botch in doindex\n");
  849. regalloc(&nod, &regnode, Z);
  850. v = constnode.vconst;
  851. cgen(n->right, &nod);
  852. idx.ptr = D_NONE;
  853. if(n->left->op == OCONST)
  854. idx.ptr = D_CONST;
  855. else if(n->left->op == OREGISTER)
  856. // else if(n->left->op == OREGISTER && typeil[n->left->type->etype])
  857. idx.ptr = n->left->reg;
  858. else if(n->left->op != OADDR) {
  859. reg[D_BP]++; // cant be used as a base
  860. regalloc(&nod1, &regnode, Z);
  861. cgen(n->left, &nod1);
  862. idx.ptr = nod1.reg;
  863. regfree(&nod1);
  864. reg[D_BP]--;
  865. }
  866. idx.reg = nod.reg;
  867. regfree(&nod);
  868. constnode.vconst = v;
  869. }
  870. void
  871. gins(int a, Node *f, Node *t)
  872. {
  873. if(f != Z && f->op == OINDEX)
  874. doindex(f);
  875. if(t != Z && t->op == OINDEX)
  876. doindex(t);
  877. nextpc();
  878. p->as = a;
  879. if(f != Z)
  880. naddr(f, &p->from);
  881. if(t != Z)
  882. naddr(t, &p->to);
  883. if(debug['g'])
  884. print("%P\n", p);
  885. }
  886. void
  887. fgopcode(int o, Node *f, Node *t, int pop, int rev)
  888. {
  889. int a, et;
  890. Node nod;
  891. et = TLONG;
  892. if(f != Z && f->type != T)
  893. et = f->type->etype;
  894. if(!typefd[et]) {
  895. diag(f, "fop: integer %O", o);
  896. return;
  897. }
  898. if(debug['M']) {
  899. if(t != Z && t->type != T)
  900. print("gop: %O %O-%s Z\n", o, f->op, tnames[et]);
  901. else
  902. print("gop: %O %O-%s %O-%s\n", o,
  903. f->op, tnames[et], t->op, tnames[t->type->etype]);
  904. }
  905. a = AGOK;
  906. switch(o) {
  907. case OASADD:
  908. case OADD:
  909. if(et == TFLOAT)
  910. a = AFADDF;
  911. else
  912. if(et == TDOUBLE) {
  913. a = AFADDD;
  914. if(pop)
  915. a = AFADDDP;
  916. }
  917. break;
  918. case OASSUB:
  919. case OSUB:
  920. if(et == TFLOAT) {
  921. a = AFSUBF;
  922. if(rev)
  923. a = AFSUBRF;
  924. } else
  925. if(et == TDOUBLE) {
  926. a = AFSUBD;
  927. if(pop)
  928. a = AFSUBDP;
  929. if(rev) {
  930. a = AFSUBRD;
  931. if(pop)
  932. a = AFSUBRDP;
  933. }
  934. }
  935. break;
  936. case OASMUL:
  937. case OMUL:
  938. if(et == TFLOAT)
  939. a = AFMULF;
  940. else
  941. if(et == TDOUBLE) {
  942. a = AFMULD;
  943. if(pop)
  944. a = AFMULDP;
  945. }
  946. break;
  947. case OASMOD:
  948. case OMOD:
  949. case OASDIV:
  950. case ODIV:
  951. if(et == TFLOAT) {
  952. a = AFDIVF;
  953. if(rev)
  954. a = AFDIVRF;
  955. } else
  956. if(et == TDOUBLE) {
  957. a = AFDIVD;
  958. if(pop)
  959. a = AFDIVDP;
  960. if(rev) {
  961. a = AFDIVRD;
  962. if(pop)
  963. a = AFDIVRDP;
  964. }
  965. }
  966. break;
  967. case OEQ:
  968. case ONE:
  969. case OLT:
  970. case OLE:
  971. case OGE:
  972. case OGT:
  973. pop += rev;
  974. if(et == TFLOAT) {
  975. a = AFCOMF;
  976. if(pop) {
  977. a = AFCOMFP;
  978. if(pop > 1)
  979. a = AGOK;
  980. }
  981. } else
  982. if(et == TDOUBLE) {
  983. a = AFCOMF;
  984. if(pop) {
  985. a = AFCOMDP;
  986. if(pop > 1)
  987. a = AFCOMDPP;
  988. }
  989. }
  990. gins(a, f, t);
  991. regalloc(&nod, &regnode, Z);
  992. if(nod.reg != D_AX) {
  993. regfree(&nod);
  994. nod.reg = D_AX;
  995. gins(APUSHL, &nod, Z);
  996. gins(AWAIT, Z, Z);
  997. gins(AFSTSW, Z, &nod);
  998. gins(ASAHF, Z, Z);
  999. gins(APOPL, Z, &nod);
  1000. } else {
  1001. gins(AWAIT, Z, Z);
  1002. gins(AFSTSW, Z, &nod);
  1003. gins(ASAHF, Z, Z);
  1004. regfree(&nod);
  1005. }
  1006. switch(o) {
  1007. case OEQ: a = AJEQ; break;
  1008. case ONE: a = AJNE; break;
  1009. case OLT: a = AJCS; break;
  1010. case OLE: a = AJLS; break;
  1011. case OGE: a = AJCC; break;
  1012. case OGT: a = AJHI; break;
  1013. }
  1014. gins(a, Z, Z);
  1015. return;
  1016. }
  1017. if(a == AGOK)
  1018. diag(Z, "bad in gopcode %O", o);
  1019. gins(a, f, t);
  1020. }
  1021. void
  1022. gopcode(int o, Type *ty, Node *f, Node *t)
  1023. {
  1024. int a, et;
  1025. et = TLONG;
  1026. if(ty != T)
  1027. et = ty->etype;
  1028. if(typefd[et] && o != OADDR && o != OFUNC) {
  1029. diag(f, "gop: float %O", o);
  1030. return;
  1031. }
  1032. if(debug['M']) {
  1033. if(f != Z && f->type != T)
  1034. print("gop: %O %O[%s],", o, f->op, tnames[et]);
  1035. else
  1036. print("gop: %O Z,", o);
  1037. if(t != Z && t->type != T)
  1038. print("%O[%s]\n", t->op, tnames[t->type->etype]);
  1039. else
  1040. print("Z\n");
  1041. }
  1042. a = AGOK;
  1043. switch(o) {
  1044. case OCOM:
  1045. a = ANOTL;
  1046. if(et == TCHAR || et == TUCHAR)
  1047. a = ANOTB;
  1048. if(et == TSHORT || et == TUSHORT)
  1049. a = ANOTW;
  1050. break;
  1051. case ONEG:
  1052. a = ANEGL;
  1053. if(et == TCHAR || et == TUCHAR)
  1054. a = ANEGB;
  1055. if(et == TSHORT || et == TUSHORT)
  1056. a = ANEGW;
  1057. break;
  1058. case OADDR:
  1059. a = ALEAL;
  1060. break;
  1061. case OASADD:
  1062. case OADD:
  1063. a = AADDL;
  1064. if(et == TCHAR || et == TUCHAR)
  1065. a = AADDB;
  1066. if(et == TSHORT || et == TUSHORT)
  1067. a = AADDW;
  1068. break;
  1069. case OASSUB:
  1070. case OSUB:
  1071. a = ASUBL;
  1072. if(et == TCHAR || et == TUCHAR)
  1073. a = ASUBB;
  1074. if(et == TSHORT || et == TUSHORT)
  1075. a = ASUBW;
  1076. break;
  1077. case OASOR:
  1078. case OOR:
  1079. a = AORL;
  1080. if(et == TCHAR || et == TUCHAR)
  1081. a = AORB;
  1082. if(et == TSHORT || et == TUSHORT)
  1083. a = AORW;
  1084. break;
  1085. case OASAND:
  1086. case OAND:
  1087. a = AANDL;
  1088. if(et == TCHAR || et == TUCHAR)
  1089. a = AANDB;
  1090. if(et == TSHORT || et == TUSHORT)
  1091. a = AANDW;
  1092. break;
  1093. case OASXOR:
  1094. case OXOR:
  1095. a = AXORL;
  1096. if(et == TCHAR || et == TUCHAR)
  1097. a = AXORB;
  1098. if(et == TSHORT || et == TUSHORT)
  1099. a = AXORW;
  1100. break;
  1101. case OASLSHR:
  1102. case OLSHR:
  1103. a = ASHRL;
  1104. if(et == TCHAR || et == TUCHAR)
  1105. a = ASHRB;
  1106. if(et == TSHORT || et == TUSHORT)
  1107. a = ASHRW;
  1108. break;
  1109. case OASASHR:
  1110. case OASHR:
  1111. a = ASARL;
  1112. if(et == TCHAR || et == TUCHAR)
  1113. a = ASARB;
  1114. if(et == TSHORT || et == TUSHORT)
  1115. a = ASARW;
  1116. break;
  1117. case OASASHL:
  1118. case OASHL:
  1119. a = ASALL;
  1120. if(et == TCHAR || et == TUCHAR)
  1121. a = ASALB;
  1122. if(et == TSHORT || et == TUSHORT)
  1123. a = ASALW;
  1124. break;
  1125. case OFUNC:
  1126. a = ACALL;
  1127. break;
  1128. case OASMUL:
  1129. case OMUL:
  1130. if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
  1131. t = Z;
  1132. a = AIMULL;
  1133. break;
  1134. case OASMOD:
  1135. case OMOD:
  1136. case OASDIV:
  1137. case ODIV:
  1138. a = AIDIVL;
  1139. break;
  1140. case OASLMUL:
  1141. case OLMUL:
  1142. a = AMULL;
  1143. break;
  1144. case OASLMOD:
  1145. case OLMOD:
  1146. case OASLDIV:
  1147. case OLDIV:
  1148. a = ADIVL;
  1149. break;
  1150. case OEQ:
  1151. case ONE:
  1152. case OLT:
  1153. case OLE:
  1154. case OGE:
  1155. case OGT:
  1156. case OLO:
  1157. case OLS:
  1158. case OHS:
  1159. case OHI:
  1160. a = ACMPL;
  1161. if(et == TCHAR || et == TUCHAR)
  1162. a = ACMPB;
  1163. if(et == TSHORT || et == TUSHORT)
  1164. a = ACMPW;
  1165. gins(a, f, t);
  1166. switch(o) {
  1167. case OEQ: a = AJEQ; break;
  1168. case ONE: a = AJNE; break;
  1169. case OLT: a = AJLT; break;
  1170. case OLE: a = AJLE; break;
  1171. case OGE: a = AJGE; break;
  1172. case OGT: a = AJGT; break;
  1173. case OLO: a = AJCS; break;
  1174. case OLS: a = AJLS; break;
  1175. case OHS: a = AJCC; break;
  1176. case OHI: a = AJHI; break;
  1177. }
  1178. gins(a, Z, Z);
  1179. return;
  1180. }
  1181. if(a == AGOK)
  1182. diag(Z, "bad in gopcode %O", o);
  1183. gins(a, f, t);
  1184. }
  1185. int
  1186. samaddr(Node *f, Node *t)
  1187. {
  1188. if(f->op != t->op)
  1189. return 0;
  1190. switch(f->op) {
  1191. case OREGISTER:
  1192. if(f->reg != t->reg)
  1193. break;
  1194. return 1;
  1195. }
  1196. return 0;
  1197. }
  1198. void
  1199. gbranch(int o)
  1200. {
  1201. int a;
  1202. a = AGOK;
  1203. switch(o) {
  1204. case ORETURN:
  1205. a = ARET;
  1206. break;
  1207. case OGOTO:
  1208. a = AJMP;
  1209. break;
  1210. }
  1211. nextpc();
  1212. if(a == AGOK) {
  1213. diag(Z, "bad in gbranch %O", o);
  1214. nextpc();
  1215. }
  1216. p->as = a;
  1217. }
  1218. void
  1219. patch(Prog *op, long pc)
  1220. {
  1221. op->to.offset = pc;
  1222. op->to.type = D_BRANCH;
  1223. }
  1224. void
  1225. gpseudo(int a, Sym *s, Node *n)
  1226. {
  1227. nextpc();
  1228. p->as = a;
  1229. p->from.type = D_EXTERN;
  1230. p->from.sym = s;
  1231. p->from.scale = (profileflg ? 0 : NOPROF);
  1232. if(s->class == CSTATIC)
  1233. p->from.type = D_STATIC;
  1234. naddr(n, &p->to);
  1235. if(a == ADATA || a == AGLOBL)
  1236. pc--;
  1237. }
  1238. int
  1239. sconst(Node *n)
  1240. {
  1241. long v;
  1242. if(n->op == OCONST && !typefd[n->type->etype]) {
  1243. v = n->vconst;
  1244. if(v >= -32766L && v < 32766L)
  1245. return 1;
  1246. }
  1247. return 0;
  1248. }
  1249. long
  1250. exreg(Type *t)
  1251. {
  1252. int o;
  1253. if(typechlp[t->etype]){
  1254. if(exregoffset >= 32)
  1255. return 0;
  1256. o = exregoffset;
  1257. exregoffset += 4;
  1258. return o+1; /* +1 to avoid 0 == failure; naddr case OEXREG will -1. */
  1259. }
  1260. return 0;
  1261. }
  1262. schar ewidth[NTYPE] =
  1263. {
  1264. -1, /*[TXXX]*/
  1265. SZ_CHAR, /*[TCHAR]*/
  1266. SZ_CHAR, /*[TUCHAR]*/
  1267. SZ_SHORT, /*[TSHORT]*/
  1268. SZ_SHORT, /*[TUSHORT]*/
  1269. SZ_INT, /*[TINT]*/
  1270. SZ_INT, /*[TUINT]*/
  1271. SZ_LONG, /*[TLONG]*/
  1272. SZ_LONG, /*[TULONG]*/
  1273. SZ_VLONG, /*[TVLONG]*/
  1274. SZ_VLONG, /*[TUVLONG]*/
  1275. SZ_FLOAT, /*[TFLOAT]*/
  1276. SZ_DOUBLE, /*[TDOUBLE]*/
  1277. SZ_IND, /*[TIND]*/
  1278. 0, /*[TFUNC]*/
  1279. -1, /*[TARRAY]*/
  1280. 0, /*[TVOID]*/
  1281. -1, /*[TSTRUCT]*/
  1282. -1, /*[TUNION]*/
  1283. SZ_INT, /*[TENUM]*/
  1284. };
  1285. long ncast[NTYPE] =
  1286. {
  1287. 0, /*[TXXX]*/
  1288. BCHAR|BUCHAR, /*[TCHAR]*/
  1289. BCHAR|BUCHAR, /*[TUCHAR]*/
  1290. BSHORT|BUSHORT, /*[TSHORT]*/
  1291. BSHORT|BUSHORT, /*[TUSHORT]*/
  1292. BINT|BUINT|BLONG|BULONG|BIND, /*[TINT]*/
  1293. BINT|BUINT|BLONG|BULONG|BIND, /*[TUINT]*/
  1294. BINT|BUINT|BLONG|BULONG|BIND, /*[TLONG]*/
  1295. BINT|BUINT|BLONG|BULONG|BIND, /*[TULONG]*/
  1296. BVLONG|BUVLONG, /*[TVLONG]*/
  1297. BVLONG|BUVLONG, /*[TUVLONG]*/
  1298. BFLOAT, /*[TFLOAT]*/
  1299. BDOUBLE, /*[TDOUBLE]*/
  1300. BLONG|BULONG|BIND, /*[TIND]*/
  1301. 0, /*[TFUNC]*/
  1302. 0, /*[TARRAY]*/
  1303. 0, /*[TVOID]*/
  1304. BSTRUCT, /*[TSTRUCT]*/
  1305. BUNION, /*[TUNION]*/
  1306. 0, /*[TENUM]*/
  1307. };