GEXPR68.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:121k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. #include        <stdio.h>
  23. #include        "expr.h"
  24. #include        "c.h"
  25. #include        "gen68.h"
  26. #include  "diag.h"
  27. /*
  28.  *      this module contains all of the code generation routines
  29.  *      for evaluating expressions and conditions.
  30.  */
  31. extern int stdinttype,stdunstype,stdintsize, stdldoublesize,stdaddrsize;
  32. extern int cf_freeaddress, cf_freedata;
  33. extern int linkreg,basereg;
  34. extern long stackdepth,framedepth;
  35. extern int prm_largedata, prm_68020,prm_phiform,prm_linkreg;
  36. extern int prm_smallcode, prm_rel, prm_smalldata;
  37. extern AMODE     push[], pop[];
  38. extern int prm_68020;
  39. extern SYM *currentfunc;
  40. extern long lc_maxauto;
  41. extern long nextlabel;
  42. extern char regstack[], rsold[], rsodepth,rsdepth;
  43. long bittab[32] = { 1,0x3,0x7,0xf,0x1f,0x3f,0x7f,0xff,
  44. 0x1ff,0x3ff,0x7ff,0xfff,0x1fff,0x3fff,0x7fff,0xffff,
  45. 0x1ffffL,0x3ffffL,0x7ffffL,0xfffffL,0x1fffffL,0x3fffffL,0x7fffffL,0xffffffL,
  46. 0x1ffffffL,0x3ffffffL,0x7ffffffL,0xfffffffL,0x1fffffffL,0x3fffffffL,0x7fffffffL,0xffffffffL
  47. };
  48. int chksize(int lsize, int rsize)
  49. {
  50. int l,r;
  51. l = lsize;
  52. r = rsize;
  53. if (l < 0) l = - l;
  54. if (r < 0) r = - r;
  55. return(l > r);
  56. }
  57. AMODE    *make_label(int lab)
  58. /*
  59.  *      construct a reference node for an internal label number.
  60.  */
  61. {       ENODE    *lnode;
  62.         AMODE    *ap;
  63.         lnode = xalloc(sizeof(ENODE));
  64.         lnode->nodetype = en_labcon;
  65.         lnode->v.i = lab;
  66.         ap = xalloc(sizeof(AMODE));
  67.         ap->mode = am_direct;
  68.         ap->offset = lnode;
  69.         return ap;
  70. }
  71. AMODE    *makebf(ENODE *node, AMODE *ap1, int size)
  72. /*
  73.  *      construct a bit field reference for 68020 bit field instructions
  74.  */
  75. {
  76.         AMODE    *ap;
  77. if (node->startbit == -1)
  78. DIAG("Illegal bit field");
  79.         ap = xalloc(sizeof(AMODE));
  80.         ap->mode = am_bf;
  81. ap->preg = node->startbit;
  82. ap->sreg = node->bits;
  83. switch (size) {
  84. case 1:
  85. case -1:
  86.   ap->preg =8-node->startbit-node->bits;
  87. break;
  88. case 2:
  89. case -2:
  90.   ap->preg =16-node->startbit-node->bits;
  91. break;
  92. case 4:
  93. case -4:
  94.   ap->preg =32-node->startbit-node->bits;
  95. break;
  96. }
  97.         return ap;
  98. }
  99. AMODE    *make_immed(long i)
  100. /*
  101.  *      make a node to reference an immediate value i.
  102.  */
  103. {       AMODE    *ap;
  104.         ENODE    *ep;
  105.         ep = xalloc(sizeof(ENODE));
  106.         ep->nodetype = en_icon;
  107.         ep->v.i = i;
  108.         ap = xalloc(sizeof(AMODE));
  109.         ap->mode = am_immed;
  110.         ap->offset = ep;
  111.         return ap;
  112. }
  113. AMODE    *make_offset(ENODE *node)
  114. /*
  115.  *      make a direct reference to a node.
  116.  */
  117. {       AMODE    *ap;
  118.         ap = xalloc(sizeof(AMODE));
  119.         ap->mode = am_direct;
  120.         ap->offset = node;
  121.         return ap;
  122. }
  123.         
  124. void tofloat(AMODE *ap,int size)
  125. {
  126. AMODE *ap2;
  127. freeop(ap);
  128. ap2 = temp_float();
  129.                 gen_codef(op_fmove,size,ap,ap2);
  130.                 ap->mode = am_freg;
  131.                 ap->preg = ap2->preg;
  132.                 ap->tempflag = 1;
  133. }
  134. void make_legal(AMODE *ap,int flags,int size)
  135. /*
  136.  *      make_legal will coerce the addressing mode in ap1 into a
  137.  *      mode that is satisfactory for the flag word.
  138.  */
  139. {       AMODE    *ap2;
  140.         if( ((flags & F_VOL) == 0) || ap->tempflag )
  141.                 {
  142.                 switch( ap->mode )
  143.                         {
  144. case am_freg:
  145. if (flags & F_FREG)
  146. return;
  147. break;
  148.                         case am_immed:
  149.                                 if( flags & F_IMMED )
  150.                                         return;         /* mode ok */
  151.                                 break;
  152.                         case am_areg:
  153.                                 if( flags & F_AREG )
  154.                                         return;
  155.                                 break;
  156.                         case am_dreg:
  157.                                 if( flags & F_DREG )
  158.                                         return;
  159.                                 break;
  160. case am_indx:
  161. case am_ind:
  162.                         case am_baseindxdata: 
  163.                         case am_baseindxaddr:
  164. case am_adirect:
  165. case am_ainc: case am_adec:
  166. if (flags & F_INDX)
  167. return;
  168. case am_direct:
  169.                         case am_pcindx:
  170.                                 if( flags & F_INDX )
  171.                                         return;
  172.                                 break;
  173.                         }
  174.                 }
  175. if (size > 4) {
  176. tofloat(ap,size);
  177. return;
  178.                 }
  179.         if( flags & F_DREG )
  180.                 {
  181. if (ap->mode == am_dreg && ap->tempflag)
  182. return;
  183.                 freeop(ap);             /* maybe we can use it... */
  184.                 ap2 = temp_data();      /* allocate to dreg */
  185.                 gen_code(op_move,size,ap,ap2);
  186.                 ap->mode = am_dreg;
  187.                 ap->preg = ap2->preg;
  188.                 ap->tempflag = 1;
  189.                 return;
  190.                 }
  191.         if( size == -1 )
  192.                 {
  193.                 freeop(ap);
  194.                 ap2 = temp_data();
  195.                 gen_code(op_move,1,ap,ap2);
  196.                 gen_code(op_ext,2,ap2,0);
  197.                 ap->mode = ap2->mode;
  198.                 ap->preg = ap2->preg;
  199.                 size = -2;
  200.                 }
  201.         if( size == 1 )
  202.                 {
  203.                 freeop(ap);
  204.                 ap2 = temp_data();
  205.                 gen_code(op_move,1,ap,ap2);
  206.                 gen_code(op_and,2,make_immed(0xff),ap2);
  207.                 ap->mode = ap2->mode;
  208.                 ap->preg = ap2->preg;
  209.                 size = 2;
  210.                 }
  211.          freeop(ap);
  212.          ap2 = temp_addr();
  213.          gen_code(op_move,size,ap,ap2);
  214.          ap->mode = am_areg;
  215.          ap->preg = ap2->preg;
  216.          ap->tempflag = 1;
  217. }
  218. void doshift(int op, AMODE *ap2, AMODE *ap1, int size)
  219. {
  220. if (ap2->mode == am_immed) {
  221. int temp = ap2->offset->v.i;
  222. while (temp >8) {
  223. temp = temp-8;
  224.          gen_code(op,size,make_immed(8),ap1);
  225. }
  226. if (temp != 0) {
  227. ap2->offset->v.i = temp;
  228.          gen_code(op,size,ap2,ap1);
  229. }
  230. }
  231. else
  232.          gen_code(op,size,ap2,ap1);
  233. }
  234. void bit_legal(AMODE *ap,ENODE *node, int size)
  235. {
  236. if (node->bits != -1) {
  237. if (prm_68020) {
  238. AMODE *ap1;
  239. if (ap->mode != am_dreg || !ap->tempflag) {
  240. ap1 = temp_data();
  241. ap1->tempflag = 1;
  242. }
  243. else
  244. ap1 = copy_addr(ap);
  245. gen_code3(op_bfextu,0,ap,makebf(node,ap1,size),ap1);
  246. ap->mode = ap1->mode;
  247. ap->preg = ap1->preg;
  248. ap->tempflag = ap1->tempflag;
  249. }
  250. else {
  251. make_legal(ap,F_DREG | F_VOL,size);
  252. if (node->startbit)
  253. doshift(op_asr,make_immed(node->startbit),ap,size);
  254. gen_code(op_asr,size,make_immed(node->startbit),ap);
  255. gen_code(op_andi,4,make_immed(bittab[node->bits-1]),ap);
  256. }
  257. }
  258. }
  259. AMODE *get_bitval(AMODE *ap,ENODE *node, int size)
  260. {
  261. AMODE *ap1 = temp_data();
  262. ap1->tempflag = TRUE;
  263. if (prm_68020) {
  264. gen_code3(op_bfextu,0,ap,makebf(node,ap,size),ap1);
  265. return ap1;
  266. }
  267. else {
  268. gen_code(op_move,size,ap,ap1);
  269. if (node->startbit)
  270. doshift(op_asr,make_immed(node->startbit),ap1,size);
  271. gen_code(op_andi,4,make_immed(bittab[node->bits-1]),ap1);
  272. return ap1;
  273. }
  274. }
  275. void bit_move(AMODE *ap1, AMODE *ap2, ENODE *node, int flags, int sizein, int sizeout)
  276. {
  277. if (prm_68020) {
  278. make_legal(ap1,F_DREG,sizein);
  279. gen_code3(op_bfins,0,ap1,ap2,makebf(node,ap2,sizeout));
  280. }
  281. else {
  282. gen_code(op_andi,sizeout,make_immed(~(bittab[node->bits-1]<<node->startbit)), ap2);
  283. if (ap1->mode == am_immed) {
  284. ap1->offset->v.i &= bittab[node->bits-1];
  285. if (ap1->offset->v.i) {
  286. ap1->offset->v.i <<= node->startbit;
  287. gen_code(op_ori,sizeout,ap1,ap2);
  288. if (!(flags & F_NOVALUE)) {
  289. make_legal(ap2,flags,sizeout);
  290. ap1->offset->v.i >>= node->startbit;
  291. gen_code(op_move,sizeout,ap1,ap2);
  292. }
  293. }
  294. }
  295. else {
  296. make_legal(ap1,F_DREG | F_VOL,sizein);
  297. gen_code(op_andi,sizein,make_immed(bittab[node->bits-1]), ap1);
  298. if (node->startbit)
  299. doshift(op_asl,make_immed(node->startbit),ap1,sizein);
  300. gen_code(op_or,sizeout,ap2,ap1);
  301. if (!(flags & F_NOVALUE)) {
  302. if (node->startbit)
  303. doshift(op_asr,make_immed(node->startbit),ap1,sizein);
  304. }
  305. }
  306. }
  307. }
  308. void do_extend(AMODE *ap,int isize,int osize,int flags)
  309. /*
  310.  *      if isize is not equal to osize then the operand ap will be
  311.  *      loaded into a register (if not already) and if osize is
  312.  *      greater than isize it will be extended to match.
  313.  */
  314. { AMODE *ap2;
  315.   if (osize == 0 || isize == 0)
  316. return;
  317.        if( isize == osize || isize == -osize)
  318.                 return;
  319. if (chksize(osize,isize) && osize <=4)
  320. if (isize ^ osize < 0)
  321. osize = -osize;
  322.         if( ap->mode != am_areg && ap->mode != am_dreg && isize <= 4) {
  323. if (flags&F_DREG) {
  324. freeop(ap);
  325. gen_code(op_move,isize,ap,ap2=temp_data());
  326. ap->mode = am_dreg;
  327. ap->preg = ap2->preg;
  328. }
  329. else if (isize ==1 || isize == -1) {
  330. freeop(ap);
  331. gen_code(op_move,isize,ap,ap2=temp_data());
  332. ap->mode = am_dreg;
  333. ap->preg = ap2->preg;
  334. freeop(ap);
  335. gen_code(op_ext,2,ap,0);
  336. gen_code(op_move,2,ap,ap2=temp_addr());
  337. ap->mode = am_areg;
  338. ap->preg = ap2->preg;
  339. }
  340. else {
  341. freeop(ap);
  342. gen_code(op_move,isize,ap,ap2=temp_addr());
  343. ap = ap2;
  344. }
  345. }
  346.         if( ap->mode == am_areg )
  347.                 return;         /* extend is automagic */
  348. switch(isize)
  349. {
  350.                 case -1:
  351. case 1:
  352. if (osize < 0)
  353. if (osize <= -4 && prm_68020)
  354. gen_code(op_extb,4,ap,0);
  355. else
  356.                          gen_code(op_ext,2,ap,0);
  357. else {
  358. int t = osize;
  359. if (osize > 4) t = 4;
  360. gen_code(op_andi,t,make_immed(0xff),ap);
  361. }
  362.                 case -2:
  363. case 2:
  364. if (osize == 1 || osize == -1)
  365. break;
  366.                          if( osize <-2 && !(prm_68020 && (isize == -1 || isize == 1))) {
  367.                            gen_code(op_ext,4,ap,0);
  368. }
  369. else
  370. if (isize == 2 || isize == -2) {
  371. gen_code(op_andi,4,make_immed(0xffff),ap);
  372. }
  373. case 4:
  374. case -4:
  375. if  (osize <=4)
  376. break;
  377. isize = -4;
  378. case 6:
  379. case 8: 
  380. if (osize > 4) {
  381. if (ap->mode != am_freg)
  382. tofloat(ap,isize);
  383. }
  384. else {
  385. freeop(ap);
  386. ap2 = temp_data();
  387. gen_codef(op_fmove,osize,ap,ap2);
  388. ap->mode = am_dreg;
  389. ap->preg = ap2->preg;
  390. }
  391. break;
  392. }
  393. }
  394. int     isshort(ENODE *node)
  395. /*
  396.  *      return true if the node passed can be generated as a short
  397.  *      offset.
  398.  */
  399. {       return (isintconst(node->nodetype) || node->nodetype == en_absacon)&&
  400.                 (node->v.i >= -32768L && node->v.i <= 32767L);
  401. }
  402. int     isbyte(ENODE *node)
  403. /*
  404.  *      return true if the node passed can be evaluated as a byte
  405.  *      offset.
  406.  */
  407. {       return isintconst(node->nodetype) &&
  408.                 (-128 <= node->v.i && node->v.i <= 127);
  409. }
  410. int isamshort(AMODE *ap)
  411. {
  412. long v;
  413. if (ap->offset->nodetype != en_icon)
  414. return TRUE;
  415. v = ap->offset->v.i;
  416. return (v >=-32768L && v < 32767);
  417. }
  418. int isamshort2(AMODE *ap, AMODE *ap2)
  419. {
  420. long v;
  421. if (ap->offset->nodetype != en_icon || ap2->offset->nodetype != en_icon)
  422. return TRUE;
  423. v = ap->offset->v.i + ap2->offset->v.i;
  424. return (v >=-32768L && v < 32767);
  425. }
  426. int isambyte(AMODE *ap)
  427. {
  428. long v;
  429. if (ap->offset->nodetype != en_icon)
  430. return FALSE;
  431. v = ap->offset->v.i;
  432. return (v >=-128 && v < 128);
  433. }
  434. int isambyte2(AMODE *ap, AMODE *ap2)
  435. {
  436. long v;
  437. if (ap->offset->nodetype != en_icon || ap2->offset->nodetype != en_icon)
  438. return FALSE;
  439. v = ap->offset->v.i + ap2->offset->v.i;
  440. return (v >=-128 && v < 128);
  441. }                            
  442. AMODE    *gen_index(int siz1,ENODE *node)
  443. /*
  444.  *      generate code to evaluate an index node (^+) and return
  445.  *      the addressing mode of the result. This routine takes no
  446.  *      flags since it always returns either am_ind or am_indx.
  447.  */
  448. {       AMODE    *ap1,*ap2, *ap3, *ap;
  449. ENODE node2;
  450. int scale;
  451. switch (node->v.p[0]->nodetype) {
  452. case en_icon:
  453. ap1 = gen_expr(node->v.p[0],F_IMMED,4);
  454. break;
  455. case en_lsh:
  456. if (prm_68020 && (scale = node->v.p[0]->v.p[1]->v.i) < 4 && scale) {
  457. ap1 = gen_expr(node->v.p[0]->v.p[0],F_IMMED | F_DREG | F_AREG,4);
  458. if (ap1->mode == am_immed) {
  459. while (--scale)
  460. ap1->offset->v.i <<=1;
  461. }
  462. else {
  463. if (ap1->mode == am_dreg)
  464. ap1->mode = am_baseindxdata;
  465. else
  466. ap1->mode = am_baseindxaddr;
  467. ap1->sreg = ap1->preg;
  468. ap1->preg = -1;
  469. ap1->scale = scale;
  470. ap1->offset = makenode(en_icon,0,0);
  471. }
  472. break;
  473. }
  474. default:
  475. mark();
  476. ap1 = gen_deref(node,F_INDX | F_DREG | F_AREG,4,FALSE);
  477. switch (ap1->mode) {
  478. case am_ainc:
  479. case am_adec:
  480. ap2 = temp_addr();
  481. gen_lea(siz1,ap1,ap2);
  482. freeop(ap1);
  483. ap1 = ap2;
  484. default:
  485. rsold[rsodepth-1] = rsdepth;
  486. break;
  487. case am_baseindxdata:
  488. case am_baseindxaddr:
  489. if (ap1->sreg >=0 && ap1->preg >= 0) {
  490. int t = rsold[rsodepth-1];
  491. freeop(ap1);
  492. ap3 = temp_addr();
  493. gen_lea(siz1,ap1,ap3);
  494. ap3->mode = am_ind;
  495. if (t <rsdepth-1 && ap3->preg + 8 == regstack[t+1])
  496. t+=2;
  497. if (t <rsdepth && ap3->preg + 8 == regstack[t])
  498. t+=1;
  499. ap1 = ap3;
  500. }
  501. }
  502. release();
  503. break;
  504. }
  505. switch (node->v.p[1]->nodetype) {
  506. case en_icon:
  507. ap2 = gen_expr(node->v.p[1],F_IMMED,4);
  508. break;
  509. case en_lsh:
  510. if (prm_68020 && (scale = node->v.p[1]->v.p[1]->v.i) < 4 && scale) {
  511. if (node->v.p[1]->v.p[0]->nodetype == en_tempref)
  512. ap2 = gen_expr(node->v.p[1]->v.p[0],F_IMMED | F_DREG | F_AREG,4);
  513. if (ap2->mode == am_immed) {
  514. while (--scale)
  515. ap2->offset->v.i <<=1;
  516. }
  517. else {
  518. if (ap2->mode == am_dreg)
  519. ap2->mode = am_baseindxdata;
  520. else
  521. ap2->mode = am_baseindxaddr;
  522. ap2->sreg = ap1->preg;
  523. ap2->preg = -1;
  524. ap2->scale = scale;
  525. ap2->offset = makenode(en_icon,0,0);
  526. }
  527. break;
  528. }
  529. default:      {
  530. int flag = ap1->mode == am_areg || ap1->mode == am_ind ||
  531. ap1->mode == am_indx || ap1->mode == am_baseindxaddr;
  532. node2.v.p[0] = node->v.p[1];
  533. node2.nodetype = node->nodetype;
  534. mark();
  535. ap2 = gen_deref(&node2,F_INDX | F_DREG | F_AREG,4,flag);
  536. switch (ap1->mode) {
  537. case am_ainc:
  538. case am_adec:
  539. ap3 = temp_addr();
  540. gen_lea(siz1,ap2,ap3);
  541. freeop(ap2);
  542. ap2 = ap3;
  543. default:
  544. rsold[rsodepth-1] = rsdepth;
  545. break;
  546. case am_baseindxdata:
  547. case am_baseindxaddr:
  548. if (ap2->sreg >=0 && ap2->preg >= 0) {
  549. int t = rsold[rsodepth-1];
  550. freeop(ap2);
  551. ap3 = temp_addr();
  552. gen_lea(siz1,ap2,ap3);
  553. ap3->mode = am_ind;
  554. if (t <rsdepth-1 && ap3->preg + 8 == regstack[t+1])
  555. t+=2;
  556. if (t <rsdepth && ap3->preg + 8 == regstack[t])
  557. t+=1;
  558. ap2 = ap3;
  559. }
  560. }
  561. release();
  562. }
  563. break;
  564. }
  565. tryagain:
  566. switch(ap1->mode) {
  567. case am_areg:
  568. switch (ap2->mode) {
  569. case am_areg:
  570. ap1->sreg = ap2->preg;
  571. ap1->mode = am_baseindxaddr;
  572. ap1->offset = makenode(en_icon,0,0);
  573. ap1->scale = 0;
  574. return ap1;
  575. case am_dreg:
  576. ap1->sreg = ap2->preg;
  577. ap1->mode = am_baseindxdata;
  578. ap1->offset = makenode(en_icon,0,0);
  579. ap1->scale = 0;
  580. return ap1;
  581. case am_adirect:
  582. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  583. ap1->mode = am_indx;
  584. ap1->offset = ap2->offset;
  585. return ap1;
  586. }
  587. ap = temp_addr();
  588. gen_lea(0,ap2,ap);
  589. ap1->mode = am_baseindxaddr;
  590. ap1->offset = makenode(en_icon,0,0);
  591. ap1->scale = 0;
  592. ap1->sreg = ap->preg;
  593. return ap1;
  594. case am_immed:
  595. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  596. ap1->mode = am_indx;
  597. ap1->offset = ap2->offset;
  598. return ap1;
  599. }
  600. ap = temp_data();
  601. gen_code(op_move,4,ap2,ap);
  602. ap1->mode = am_baseindxdata;
  603. ap1->offset = makenode(en_icon,0,0);
  604. ap1->scale = 0;
  605. ap1->sreg = ap->preg;
  606. return ap1;
  607. case am_indx:
  608. if (prm_68020 || isambyte(ap2)) {
  609. ap1->mode = am_baseindxaddr;
  610. ap1->offset = ap2->offset;
  611. ap1->scale = 0;
  612. ap1->sreg = ap2->preg;
  613. return ap1;
  614. }
  615. freeop(ap2);
  616. ap = temp_addr();
  617. gen_lea(0,ap2,ap);
  618. ap->mode = am_baseindxaddr;
  619. ap->sreg = ap1->preg;
  620. ap->scale = 0;
  621. ap->offset = makenode(en_icon,0,0);
  622. return ap;
  623. case am_ind:
  624. ap1->mode = am_baseindxaddr;
  625. ap1->offset = makenode(en_icon,0,0);
  626. ap1->scale = 0;
  627. ap1->sreg = ap2->preg;
  628. return ap1;
  629. case am_baseindxaddr:
  630. case am_baseindxdata:
  631. if (ap2->preg == -1) {
  632. ap2->preg = ap1->preg;
  633. return ap2;
  634. }
  635. freeop(ap2);
  636. ap = temp_addr();
  637. gen_lea(0,ap2,ap);
  638. ap1->mode = am_baseindxaddr;
  639. ap1->scale = 0;
  640. ap1->offset = makenode(en_icon,0,0);
  641. ap1->sreg = ap->preg;
  642. return ap1;
  643. }
  644. break;
  645. case am_dreg:
  646. switch (ap2->mode) {
  647. case am_areg:
  648. ap2->sreg = ap1->preg;
  649. ap2->mode = am_baseindxdata;
  650. ap2->offset = makenode(en_icon,0,0);
  651. ap2->scale = 0;
  652. return ap2;
  653. case am_dreg:
  654. freeop(ap2);
  655. ap = temp_addr();
  656. gen_lea(0,ap1,ap);
  657. ap->sreg = ap1->preg;
  658. ap->mode = am_baseindxdata;
  659. ap->offset = makenode(en_icon,0,0);
  660. ap->scale = 0;
  661. return ap;
  662. case am_adirect:
  663. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  664. freeop(ap1);
  665. ap = temp_addr();
  666. gen_code(op_move,4,ap1,ap);
  667. ap->mode = am_indx;
  668. ap->offset = ap2->offset;
  669. return ap;
  670. }
  671. ap = temp_addr();
  672. gen_lea(0,ap2,ap);
  673. ap->mode = am_baseindxdata;
  674. ap->offset = makenode(en_icon,0,0);
  675. ap->scale = 0;
  676. ap->sreg = ap1->preg;
  677. return ap;
  678. case am_immed:
  679. if (prm_68020 || isamshort(ap2)) {
  680. freeop(ap1);
  681. ap = temp_addr();
  682. gen_code(op_move,4,ap1,ap);
  683. ap->mode = am_indx;
  684. ap->offset = ap2->offset;
  685. return ap;
  686. }
  687. ap = temp_addr();
  688. gen_code(op_move,0,ap2,ap);
  689. ap->mode = am_baseindxdata;
  690. ap->offset = makenode(en_icon,0,0);
  691. ap->scale = 0;
  692. ap->sreg = ap1->preg;
  693. return ap;
  694. case am_indx:
  695. if (prm_68020 || isambyte(ap2)) {
  696. ap2->mode = am_baseindxdata;
  697. ap2->scale = 0;
  698. ap2->sreg = ap1->preg;
  699. return ap2;
  700. }
  701. freeop(ap2);
  702. ap = temp_addr();
  703. gen_lea(0,ap2,ap);
  704. ap->mode = am_baseindxdata;
  705. ap->sreg = ap1->preg;
  706. ap->scale = 0;
  707. ap->offset = makenode(en_icon,0,0);
  708. return ap;
  709. case am_ind:
  710. ap2->mode = am_baseindxdata;
  711. ap2->offset = makenode(en_icon,0,0);
  712. ap2->scale = 0;
  713. ap2->sreg = ap1->preg;
  714. return ap2;
  715. case am_baseindxaddr:
  716. case am_baseindxdata:
  717. if (ap2->preg == -1) {
  718. ap = temp_addr();
  719. gen_code(op_move,4,ap1,ap);
  720. ap2->preg = ap->preg;
  721. return ap2;
  722. }
  723. freeop(ap2);
  724. ap = temp_addr();
  725. gen_lea(0,ap2,ap);
  726. ap->mode = am_baseindxdata;
  727. ap->scale = 0;
  728. ap->offset = makenode(en_icon,0,0);
  729. ap->sreg = ap1->preg;
  730. return ap;
  731. }
  732. break;
  733. case am_adirect:
  734. switch (ap2->mode) {
  735. case am_areg:
  736. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  737. ap2->mode = am_indx;
  738. ap2->offset = ap1->offset;
  739. return ap2;
  740. }
  741. ap = temp_addr();
  742. gen_lea(0,ap1,ap);
  743. ap2->mode = am_baseindxaddr;
  744. ap2->offset = makenode(en_icon,0,0);
  745. ap2->scale = 0;
  746. ap2->sreg = ap->preg;
  747. return ap2;
  748. case am_dreg:
  749. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  750. freeop(ap1);
  751. ap = temp_addr();
  752. gen_code(op_move,4,ap2,ap);
  753. ap->mode = am_indx;
  754. ap->offset = ap1->offset;
  755. return ap;
  756. }
  757. ap = temp_addr();
  758. gen_lea(0,ap1,ap);
  759. ap->mode = am_baseindxdata;
  760. ap->offset = makenode(en_icon,0,0);
  761. ap->scale = 0;
  762. ap->sreg = ap2->preg;
  763. return ap;
  764. case am_adirect:
  765. ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
  766. return ap1;
  767. case am_immed:
  768. ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
  769. return ap1;
  770. case am_indx:
  771. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  772. ap2->offset = makenode(en_add,ap2->offset,ap1->offset);
  773. return ap2;
  774. }
  775. ap = temp_addr();
  776. gen_lea(0,ap1,ap);
  777. ap2->mode = am_baseindxaddr;
  778. ap2->sreg = ap->preg;
  779. ap2->scale = 0;
  780. return ap2;
  781. case am_ind:
  782. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  783. ap2->offset = ap1->offset;
  784. ap2->mode = am_indx;
  785. return ap2;
  786. }
  787. ap = temp_addr();
  788. gen_lea(0,ap1,ap);
  789. ap2->mode = am_baseindxaddr;
  790. ap2->sreg = ap->preg;
  791. ap2->scale = 0;
  792. ap2->offset = makenode(en_icon,0,0);
  793. return ap2;
  794. case am_baseindxaddr:
  795. case am_baseindxdata:
  796. if (prm_68020) {
  797. ap2->offset = makenode(en_add,ap2->offset,ap1->offset);
  798. return ap2;
  799. }
  800. if (ap2->preg == -1) {
  801. ap = temp_addr();
  802. ap2->preg = ap->preg;
  803. gen_lea(0,ap1,ap);
  804. return ap2;
  805. }
  806. ap = temp_addr();
  807. gen_lea(0,ap1,ap);
  808. ap2->mode = am_baseindxaddr;
  809. ap2->sreg = ap->preg;
  810. ap2->scale = 0;
  811. ap2->offset = makenode(en_icon,0,0);
  812. return ap2;
  813. }
  814. break;
  815. case am_immed:
  816. switch (ap2->mode) {
  817. case am_areg:
  818. if (prm_68020 || isamshort(ap1)) {
  819. ap2->mode = am_indx;
  820. ap2->offset = ap1->offset;
  821. return ap2;
  822. }
  823. ap = temp_data();
  824. gen_code(op_move,4,ap1,ap);
  825. ap2->mode = am_baseindxdata;
  826. ap2->offset = makenode(en_icon,0,0);
  827. ap2->scale = 0;
  828. ap2->sreg = ap->preg;
  829. return ap2;
  830. case am_dreg:
  831. if (prm_68020 || isamshort(ap1)) {
  832. freeop(ap2);
  833. ap = temp_addr();
  834. gen_code(op_move,4,ap2,ap);
  835. ap->mode = am_indx;
  836. ap->offset = ap1->offset;
  837. return ap;
  838. }
  839. ap = temp_addr();
  840. gen_code(op_move,0,ap1,ap);
  841. ap->mode = am_baseindxdata;
  842. ap->offset = makenode(en_icon,0,0);
  843. ap->scale = 0;
  844. ap->sreg = ap2->preg;
  845. return ap;
  846. case am_adirect:
  847. ap2->offset = makenode(en_add,ap2->offset,ap1->offset);
  848. return ap2;
  849. case am_immed:
  850. if (prm_68020 || isamshort2(ap1,ap2)) {
  851. ap1->offset->v.i += ap2->offset->v.i;
  852. return ap1;
  853. }
  854. if (isamshort(ap1)) {
  855. ap = temp_addr();
  856. gen_code(op_move,4,ap2,ap);
  857. ap->mode = am_indx;
  858. ap->offset = ap1->offset;
  859. return ap;
  860. }
  861. if (isamshort(ap2)) {
  862. ap = temp_addr();
  863. gen_code(op_move,4,ap1,ap);
  864. ap->mode = am_indx;
  865. ap->offset = ap2->offset;
  866. return ap;
  867. }
  868. ap = temp_addr();
  869. ap3 = temp_data();
  870. gen_code(op_move,4,ap1,ap);
  871. gen_code(op_move,4,ap2,ap3);
  872. ap->mode = am_baseindxdata;
  873. ap->sreg = ap3->preg;
  874. ap->scale = 0;
  875. ap->offset = makenode(en_icon,0,0);
  876. return ap;
  877. case am_indx:
  878. if (prm_68020 || isamshort2(ap1,ap2)) {
  879. if (ap2->offset->nodetype == en_icon)
  880. ap2->offset->v.i += ap1->offset->v.i;
  881. else
  882. ap2->offset = makenode(en_add,ap2->offset,ap1->offset);
  883. return ap2;
  884. }
  885. ap = temp_data();
  886. gen_code(op_move,4,ap2,ap);
  887. ap1->mode = am_baseindxdata;
  888. ap1->scale = 0;
  889. ap1->sreg = ap->preg;
  890. return ap1;
  891. case am_baseindxaddr:
  892. case am_baseindxdata:
  893. if (ap2->preg == -1 && !prm_68020) {
  894. ap = temp_addr();
  895. gen_code(op_move,4,ap1,ap);
  896. ap2->preg = ap->preg;
  897. return ap2;
  898. }
  899. if (prm_68020 || isambyte2(ap1,ap2)) {
  900. if (ap2->offset->nodetype == am_immed)
  901. ap2->offset->v.i += ap1->offset->v.i;
  902. else
  903. ap2->offset = makenode(en_add,ap2->offset,ap1->offset);
  904. return ap2;
  905. }
  906. freeop(ap2);
  907. ap = temp_addr();
  908. gen_lea(0,ap2,ap);
  909. ap->mode = am_ind;
  910. ap2 = ap;
  911. /* drop through */
  912. case am_ind:
  913. if (prm_68020 || isamshort(ap1)) {
  914. ap2->offset = ap1->offset;
  915. ap2->mode = am_indx;
  916. return ap2;
  917. }
  918. ap = temp_data();
  919. gen_code(op_move,4,ap1,ap);
  920. ap2->mode = am_baseindxdata;
  921. ap2->scale = 0;
  922. ap2->sreg = ap->preg;
  923. ap2->offset = makenode(en_icon,0,0);
  924. return ap2;
  925. }
  926. break;
  927. case am_indx:
  928. switch (ap2->mode) {
  929. case am_areg:
  930. if (prm_68020 || isambyte(ap1)) {
  931. ap2->mode = am_baseindxaddr;
  932. ap2->offset = ap1->offset;
  933. ap2->scale = 0;
  934. ap2->sreg = ap2->preg;
  935. return ap2;
  936. }
  937. freeop(ap1);
  938. ap = temp_addr();
  939. gen_lea(0,ap1,ap);
  940. ap->mode = am_baseindxaddr;
  941. ap->sreg = ap2->preg;
  942. ap->scale = 0;
  943. ap->offset = makenode(en_icon,0,0);
  944. return ap;
  945. case am_dreg:
  946. if (prm_68020 || isambyte(ap1)) {
  947. ap1->mode = am_baseindxdata;
  948. ap1->scale = 0;
  949. ap1->sreg = ap2->preg;
  950. return ap1;
  951. }
  952. freeop(ap1);
  953. ap = temp_addr();
  954. gen_lea(0,ap1,ap);
  955. ap->mode = am_baseindxdata;
  956. ap->sreg = ap2->preg;
  957. ap->scale = 0;
  958. ap->offset = makenode(en_icon,0,0);
  959. return ap;
  960. case am_adirect:
  961. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  962. ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
  963. return ap1;
  964. }
  965. ap = temp_addr();
  966. gen_lea(0,ap2,ap);
  967. ap1->mode = am_baseindxaddr;
  968. ap1->sreg = ap->preg;
  969. ap1->scale = 0;
  970. return ap1;
  971. case am_immed:
  972. if (prm_68020 || isamshort2(ap1,ap2)) {
  973. if (ap1->offset->nodetype == am_immed)
  974. ap1->offset->v.i += ap2->offset->v.i;
  975. else
  976. ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
  977. return ap1;
  978. }
  979. ap = temp_data();
  980. gen_code(op_move,4,ap2,ap);
  981. ap1->mode = am_baseindxdata;
  982. ap1->scale = 0;
  983. ap1->sreg = ap->preg;
  984. return ap1;
  985. case am_indx:
  986. if (isambyte2(ap1,ap2) || prm_68020) {
  987. if (ap1->offset->nodetype == am_immed && ap2->offset->nodetype)
  988. ap1->offset->v.i += ap2->offset->v.i;
  989. else
  990. ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
  991. ap1->mode = am_baseindxaddr;
  992. ap1->sreg = ap2->preg;
  993. ap1->scale = 0;
  994. ap1->offset = makenode(en_icon,0,0);
  995. return ap1;
  996. }
  997. if (isambyte(ap1)) {
  998. freeop(ap2);
  999. ap = temp_addr();
  1000.     gen_lea(0,ap2,ap);
  1001. ap1->mode = am_baseindxaddr;
  1002. ap1->sreg = ap->preg;
  1003. ap1->scale = 0;
  1004. ap1->offset = makenode(en_icon,0,0);
  1005. return ap1;
  1006. }
  1007. if (isambyte(ap2)) {
  1008. freeop(ap1);
  1009. ap = temp_addr();
  1010.     gen_lea(0,ap1,ap);
  1011. ap2->mode = am_baseindxaddr;
  1012. ap2->sreg = ap->preg;
  1013. ap2->scale = 0;
  1014. ap2->offset = makenode(en_icon,0,0);
  1015. return ap2;
  1016. }
  1017. freeop(ap1);
  1018. ap = temp_addr();
  1019. gen_lea(0,ap1,ap);
  1020. freeop(ap2);
  1021. ap1 = temp_addr();
  1022. gen_lea(0,ap2,ap1);
  1023. ap1->sreg = ap->preg;
  1024. ap1->mode = am_baseindxaddr;
  1025. ap1->scale = 0;
  1026. ap1->offset = makenode(en_icon,0,0);
  1027. return ap1;
  1028. case am_ind:
  1029. if (isambyte(ap1) || prm_68020) {
  1030. ap1->mode = am_baseindxaddr;
  1031. ap1->sreg = ap2->preg;
  1032. ap1->scale = 0;
  1033. return ap1;
  1034. }
  1035. freeop(ap1);
  1036. ap = temp_addr();
  1037. gen_lea(0,ap1,ap);
  1038. ap2->sreg = ap->preg;
  1039. ap2->mode = am_baseindxaddr;
  1040. ap2->scale = 0;
  1041. ap2->offset = makenode(en_icon,0,0);
  1042. return ap2;
  1043. case am_baseindxaddr:
  1044. case am_baseindxdata:
  1045. if (prm_68020 || isambyte2(ap1,ap2)) {
  1046. if (ap2->preg == -1) {
  1047. ap2->preg = ap1->preg;
  1048. if (ap2->offset->nodetype == am_immed && ap1->offset->nodetype == am_immed)
  1049. ap2->offset->v.i+= ap1->offset->v.i;
  1050. else
  1051. ap2->offset = makenode(en_add,ap2->offset, ap1->offset);
  1052. return ap2;
  1053. }
  1054. freeop(ap2);
  1055. ap = temp_addr();
  1056. gen_lea(0,ap2,ap);
  1057. ap->mode = am_baseindxaddr;
  1058. ap->sreg = ap1->preg;
  1059. ap->scale = 0;
  1060. ap->offset = ap1->offset;
  1061. return ap;
  1062. }
  1063. if (ap2->preg == -1) {
  1064. ap3 = xalloc(sizeof(AMODE));
  1065. ap3->preg = ap2->sreg;
  1066. if (ap2->mode == am_baseindxdata) {
  1067. ap3->mode = F_DREG;
  1068. if (ap3->preg < cf_freedata)
  1069. ap3->tempflag = 1;
  1070. }
  1071. else {
  1072. ap3->mode = F_AREG;
  1073. if (ap3->preg < cf_freeaddress)
  1074. ap3->tempflag = 1;
  1075. }
  1076. if (ap2->scale) {
  1077. make_legal(ap3,F_DREG | F_VOL,4);
  1078. gen_code(op_asl,4,ap3,make_immed(ap2->scale));
  1079. make_legal(ap3,F_AREG | F_VOL,4);
  1080. }
  1081. else
  1082. make_legal(ap3,F_AREG,4);
  1083. ap2->preg = ap3->preg;
  1084. ap2->mode = am_indx;
  1085. return ap2;
  1086. }
  1087. freeop(ap2);
  1088. ap = temp_addr();
  1089. gen_lea(0,ap2,ap);
  1090. ap2 = temp_data();
  1091. gen_code(op_move,4,ap,ap2);
  1092. freeop(ap1);
  1093. gen_lea(0,ap1,ap);
  1094. ap->mode = am_baseindxdata;
  1095. ap->sreg = ap2->preg;
  1096. ap->scale = 0;
  1097. ap->offset = makenode(en_icon,0,0);
  1098. return ap;
  1099. }
  1100. break;
  1101. case am_ind:
  1102. switch (ap2->mode) {
  1103. case am_areg:
  1104. ap2->mode = am_baseindxaddr;
  1105. ap2->offset = makenode(en_icon,0,0);
  1106. ap2->scale = 0;
  1107. ap2->sreg = ap1->preg;
  1108. return ap2;
  1109. case am_dreg:
  1110. ap1->mode = am_baseindxdata;
  1111. ap1->offset = makenode(en_icon,0,0);
  1112. ap1->scale = 0;
  1113. ap1->sreg = ap2->preg;
  1114. return ap1;
  1115. case am_adirect:
  1116. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  1117. ap1->offset = ap2->offset;
  1118. ap1->mode = am_indx;
  1119. return ap1;
  1120. }
  1121. ap = temp_addr();
  1122. gen_lea(0,ap2,ap);
  1123. ap1->mode = am_baseindxaddr;
  1124. ap1->sreg = ap->preg;
  1125. ap1->scale = 0;
  1126. ap1->offset = makenode(en_icon,0,0);
  1127. return ap1;
  1128. case am_immed:
  1129. if (prm_68020 || isamshort(ap2)) {
  1130. ap1->offset = ap2->offset;
  1131. ap1->mode = am_indx;
  1132. return ap1;
  1133. }
  1134. ap = temp_data();
  1135. gen_code(op_move,4,ap2,ap);
  1136. ap1->mode = am_baseindxdata;
  1137. ap1->scale = 0;
  1138. ap1->sreg = ap->preg;
  1139. ap1->offset = makenode(en_icon,0,0);
  1140. return ap1;
  1141. case am_indx:
  1142. if (isambyte(ap2) || prm_68020) {
  1143. ap2->mode = am_baseindxaddr;
  1144. ap2->sreg = ap1->preg;
  1145. return ap2;
  1146. }
  1147. freeop(ap2);
  1148. ap = temp_addr();
  1149. gen_lea(0,ap2,ap);
  1150. ap1->sreg = ap->preg;
  1151. ap1->mode = am_baseindxaddr;
  1152. ap1->scale = 0;
  1153. ap1->offset = makenode(en_icon,0,0);
  1154. return ap1;
  1155. case am_ind:
  1156. ap1->mode = am_baseindxaddr;
  1157. ap1->sreg= ap2->preg;
  1158. ap1->scale = 0;
  1159. ap1->offset = makenode(en_icon,0,0);
  1160. return ap1;
  1161. case am_baseindxaddr:
  1162. case am_baseindxdata:
  1163. if (ap2->preg == -1) {
  1164. ap2->preg = ap1->preg;
  1165. return ap2;
  1166. }
  1167. freeop(ap2);
  1168. ap = temp_addr();
  1169. gen_lea(0,ap2,ap);
  1170. ap->mode = am_baseindxaddr;
  1171. ap->sreg = ap1->preg;
  1172. ap->scale = 0;
  1173. ap->offset = makenode(en_icon,0,0);
  1174. return ap;
  1175. }
  1176. break;
  1177. case am_baseindxaddr:
  1178. switch (ap2->mode) {
  1179. case am_areg:
  1180. if (ap1->preg == -1) {
  1181. ap1->preg = ap2->preg;
  1182. return ap1;
  1183. }
  1184. freeop(ap1);
  1185. ap = temp_addr();
  1186. gen_lea(0,ap1,ap);
  1187. ap2->mode = am_baseindxaddr;
  1188. ap2->scale = 0;
  1189. ap2->offset = makenode(en_icon,0,0);
  1190. ap2->sreg = ap->preg;
  1191. return ap2;
  1192. case am_dreg:
  1193. if (ap1->preg == -1) {
  1194. ap = temp_addr();
  1195. gen_code(op_move,4,ap2,ap);
  1196. ap1->preg = ap->preg;
  1197. return ap1;
  1198. }
  1199. freeop(ap1);
  1200. ap = temp_addr();
  1201. gen_lea(0,ap1,ap);
  1202. ap->mode = am_baseindxdata;
  1203. ap->scale = 0;
  1204. ap->offset = makenode(en_icon,0,0);
  1205. ap->sreg = ap2->preg;
  1206. return ap;
  1207. case am_adirect:
  1208. if (prm_68020) {
  1209. ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
  1210. return ap1;
  1211. }
  1212. if (ap1->preg == -1) {
  1213. ap = temp_addr();
  1214. ap1->preg = ap->preg;
  1215. gen_lea(0,ap2,ap);
  1216. return ap1;
  1217. }
  1218. ap = temp_addr();
  1219. gen_lea(0,ap2,ap);
  1220. ap1->mode = am_baseindxaddr;
  1221. ap1->sreg = ap->preg;
  1222. ap1->scale = 0;
  1223. ap1->offset = makenode(en_icon,0,0);
  1224. return ap1;
  1225. case am_immed:
  1226. if (!prm_68020 && ap1->preg == -1) {
  1227. ap = temp_addr();
  1228. gen_code(op_move,4,ap2,ap);
  1229. ap1->preg = ap->preg;
  1230. return ap1;
  1231. }
  1232. if (prm_68020 || isambyte2(ap1,ap2)) {
  1233. if (ap1->offset->nodetype == am_immed)
  1234. ap1->offset->v.i += ap2->offset->v.i;
  1235. else
  1236. ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
  1237. return ap1;
  1238. }
  1239. freeop(ap1);
  1240. ap = temp_addr();
  1241. gen_lea(0,ap1,ap);
  1242. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  1243. ap->mode = am_indx;
  1244. ap->offset = ap2->offset;
  1245. return ap;
  1246. }
  1247. ap1 = temp_data();
  1248. ap1->mode = am_baseindxdata;
  1249. ap1->sreg = ap->preg;
  1250. ap1->scale = 0;
  1251. ap1->offset = makenode(en_icon,0,0);
  1252. return ap1;
  1253. case am_indx:
  1254. if (prm_68020 || isambyte2(ap1,ap2)) {
  1255. if (ap1->preg == -1) {
  1256. ap1->preg = ap2->preg;
  1257. if (ap2->offset->nodetype == am_immed && ap1->offset->nodetype == am_immed)
  1258. ap1->offset->v.i+= ap2->offset->v.i;
  1259. else
  1260. ap1->offset = makenode(en_add,ap1->offset, ap2->offset);
  1261. return ap1;
  1262. }
  1263. freeop(ap1);
  1264. ap = temp_addr();
  1265. gen_lea(0,ap1,ap);
  1266. ap->mode = am_baseindxaddr;
  1267. ap->sreg = ap2->preg;
  1268. ap->scale = 0;
  1269. ap->offset = ap2->offset;
  1270. return ap;
  1271. }
  1272. if (ap1->preg == -1) {
  1273. ap3 = xalloc(sizeof(AMODE));
  1274. ap3->preg = ap1->sreg;
  1275. if (ap1->mode == am_baseindxdata) {
  1276. ap3->mode = F_DREG;
  1277. if (ap3->preg < cf_freedata)
  1278. ap3->tempflag = 1;
  1279. }
  1280. else {
  1281. ap3->mode = F_AREG;
  1282. if (ap3->preg < cf_freeaddress)
  1283. ap3->tempflag = 1;
  1284. }
  1285. if (ap1->scale) {
  1286. make_legal(ap3,F_DREG | F_VOL,4);
  1287. gen_code(op_asl,4,ap3,make_immed(ap1->scale));
  1288. make_legal(ap3,F_AREG | F_VOL,4);
  1289. }
  1290. else
  1291. make_legal(ap3,F_AREG,4);
  1292. ap1->preg = ap3->preg;
  1293. ap1->mode = am_indx;
  1294. return ap1;
  1295. }
  1296. freeop(ap1);
  1297. ap = temp_addr();
  1298. gen_lea(0,ap1,ap);
  1299. ap1 = temp_data();
  1300. gen_code(op_move,4,ap,ap1);
  1301. freeop(ap2);
  1302. ap = temp_addr();
  1303. gen_lea(0,ap2,ap);
  1304. ap->mode = am_baseindxdata;
  1305. ap->sreg = ap1->preg;
  1306. ap->scale = 0;
  1307. ap->offset = makenode(en_icon,0,0);
  1308. return ap;
  1309. case am_ind:
  1310. if (ap1->preg == -1) {
  1311. ap1->preg = ap2->preg;
  1312. return ap1;
  1313. }
  1314. freeop(ap1);
  1315. ap = temp_addr();
  1316. gen_lea(0,ap1,ap);
  1317. ap->mode = am_baseindxaddr;
  1318. ap->sreg = ap2->preg;
  1319. ap->scale = 0;
  1320. ap->offset = ap1->offset;
  1321. return ap;
  1322. case am_baseindxaddr:
  1323. case am_baseindxdata:
  1324. if (prm_68020 || (ap1->preg != -1 && ap2->preg != -1)) {
  1325. freeop(ap1);
  1326. ap = temp_addr();
  1327. gen_lea(0,ap1,ap);
  1328. ap1 = temp_data();
  1329. gen_code(op_move,4,ap,ap1);
  1330. freeop(ap2);
  1331. gen_lea(0,ap2,ap);
  1332. ap->mode = am_baseindxdata;
  1333. ap->sreg = ap1->preg;
  1334. ap->scale = 0;
  1335. ap->offset = makenode(en_icon,0,0);
  1336. return ap;
  1337. }
  1338. if (ap1->preg == -1) {
  1339. ap3 = xalloc(sizeof(AMODE));
  1340. ap3->preg = ap1->sreg;
  1341. if (ap1->mode == am_baseindxdata) {
  1342. ap3->mode = F_DREG;
  1343. if (ap3->preg < cf_freedata)
  1344. ap3->tempflag = 1;
  1345. }
  1346. else {
  1347. ap3->mode = F_AREG;
  1348. if (ap3->preg < cf_freeaddress)
  1349. ap3->tempflag = 1;
  1350. }
  1351. if (ap1->scale) {
  1352. make_legal(ap3,F_DREG | F_VOL,4);
  1353. gen_code(op_asl,4,ap3,make_immed(ap1->scale));
  1354. make_legal(ap3,F_AREG | F_VOL,4);
  1355. }
  1356. else
  1357. make_legal(ap3,F_AREG,4);
  1358. ap1->preg = ap3->preg;
  1359. ap1->mode = am_indx;
  1360. }
  1361. if (ap2->preg == -1) {
  1362. ap3 = xalloc(sizeof(AMODE));
  1363. ap3->preg = ap2->sreg;
  1364. if (ap2->mode == am_baseindxdata) {
  1365. ap3->mode = F_DREG;
  1366. if (ap3->preg < cf_freedata)
  1367. ap3->tempflag = 1;
  1368. }
  1369. else {
  1370. ap3->mode = F_AREG;
  1371. if (ap3->preg < cf_freeaddress)
  1372. ap3->tempflag = 1;
  1373. }
  1374. if (ap2->scale) {
  1375. make_legal(ap3,F_DREG | F_VOL,4);
  1376. gen_code(op_asl,4,ap3,make_immed(ap2->scale));
  1377. make_legal(ap3,F_AREG | F_VOL,4);
  1378. }
  1379. else
  1380. make_legal(ap3,F_AREG,4);
  1381. ap2->preg = ap3->preg;
  1382. ap2->mode = am_indx;
  1383. }
  1384. goto tryagain;
  1385. }
  1386. break;
  1387. case am_baseindxdata:
  1388. switch (ap2->mode) {
  1389. case am_areg:
  1390. if (ap1->preg == -1) {
  1391. ap1->preg = ap2->preg;
  1392. return ap1;
  1393. }
  1394. freeop(ap1);
  1395. ap = temp_addr();
  1396. gen_lea(0,ap1,ap);
  1397. ap2->mode = am_baseindxaddr;
  1398. ap2->scale = 0;
  1399. ap2->offset = makenode(en_icon,0,0);
  1400. ap2->sreg = ap->preg;
  1401. return ap2;
  1402. case am_dreg:
  1403. if (ap1->preg == -1) {
  1404. ap = temp_addr();
  1405. gen_code(op_move,4,ap2,ap);
  1406. ap1->preg = ap->preg;
  1407. return ap1;
  1408. }
  1409. freeop(ap1);
  1410. ap = temp_addr();
  1411. gen_lea(0,ap1,ap);
  1412. ap->mode = am_baseindxdata;
  1413. ap->scale = 0;
  1414. ap->offset = makenode(en_icon,0,0);
  1415. ap->sreg = ap2->preg;
  1416. return ap;
  1417. case am_adirect:
  1418. if (prm_68020) {
  1419. ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
  1420. return ap1;
  1421. }
  1422. if (ap1->preg == -1) {
  1423. ap = temp_addr();
  1424. ap1->preg = ap->preg;
  1425. gen_lea(0,ap2,ap);
  1426. return ap1;
  1427. }
  1428. ap = temp_addr();
  1429. gen_lea(0,ap2,ap);
  1430. ap1->mode = am_baseindxaddr;
  1431. ap1->sreg = ap->preg;
  1432. ap1->scale = 0;
  1433. ap1->offset = makenode(en_icon,0,0);
  1434. return ap1;
  1435. case am_immed:
  1436. if (!prm_68020 && ap1->preg == -1) {
  1437. ap = temp_addr();
  1438. gen_code(op_move,4,ap2,ap);
  1439. ap1->preg = ap->preg;
  1440. return ap1;
  1441. }
  1442. if (prm_68020 || isambyte2(ap1,ap2)) {
  1443. if (ap1->offset->nodetype == am_immed)
  1444. ap1->offset->v.i += ap2->offset->v.i;
  1445. else
  1446. ap1->offset = makenode(en_add,ap1->offset,ap2->offset);
  1447. return ap1;
  1448. }
  1449. freeop(ap1);
  1450. ap = temp_addr();
  1451. gen_lea(0,ap1,ap);
  1452. if ((!prm_largedata && (prm_rel || !prm_smalldata)) || prm_68020) {
  1453. ap->mode = am_indx;
  1454. ap->offset = ap2->offset;
  1455. return ap;
  1456. }
  1457. ap1 = temp_data();
  1458. ap1->mode = am_baseindxdata;
  1459. ap1->sreg = ap->preg;
  1460. ap1->scale = 0;
  1461. ap1->offset = makenode(en_icon,0,0);
  1462. return ap1;
  1463. case am_indx:
  1464. if (prm_68020 || isambyte2(ap1,ap2)) {
  1465. if (ap1->preg == -1) {
  1466. ap1->preg = ap2->preg;
  1467. if (ap2->offset->nodetype == am_immed && ap1->offset->nodetype == am_immed)
  1468. ap1->offset->v.i+= ap2->offset->v.i;
  1469. else
  1470. ap1->offset = makenode(en_add,ap1->offset, ap2->offset);
  1471. return ap1;
  1472. }
  1473. freeop(ap1);
  1474. ap = temp_addr();
  1475. gen_lea(0,ap1,ap);
  1476. ap->mode = am_baseindxaddr;
  1477. ap->sreg = ap2->preg;
  1478. ap->scale = 0;
  1479. ap->offset = ap2->offset;
  1480. return ap;
  1481. }
  1482. if (ap1->preg == -1) {
  1483. ap3 = xalloc(sizeof(AMODE));
  1484. ap3->preg = ap1->sreg;
  1485. if (ap1->mode == am_baseindxdata) {
  1486. ap3->mode = F_DREG;
  1487. if (ap3->preg < cf_freedata)
  1488. ap3->tempflag = 1;
  1489. }
  1490. else {
  1491. ap3->mode = F_AREG;
  1492. if (ap3->preg < cf_freeaddress)
  1493. ap3->tempflag = 1;
  1494. }
  1495. if (ap3->preg < cf_freedata)
  1496. ap3->tempflag = 1;
  1497. if (ap1->scale) {
  1498. make_legal(ap3,F_DREG | F_VOL,4);
  1499. gen_code(op_asl,4,ap3,make_immed(ap1->scale));
  1500. make_legal(ap3,F_AREG | F_VOL,4);
  1501. }
  1502. else
  1503. make_legal(ap3,F_AREG,4);
  1504. ap1->preg = ap3->preg;
  1505. ap1->mode = am_indx;
  1506. return ap1;
  1507. }
  1508. freeop(ap1);
  1509. ap = temp_addr();
  1510. gen_lea(0,ap1,ap);
  1511. ap1 = temp_data();
  1512. gen_code(op_move,4,ap,ap1);
  1513. freeop(ap2);
  1514. gen_lea(0,ap2,ap);
  1515. ap->mode = am_baseindxdata;
  1516. ap->sreg = ap1->preg;
  1517. ap->scale = 0;
  1518. ap->offset = makenode(en_icon,0,0);
  1519. return ap;
  1520. case am_ind:
  1521. if (ap1->preg == -1) {
  1522. ap1->preg = ap2->preg;
  1523. return ap1;
  1524. }
  1525. freeop(ap1);
  1526. ap = temp_addr();
  1527. gen_lea(0,ap1,ap);
  1528. ap->mode = am_baseindxaddr;
  1529. ap->sreg = ap2->preg;
  1530. ap->scale = 0;
  1531. ap->offset = ap1->offset;
  1532. return ap;
  1533. case am_baseindxaddr:
  1534. case am_baseindxdata:
  1535. if (prm_68020 || (ap1->preg != -1 && ap2->preg != -1)) {
  1536. freeop(ap1);
  1537. ap = temp_addr();
  1538. gen_lea(0,ap1,ap);
  1539. ap1 = temp_data();
  1540. gen_code(op_move,4,ap,ap1);
  1541. freeop(ap2);
  1542. gen_lea(0,ap2,ap);
  1543. ap->mode = am_baseindxdata;
  1544. ap->sreg = ap->preg;
  1545. ap->scale = 0;
  1546. ap->offset = makenode(en_icon,0,0);
  1547. return ap;
  1548. }
  1549. if (ap1->preg == -1) {
  1550. ap3 = xalloc(sizeof(AMODE));
  1551. ap3->preg = ap1->sreg;
  1552. if (ap1->mode == am_baseindxdata) {
  1553. ap3->mode = F_DREG;
  1554. if (ap3->preg < cf_freedata)
  1555. ap3->tempflag = 1;
  1556. }
  1557. else {
  1558. ap3->mode = F_AREG;
  1559. if (ap3->preg < cf_freeaddress)
  1560. ap3->tempflag = 1;
  1561. }
  1562. if (ap1->scale) {
  1563. make_legal(ap3,F_DREG | F_VOL,4);
  1564. gen_code(op_asl,4,ap3,make_immed(ap1->scale));
  1565. make_legal(ap3,F_AREG | F_VOL,4);
  1566. }
  1567. else
  1568. make_legal(ap3,F_AREG,4);
  1569. ap1->preg = ap3->preg;
  1570. ap1->mode = am_indx;
  1571. }
  1572. if (ap2->preg == -1) {
  1573. ap3 = xalloc(sizeof(AMODE));
  1574. ap3->preg = ap2->sreg;
  1575. if (ap2->mode == am_baseindxdata) {
  1576. ap3->mode = F_DREG;
  1577. if (ap3->preg < cf_freedata)
  1578. ap3->tempflag = 1;
  1579. }
  1580. else {
  1581. ap3->mode = F_AREG;
  1582. if (ap3->preg < cf_freeaddress)
  1583. ap3->tempflag = 1;
  1584. }
  1585. if (ap2->scale) {
  1586. make_legal(ap3,F_DREG | F_VOL,4);
  1587. gen_code(op_asl,4,ap3,make_immed(ap2->scale));
  1588. make_legal(ap3,F_AREG | F_VOL,4);
  1589. }
  1590. else
  1591. make_legal(ap3,F_AREG,4);
  1592. ap2->preg = ap3->preg;
  1593. ap2->mode = am_indx;
  1594. }
  1595. goto tryagain;
  1596. }
  1597. break;
  1598. }
  1599. DIAG("invalid index conversion");
  1600. }
  1601. AMODE    *gen_deref(ENODE *node, int flags,int size, int flag)
  1602. /*
  1603.  *      return the addressing mode of a dereferenced node.
  1604.  */
  1605. {       AMODE    *ap1,*ap2;
  1606.         int             siz1,psize;
  1607. psize = size;
  1608. if (psize < 0)
  1609. psize = - psize;
  1610.         switch( node->nodetype )        /* get load size */
  1611.                 {
  1612.                 case en_ub_ref:
  1613.                         siz1 = 1;
  1614.                         break;
  1615.                 case en_b_ref:
  1616.                         siz1 = -1;
  1617.                         break;
  1618.                 case en_uw_ref:
  1619.                         siz1 = 2;
  1620.                         break;
  1621.                 case en_w_ref:
  1622.                         siz1 = -2;
  1623.                         break;
  1624.                 case en_l_ref:
  1625. siz1 = -4;
  1626. break;
  1627. case en_add:
  1628. case en_ul_ref:
  1629.                         siz1 = 4;
  1630.                         break;
  1631. case en_floatref:
  1632. siz1 = 6;
  1633. break;
  1634. case en_doubleref:
  1635. siz1 = 8;
  1636. break;
  1637. case en_longdoubleref:
  1638. siz1 = 10;
  1639. break;
  1640. default:
  1641. siz1 = 4;
  1642.                 }
  1643.         if( node->v.p[0]->nodetype == en_add )
  1644.                 {
  1645.                 ap1 = gen_index(siz1,node->v.p[0]);
  1646.                 do_extend(ap1,siz1,size,flags);
  1647.                 make_legal(ap1,flags,psize);
  1648.                 return ap1;
  1649.                 }
  1650.         else if( node->v.p[0]->nodetype == en_autocon  || node->v.p[0]->nodetype == en_autoreg)
  1651.                 {
  1652.                 ap1 = xalloc(sizeof(AMODE));
  1653.                 ap1->mode = am_indx;
  1654. if (prm_linkreg && !currentfunc->intflag) {
  1655.                  ap1->preg = linkreg;
  1656.                  ap1->offset = makenode(en_icon,(char *)((SYM *)node->v.p[0]->v.p[0])->value.i,0);
  1657. }
  1658. else if (((SYM *)node->v.p[0]->v.p[0])->funcparm) {
  1659. if (prm_phiform || currentfunc->intflag) {
  1660.                  ap1->preg = linkreg;
  1661.                  ap1->offset = makenode(en_icon,(char *)((SYM *)node->v.p[0]->v.p[0])->value.i,0);
  1662. }
  1663. else {
  1664.                  ap1->preg = 7;
  1665.                  ap1->offset = makenode(en_icon,(char *)(((SYM *)node->v.p[0]->v.p[0])->value.i+framedepth+stackdepth),0);
  1666. }
  1667. }
  1668. else {
  1669.                  ap1->preg = 7;
  1670.                  ap1->offset = makenode(en_icon,(char *)(((SYM *)node->v.p[0]->v.p[0])->value.i+stackdepth+lc_maxauto),0);
  1671. }
  1672.                 do_extend(ap1,siz1,size,flags);
  1673.                 make_legal(ap1,flags,psize);
  1674.                 return ap1;
  1675.                 }
  1676.         else if( node->v.p[0]->nodetype == en_nacon)
  1677.                 {
  1678.                ap1 = xalloc(sizeof(AMODE));
  1679. if (prm_rel) {
  1680.                  ap1->preg = basereg;
  1681.                  ap1->offset = makenode(node->v.p[0]->nodetype,((SYM *)node->v.p[0]->v.p[0])->name,0);
  1682.         if (prm_largedata) {
  1683. ap2 = temp_addr();
  1684. ap1->mode = am_areg;
  1685. gen_code(op_move,4,ap1,ap2);
  1686. ap1->mode = am_immed;
  1687. gen_code(op_add,4,ap1,ap2);
  1688. ap1 = ap2;
  1689. ap1->mode = am_ind;
  1690. }
  1691. else {
  1692.                   ap1->mode = am_indx;
  1693. }
  1694. }
  1695. else {
  1696. ap1->mode = am_adirect;
  1697.                  ap1->offset = makenode(node->v.p[0]->nodetype,((SYM *)node->v.p[0]->v.p[0])->name,0);
  1698. if (prm_smalldata)
  1699. ap1->preg = 2;
  1700. else
  1701. ap1->preg = 4;
  1702. }
  1703.                 do_extend(ap1,siz1,size,flags);
  1704.                 make_legal(ap1,flags,psize);
  1705.                 return ap1;
  1706.                 }
  1707.         else if( node->v.p[0]->nodetype == en_nalabcon)
  1708.                 {
  1709.                ap1 = xalloc(sizeof(AMODE));
  1710. if (prm_rel) {
  1711.                  ap1->preg = basereg;
  1712.                  ap1->offset = makenode(node->v.p[0]->nodetype,(char *)node->v.p[0]->v.i,0);
  1713.         if (prm_largedata) {
  1714. ap2 = temp_addr();
  1715. ap1->mode = am_areg;
  1716. gen_code(op_move,4,ap1,ap2);
  1717. ap1->mode = am_immed;
  1718. gen_code(op_add,4,ap1,ap2);
  1719. ap1 = ap2;
  1720. ap1->mode = am_ind;
  1721. }
  1722. else {
  1723.                   ap1->mode = am_indx;
  1724. }
  1725. }
  1726. else {
  1727. ap1->mode = am_adirect;
  1728.                  ap1->offset = makenode(node->v.p[0]->nodetype,(char *)node->v.p[0]->v.i,0);
  1729. if (prm_smalldata)
  1730. ap1->preg = 2;
  1731. else
  1732. ap1->preg = 4;
  1733. }
  1734.                 do_extend(ap1,siz1,size,flags);
  1735.                 make_legal(ap1,flags,psize);
  1736.                 return ap1;
  1737.                 }
  1738.         else if( node->v.p[0]->nodetype == en_labcon || node->v.p[0]->nodetype == en_napccon)
  1739.                 {
  1740.                 ap1 = xalloc(sizeof(AMODE));
  1741. if (prm_rel)
  1742.                   ap1->mode = am_pcindx;
  1743. else {
  1744. ap1->mode = am_adirect;
  1745. if (prm_smallcode)
  1746. ap1->preg = 2;
  1747. else
  1748. ap1->preg = 4;
  1749. }
  1750. if (node->v.p[0]->nodetype == en_labcon)
  1751.                   ap1->offset = makenode(node->v.p[0]->nodetype,(char *)node->v.p[0]->v.i,0);
  1752. else
  1753.                   ap1->offset = makenode(node->v.p[0]->nodetype,((SYM *)node->v.p[0]->v.p[0])->name,0);
  1754.                 do_extend(ap1,siz1,size,flags);
  1755.                 make_legal(ap1,flags,psize);
  1756.                 return ap1;
  1757.                 }
  1758. else if (node->v.p[0]->nodetype == en_absacon) {
  1759. ap1 = xalloc(sizeof(AMODE));
  1760. ap1->mode = am_adirect;
  1761. ap1->preg = isshort(node->v.p[0]) ? 2 : 4;
  1762. ap1->offset = makenode(en_absacon,(char *)((SYM *)node->v.p[0]->v.p[0])->value.i,0);
  1763.                 do_extend(ap1,siz1,size,flags);
  1764.                 make_legal(ap1,flags,psize);
  1765.                 return ap1;
  1766. }
  1767. else if (node->v.p[0]->nodetype == en_regref) {
  1768.          ap1 = gen_expr(node->v.p[0],F_ALL,4);
  1769.           do_extend(ap1,siz1,size,flags);
  1770.           make_legal(ap1,flags,psize);
  1771. return ap1;
  1772. }
  1773. if (flag) {
  1774.          ap1 = gen_expr(node->v.p[0],F_AREG | F_DREG | F_IMMED,4); /* generate address */
  1775. if (ap1->mode == am_dreg)
  1776. return ap1;
  1777. }
  1778. else {
  1779.          ap1 = gen_expr(node->v.p[0],F_AREG | F_IMMED,4); /* generate address */
  1780. }
  1781. /* AINCDEC for example may return an indirect mode already */
  1782. if (ap1->mode == am_areg || ap1->mode == am_immed) {
  1783.          if( ap1->mode == am_areg )
  1784.                  {
  1785.                  ap1->mode = am_ind;
  1786.                  do_extend(ap1,siz1,size,flags);
  1787.                  make_legal(ap1,flags,psize);
  1788.                  return ap1;
  1789.                  }
  1790.          ap1->mode = am_direct;
  1791. }
  1792.         do_extend(ap1,siz1,size,flags);
  1793.         make_legal(ap1,flags,psize);
  1794.         return ap1;
  1795. }
  1796. AMODE    *gen_unary(ENODE *node,int flags,int size,int op, int fop)
  1797. /*
  1798.  *      generate code to evaluate a unary minus or complement.
  1799.  */
  1800. {       AMODE    *ap;
  1801.         ap = gen_expr(node->v.p[0],F_FREG | F_DREG | F_VOL,size);
  1802. if (ap->mode == am_freg) {
  1803.          gen_codef(fop,size,ap,0);
  1804. }
  1805. else {
  1806.          gen_code(op,size,ap,0);
  1807. }
  1808.         make_legal(ap,flags,size);
  1809.         return ap;
  1810. }
  1811. AMODE    *gen_binary(ENODE *node,int flags,int size,int op, int fop)
  1812. /*
  1813.  *      generate code to evaluate a binary node and return 
  1814.  *      the addressing mode of the result.
  1815.  */
  1816. {       AMODE    *ap1, *ap2;
  1817.         ap1 = gen_expr(node->v.p[0],F_VOL | F_DREG | F_AREG | F_FREG,size);
  1818. mark();
  1819.         ap2 = gen_expr(node->v.p[1],F_ALL,size);
  1820. if (size > 4)
  1821.          gen_codef(fop,size,ap2,ap1);
  1822. else
  1823.          gen_code(op,size,ap2,ap1);
  1824.         freeop(ap2);
  1825.         release();
  1826.         make_legal(ap1,flags,size);
  1827.         return ap1;
  1828. }
  1829. AMODE    *gen_xbin(ENODE *node,int flags,int size,int op, int fop)
  1830. /*
  1831.  *      generate code to evaluate a restricted binary node and return 
  1832.  *      the addressing mode of the result.
  1833.  */
  1834. {       AMODE    *ap1, *ap2;
  1835.         ap1 = gen_expr(node->v.p[0],F_VOL | F_DREG | F_FREG,size);
  1836. mark();
  1837.         ap2 = gen_expr(node->v.p[1],F_DREG| F_FREG, size);
  1838. if (size > 4)
  1839.          gen_codef(fop,size,ap2,ap1);
  1840. else
  1841.          gen_code(op,size,ap2,ap1);
  1842.         freeop(ap2);
  1843. release();
  1844.         make_legal(ap1,flags,size);
  1845.         return ap1;
  1846. }
  1847. AMODE    *gen_shift(ENODE *node, int flags, int size, int op)
  1848. /*
  1849.  *      generate code to evaluate a shift node and return the
  1850.  *      address mode of the result.
  1851.  */
  1852. {       AMODE    *ap1, *ap2;
  1853.         ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,size);
  1854. mark();
  1855.         ap2 = gen_expr(node->v.p[1],F_DREG | F_IMMED,size);
  1856. doshift(op,ap2,ap1,size);
  1857.         freeop(ap2);
  1858. release();
  1859.         make_legal(ap1,flags,size);
  1860.         return ap1;
  1861. }
  1862. AMODE    *gen_modiv(ENODE *node, int flags, int size, int op, int modflag)
  1863. /*
  1864.  *      generate code to evaluate a mod operator or a divide
  1865.  *      operator. these operations are done on only long
  1866.  *      divisors and word dividends so that the 68000 div
  1867.  *      instruction can be used.
  1868.  */
  1869. {       AMODE    *ap1, *ap2,*ap3;
  1870. int temp;
  1871. int sz1 = natural_size(node->v.p[0]);
  1872. int sz2 = natural_size(node->v.p[0]);
  1873. int psize;
  1874. if (sz1 < 0)  sz1 = - sz1;
  1875. if (sz2 < 0)  sz2 = - sz2;
  1876. psize = sz2 > sz1 ? sz2 : sz1;
  1877. if (psize < 2) psize = 2;
  1878. if (op == op_divs)  psize = -psize;
  1879. if (size > 4) {
  1880. ap1 = gen_expr(node->v.p[0],F_FREG | F_VOL,size);
  1881. mark();
  1882. ap2 = gen_expr(node->v.p[1],F_ALL&~F_AREG,size);
  1883. gen_codef(op_fdiv,size,ap2,ap1);
  1884. freeop(ap2);
  1885. release();
  1886. make_legal(ap1,flags,size);
  1887. return(ap1);
  1888. }
  1889. if (prm_68020 || psize ==2 || psize == -2) {
  1890. if (psize != 2 && psize != -2)
  1891. if (op == op_divs)
  1892. op = op_divsl;
  1893. else
  1894. op = op_divul;
  1895.          ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,psize == 2 ? 4 : -4);
  1896. mark();
  1897.          ap2 = gen_expr(node->v.p[1],F_ALL & ~F_AREG,psize);
  1898. if (psize !=2 && psize != -2) {
  1899. ap3 = temp_data();
  1900. temp = ap3->preg;
  1901. ap3->mode = am_divsl;
  1902.          if( modflag ) {
  1903. ap3->sreg = ap1->sreg;
  1904. }
  1905. else {
  1906. ap3->sreg = ap3->preg = ap1->sreg;
  1907. }
  1908. gen_code(op,psize,ap2,ap3);
  1909. ap3->mode = am_dreg;
  1910. ap3->preg = temp;
  1911. if (modflag)
  1912. gen_code(op_exg,0,ap1,ap3);
  1913.          freeop(ap3);
  1914. }
  1915. else {
  1916. gen_code(op,2,ap2,ap1);
  1917. if (modflag) {
  1918. gen_code(op_swap,2,ap1,0);
  1919. }
  1920. }
  1921. do_extend(ap1,psize,size,flags);
  1922.          make_legal(ap1,flags,size);
  1923.          freeop(ap2);
  1924.          release();
  1925.          return ap1;
  1926. }
  1927. flush_for_libcall();
  1928. if (op == op_divs) {
  1929.          ap1 = gen_expr(node->v.p[0],F_ALL,-4);
  1930. }
  1931. else {
  1932.          ap1 = gen_expr(node->v.p[0],F_ALL,4);
  1933. }
  1934. mark();
  1935. if (op == op_divs) {
  1936.          ap2 = gen_expr(node->v.p[1],F_ALL,-4);
  1937. }
  1938. else {
  1939.          ap2 = gen_expr(node->v.p[1],F_ALL,4);
  1940. }
  1941. gen_code(op_move,4,ap1,push);
  1942.         freeop(ap2);
  1943. gen_code(op_move,4,ap2,push);
  1944. freeop(ap1);
  1945. if (op == op_divs)
  1946. if (modflag) {
  1947. ap1 = call_library("__mods",8);
  1948. }
  1949. else {
  1950. ap1 = call_library("__divs",8);
  1951. }
  1952. else
  1953. if (modflag) {
  1954. ap1 = call_library("__modu",8);
  1955. }
  1956. else {
  1957. ap1 = call_library("__divu",8);
  1958. }
  1959. release();
  1960. make_legal(ap1,flags,size);
  1961.         return ap1;
  1962. }
  1963. void swap_nodes(ENODE *node)
  1964. /*
  1965.  *      exchange the two operands in a node.
  1966.  */
  1967. {       ENODE    *temp;
  1968.         temp = node->v.p[0];
  1969.         node->v.p[0] = node->v.p[1];
  1970.         node->v.p[1] = temp;
  1971. }
  1972. AMODE * gen_pdiv(ENODE *node, int flags, int size)
  1973. {
  1974. AMODE *ap1, *ap2;
  1975. ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,4);
  1976. mark();
  1977. ap2 = gen_expr(node->v.p[1],F_ALL,2);
  1978. gen_code(op_divs,2,ap2,ap1);
  1979. freeop(ap2);
  1980. release();
  1981. make_legal(ap1,flags,size);
  1982.         return ap1;
  1983. }
  1984. AMODE * gen_pmul(ENODE *node, int flags, int size)
  1985. {
  1986. AMODE *ap1, *ap2;
  1987. if (isintconst(node->v.p[0]->nodetype))
  1988. swap_nodes(node);
  1989. ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,4);
  1990. mark();
  1991. ap2 = gen_expr(node->v.p[1],F_ALL,4);
  1992. gen_code(op_muls,0,ap2,ap1);
  1993. freeop(ap2);
  1994. release();
  1995. make_legal(ap1,flags,size);
  1996.         return ap1;
  1997. }
  1998. AMODE    *gen_mul(ENODE *node, int flags, int size, int op)
  1999. /*
  2000.  *      generate code to evaluate a multiply node. both operands
  2001.  *      are treated as words and the result is long and is always
  2002.  *      in a register so that the 68000 mul instruction can be used.
  2003.  */
  2004. {       AMODE    *ap1, *ap2;
  2005. int sz1 = natural_size(node->v.p[0]);
  2006. int sz2 = natural_size(node->v.p[0]);
  2007. int psize;
  2008. if (sz1 < 0)  sz1 = - sz1;
  2009. if (sz2 < 0)  sz2 = - sz2;
  2010. psize = sz2 > sz1 ? sz2 : sz1;
  2011. if (psize < 2) psize = 2;
  2012. if (op == op_muls)  psize = -psize;
  2013. if (size > 4) {
  2014. ap1 = gen_expr(node->v.p[0],F_FREG | F_VOL,size);
  2015. mark();
  2016. ap2 = gen_expr(node->v.p[1],F_ALL&~F_AREG,size);
  2017. gen_codef(op_fmul,size,ap2,ap1);
  2018. freeop(ap2);
  2019. release();
  2020. make_legal(ap1,flags,size);
  2021. return(ap1);
  2022. }
  2023. if (prm_68020 || psize == -2 || psize == 2) {
  2024. if (isintconst(node->v.p[0]->nodetype))
  2025. swap_nodes(node);
  2026.          ap1 = gen_expr(node->v.p[0],F_DREG | F_VOL,psize);
  2027. mark();
  2028.          ap2 = gen_expr(node->v.p[1],F_ALL&~F_AREG,psize);
  2029. gen_code(op,psize,ap2,ap1);
  2030. freeop(ap2);
  2031. release();
  2032. do_extend(ap1,psize,size,flags);
  2033. make_legal(ap1,flags,size);
  2034.          return ap1;
  2035. }
  2036. flush_for_libcall();
  2037. if (isintconst(node->v.p[0]->nodetype))
  2038. swap_nodes(node);
  2039. if (op == op_muls) {
  2040.          ap1 = gen_expr(node->v.p[0],F_ALL,-4);
  2041. }
  2042. else {
  2043.          ap1 = gen_expr(node->v.p[0],F_ALL,4);
  2044. }
  2045. mark();
  2046. if (op == op_muls) {
  2047.          ap2 = gen_expr(node->v.p[1],F_ALL,-4);
  2048. }
  2049. else {
  2050.          ap2 = gen_expr(node->v.p[1],F_ALL,4);
  2051. }
  2052. gen_code(op_move,4,ap1,push);
  2053.         freeop(ap2);
  2054. gen_code(op_move,4,ap2,push);
  2055. freeop(ap1);
  2056. if (op == op_muls) {
  2057. ap1 = call_library("__muls",8);
  2058. }
  2059. else {
  2060. ap1 = call_library("__mulu",8);
  2061. }
  2062.         release();
  2063. make_legal(ap1,flags,size);
  2064.         return ap1;
  2065. }
  2066. AMODE    *gen_hook(ENODE *node, int flags, int size)
  2067. /*
  2068.  *      generate code to evaluate a condition operator node (?:)
  2069.  */
  2070. {       AMODE    *ap1, *ap2;
  2071.         int             false_label, end_label;
  2072.         false_label = nextlabel++;
  2073.         end_label = nextlabel++;
  2074.         flags = (flags & (F_AREG | F_DREG)) | F_VOL;
  2075.         falsejp(node->v.p[0],false_label);
  2076.         node = node->v.p[1];
  2077.         ap1 = gen_expr(node->v.p[0],flags,size);
  2078.         freeop(ap1);
  2079.         gen_code(op_bra,0,make_label(end_label),0);
  2080.         gen_label(false_label);
  2081.         ap2 = gen_expr(node->v.p[1],flags,size);
  2082.         if( !equal_address(ap1,ap2) )
  2083.                 {
  2084.                 freeop(ap2);
  2085.                 if( ap1->mode == am_dreg )
  2086.                         temp_data();
  2087.                 else
  2088.                         temp_addr();
  2089.                 gen_code(op_move,size,ap2,ap1);
  2090.                 }
  2091.         gen_label(end_label);
  2092.         return ap1;
  2093. }
  2094. AMODE    *gen_asadd(ENODE *node, int flags, int size, int op, int fop)
  2095. /*
  2096.  *      generate a plus equal or a minus equal node.
  2097.  */
  2098. {       AMODE    *ap1, *ap2, *ap3;
  2099.         int             ssize,rsize;
  2100.         ssize = natural_size(node->v.p[0]);
  2101.         rsize = natural_size(node->v.p[1]);
  2102. if (ssize > 4) {
  2103. ap1 = gen_expr(node->v.p[0],F_ALL,ssize);
  2104. ap3 = xalloc(sizeof(AMODE));
  2105. ap3->mode = ap1->mode;
  2106. ap3->preg = ap1->preg;
  2107. ap3->sreg = ap1->sreg;
  2108. ap3->offset = ap1->offset;
  2109. make_legal(ap1,F_FREG,ssize);
  2110. mark();
  2111. ap2 = gen_expr(node->v.p[1],F_ALL,size);
  2112. gen_codef(fop,ssize,ap2,ap1);
  2113. make_legal(ap1,flags,size);
  2114. if (ap3->mode != am_freg)
  2115. gen_codef(op_fmove,ssize,ap1,ap3);
  2116. freeop(ap2);
  2117. release();
  2118. return(ap1);
  2119. }
  2120.         if (chksize( size , rsize ))
  2121.                 rsize = size;
  2122.         ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,ssize);
  2123. mark();
  2124. if (node->v.p[0]->nodetype == en_bits) {
  2125. ap3= get_bitval(ap1,node->v.p[0],ssize);
  2126. }
  2127.         ap2 = gen_expr(node->v.p[1],F_DREG | F_AREG | F_FREG | F_IMMED,rsize);
  2128. if (ssize > 4)
  2129.          gen_codef(fop,ssize,ap2,ap1);
  2130. else 
  2131. if (node->v.p[0]->nodetype == en_bits) {
  2132. gen_code(op,ssize,ap2,ap3);
  2133. bit_move(ap3,ap1,node->v.p[0],flags, ssize,rsize);
  2134. freeop(ap3);
  2135. }
  2136. else
  2137.          gen_code(op,ssize,ap2,ap1);
  2138.        freeop(ap2);
  2139. release();
  2140. if (flags & F_NOVALUE)
  2141. freeop(ap1);
  2142. else {
  2143. if (node->v.p[0]->nodetype == en_bits) {
  2144.           do_extend(ap3,ssize,size,0);
  2145.           make_legal(ap3,flags,size);
  2146.           return ap3;
  2147.        }
  2148.        do_extend(ap1,ssize,size,0);
  2149.         make_legal(ap1,flags,size);
  2150. }
  2151.         return ap1;
  2152. }
  2153. AMODE    *gen_aslogic(ENODE *node, int flags, int size, int op)
  2154. /*
  2155.  *      generate a and equal or a or equal node.
  2156.  */
  2157. {       AMODE    *ap1, *ap2, *ap3;
  2158.         int             ssize,rsize;
  2159.         ssize = natural_size(node->v.p[0]);
  2160.         rsize = natural_size(node->v.p[1]);
  2161.         if (chksize( size , rsize ))
  2162.                 rsize = size;
  2163.         ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,ssize);
  2164. mark();
  2165.         ap2 = gen_expr(node->v.p[1],F_DREG | F_IMMED,rsize);
  2166. if (node->v.p[0]->nodetype == en_bits) {
  2167. if (ap2->mode == am_immed) {
  2168. ap2->offset->v.i &= bittab[node->v.p[0]->bits-1];
  2169. ap2->offset->v.i <<= node->v.p[0]->startbit;
  2170. gen_code(op,ssize,ap2,ap1);
  2171. }
  2172. else {
  2173.   gen_code(op_and,ssize,make_immed(bittab[node->v.p[0]->bits-1]),ap2);
  2174. if (node->v.p[0]->startbit)
  2175.    gen_code(op_asl,ssize,make_immed(node->v.p[0]->startbit),ap2);
  2176. gen_code(op,ssize,ap2,ap1);
  2177. if (!(flags & F_NOVALUE)) {
  2178. freeop(ap2);
  2179. if (!(ap1->mode == am_dreg && ap1->preg < cf_freedata)) {
  2180. freeop(ap1);
  2181. ap2 = temp_data();
  2182. gen_code(op_move,ssize,ap1,ap2);
  2183. ap1 = ap2;
  2184. }
  2185. if (node->v.p[0]->startbit)
  2186.    gen_code(op_asr,ssize,make_immed(node->v.p[0]->startbit),ap1);
  2187.    gen_code(op_and,ssize,make_immed(bittab[node->v.p[0]->bits-1]),ap1);
  2188. }
  2189. }
  2190. }
  2191. else
  2192.          if( ap1->mode != am_areg )
  2193.                  gen_code(op,ssize,ap2,ap1);
  2194.         else
  2195.                  {
  2196.                  ap3 = temp_data();
  2197.                  gen_code(op_move,4,ap1,ap3);
  2198.                  gen_code(op,size,ap2,ap3);
  2199.                  gen_code(op_move,size,ap3,ap1);
  2200.                  freeop(ap3);
  2201.                  }
  2202.         freeop(ap2);
  2203. release();
  2204. if (flags & F_NOVALUE)
  2205. freeop(ap1);
  2206. else {
  2207.          do_extend(ap1,ssize,size,0);
  2208.          make_legal(ap1,flags,size);
  2209. }
  2210.         return ap1;
  2211. }
  2212. AMODE *gen_asshift(ENODE *node, int flags, int size, int op)
  2213. /*
  2214.  *      generate shift equals operators.
  2215.  */
  2216. {       AMODE    *ap1, *ap2, *ap3,*ap4;
  2217.         int ssize = natural_size(node->v.p[0]);
  2218.         int rsize = natural_size(node->v.p[1]);
  2219.         if (chksize( size , rsize ))
  2220.                 rsize = size;
  2221.         ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,ssize);
  2222. mark();
  2223. if (node->v.p[0]->nodetype == en_bits)
  2224. ap4 = get_bitval(ap1,node->v.p[0],ssize);
  2225. else
  2226. ap4 = ap1;
  2227.         if( ap4->mode != am_dreg )
  2228.                 {
  2229.                 ap3 = temp_data();
  2230. ap3->tempflag = TRUE;
  2231.                 gen_code(op_move,ssize,ap4,ap3);
  2232.                 }
  2233.         else
  2234.                 ap3 = ap4;
  2235.         ap2 = gen_expr(node->v.p[1],F_DREG | F_IMMED,rsize);
  2236. doshift(op,ap2,ap3,size);
  2237. if (node->v.p[0]->nodetype == en_bits) {
  2238.   bit_move(ap3,ap1,node->v.p[0],flags,ssize,ssize);
  2239.         } else if( ap3 != ap1 )
  2240.                 {
  2241.                 gen_code(op_move,ssize,ap3,ap1);
  2242.                 }
  2243. freeop(ap2);
  2244. release();
  2245. if (ap4 != ap1)
  2246. freeop(ap4);
  2247. if (flags & F_NOVALUE)
  2248. freeop(ap2);
  2249. else {
  2250.        do_extend(ap3,ssize,size,0);
  2251.          make_legal(ap3,flags,size);
  2252. }
  2253.         return ap3;
  2254. }
  2255. AMODE    *gen_asmul(ENODE *node, int flags, int size,int op)
  2256. /*
  2257.  *      generate a *= node.
  2258.  */
  2259. {       AMODE    *ap1, *ap2, *ap3, *ap4;
  2260.         int             siz1;
  2261. int sz1 = natural_size(node->v.p[0]);
  2262. int sz2 = natural_size(node->v.p[0]);
  2263. int psize;
  2264. if (sz1 < 0)  sz1 = - sz1;
  2265. if (sz2 < 0)  sz2 = - sz2;
  2266. psize = sz2 > sz1 ? sz2 : sz1;
  2267. if (psize < 2) psize = 2;
  2268. if (op == op_muls)  psize = -psize;
  2269.         siz1 = natural_size(node->v.p[0]);
  2270. if (siz1 > 4) {
  2271. ap1 = gen_expr(node->v.p[0],F_ALL&~F_AREG,siz1);
  2272. ap3 = xalloc(sizeof(AMODE));
  2273. ap3->mode = ap1->mode;
  2274. ap3->preg = ap1->preg;
  2275. ap3->sreg = ap1->sreg;
  2276. ap3->offset = ap1->offset;
  2277. make_legal(ap1,F_FREG,siz1);
  2278. mark();
  2279. ap2 = gen_expr(node->v.p[1],F_ALL&~F_AREG,siz1);
  2280. gen_codef(op_fmul,siz1,ap2,ap1);
  2281. make_legal(ap1,flags,size);
  2282. if (ap3->mode != am_freg)
  2283. gen_codef(op_fmove,siz1,ap1,ap3);
  2284. freeop(ap2);
  2285. release();
  2286. return(ap1);
  2287. }
  2288. if (prm_68020 || psize == 2 || psize == -2) {
  2289.          ap1 = gen_expr(node->v.p[1],F_DREG | F_VOL,psize);
  2290. ap4 = xalloc(sizeof(AMODE));
  2291.          ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,0);
  2292. ap4->mode = ap2->mode;
  2293. ap4->preg = ap2->preg;
  2294. ap4->sreg = ap2->sreg;
  2295. ap4->tempflag = ap2->tempflag;
  2296. ap4->offset = ap2->offset;
  2297. if (node->v.p[0]->nodetype == en_bits)
  2298. ap2 = get_bitval(ap2,node->v.p[0],psize);
  2299. do_extend(ap2,siz1, psize,F_ALL);
  2300.          gen_code(op,psize,ap2,ap1);
  2301. if (node->v.p[0]->nodetype == en_bits) 
  2302. bit_move(ap1,ap4,node->v.p[0],flags,siz1,psize);
  2303. else 
  2304.          gen_code(op_move,siz1,ap1,ap4);
  2305. if (flags & F_NOVALUE)
  2306. freeop(ap1);
  2307. else {
  2308.         do_extend(ap1,psize,size,flags);
  2309.           make_legal(ap1,flags,size);
  2310. }
  2311.          freeop(ap2);
  2312. return(ap1);
  2313. }
  2314. flush_for_libcall();
  2315. if (op == op_muls) {
  2316.          ap1 = gen_expr(node->v.p[1],F_ALL,-4);
  2317. }
  2318. else {
  2319.          ap1 = gen_expr(node->v.p[1],F_ALL,4);
  2320. }
  2321. ap4 = xalloc(sizeof(AMODE));
  2322.         ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,siz1);
  2323. ap4->mode = ap2->mode;
  2324. ap4->preg = ap2->preg;
  2325. ap4->sreg = ap2->sreg;
  2326. ap4->tempflag = ap2->tempflag;
  2327. ap4->offset = ap2->offset;
  2328. if (node->v.p[0]->nodetype == en_bits)
  2329. ap2 = get_bitval(ap2,node->v.p[0],siz1);
  2330. if (op == op_muls) {
  2331. do_extend(ap2,siz1, - 4,F_ALL);
  2332. }
  2333. else {
  2334. do_extend(ap2,siz1, 4,F_ALL);
  2335. }
  2336. gen_code(op_move,4,ap2,push);
  2337. gen_code(op_move,4,ap1,push);
  2338.         freeop(ap2);
  2339. freeop(ap1);
  2340. if (op == op_muls) {
  2341. ap1 = call_library("__muls",8);
  2342. }
  2343. else {
  2344. ap1 = call_library("__mulu",8);
  2345. }
  2346. if (node->v.p[0]->nodetype == en_bits)
  2347. bit_move(ap1,ap4,node->v.p[0],flags,siz1,size);
  2348. else
  2349.          gen_code(op_move,siz1,ap1,ap4);
  2350. freeop(ap4);
  2351. if (flags & F_NOVALUE)
  2352. freeop(ap1);
  2353. else {
  2354.        do_extend(ap1,siz1,size,0);
  2355.          make_legal(ap1,flags,size);
  2356. }
  2357.         return ap1;
  2358. }
  2359. AMODE    *gen_asmodiv(ENODE *node, int flags, int size, int op, int modflag)
  2360. /*
  2361.  *      generate /= and %= nodes.
  2362.  */
  2363. {       AMODE    *ap1, *ap2, *ap3 = 0, *ap4,*ap5;
  2364.         int             siz1,temp;
  2365. int sz1 = natural_size(node->v.p[0]);
  2366. int sz2 = natural_size(node->v.p[0]);
  2367. int psize;
  2368. if (sz1 < 0)  sz1 = - sz1;
  2369. if (sz2 < 0)  sz2 = - sz2;
  2370. psize = sz2 > sz1 ? sz2 : sz1;
  2371. if (psize < 2) psize = 2;
  2372. if (op == op_muls)  psize = -psize;
  2373.         siz1 = natural_size(node->v.p[0]);
  2374. if (siz1 > 4) {
  2375. ap1 = gen_expr(node->v.p[0],F_ALL&~F_AREG,siz1);
  2376. ap3 = xalloc(sizeof(AMODE));
  2377. ap3->mode = ap1->mode;
  2378. ap3->preg = ap1->preg;
  2379. ap3->sreg = ap1->sreg;
  2380. ap3->offset = ap1->offset;
  2381. make_legal(ap1,F_FREG,siz1);
  2382. mark();
  2383. ap2 = gen_expr(node->v.p[1],F_ALL&~F_AREG,siz1);
  2384. gen_codef(op_fdiv,siz1,ap2,ap1);
  2385. make_legal(ap1,flags,size);
  2386. if (ap3->mode != am_freg)
  2387. gen_codef(op_fmove,siz1,ap1,ap3);
  2388. freeop(ap2);
  2389. release();
  2390. return(ap1);
  2391. }
  2392. if (prm_68020 || psize == 2 || psize == -2) {
  2393. if (psize !=2 && psize != -2)
  2394. if (op == op_divs) 
  2395. op = op_divsl;
  2396. else
  2397. op = op_divul;
  2398.          ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,0);
  2399. ap5 = xalloc(sizeof(AMODE));
  2400. ap5->mode = ap1->mode;
  2401. ap5->preg = ap1->preg;
  2402. ap5->sreg = ap1->sreg;
  2403. ap5->offset = ap1->offset;
  2404. if (node->v.p[0]->nodetype == en_bits)
  2405. ap1 = get_bitval(ap1,node->v.p[0],siz1);
  2406. do_extend(ap1,siz1, psize == 2 ? 4 : -4,F_DREG | F_VOL);
  2407. make_legal(ap1,F_DREG | F_VOL,psize == 2 ? 4 : -4);
  2408. mark();
  2409.         ap3 = gen_expr(node->v.p[1],F_ALL & ~F_AREG,psize);
  2410. if (psize != 2 && psize != -2) {
  2411. ap4 = temp_data();
  2412. ap4->tempflag = TRUE;
  2413. temp = ap4->preg;
  2414.           if( modflag ) {
  2415. gen_code(op_move,4,ap1,ap4);
  2416. ap4->sreg = ap1->preg;
  2417. }
  2418. else {
  2419. ap4->sreg = ap4->preg = ap1->preg;
  2420. }
  2421. ap4->mode = am_divsl;
  2422. gen_code(op,psize,ap3,ap4);
  2423. ap4->mode = am_dreg;
  2424. ap4->preg = temp;
  2425. freeop(ap4);
  2426.           freeop(ap3);
  2427.          release();
  2428. }
  2429. else {
  2430. gen_code(op,psize,ap3,ap1);
  2431. if (modflag) {
  2432. gen_code(op_swap,2,ap1,0);
  2433. }
  2434. freeop(ap3);
  2435. }
  2436. if (node->v.p[0]->nodetype == en_bits)
  2437. bit_move(ap1,ap5,node->v.p[0],flags,psize,size);
  2438. else
  2439.           gen_code(op_move,siz1,ap1,ap5);
  2440. if (flags & F_NOVALUE)
  2441. freeop(ap1);
  2442. else {
  2443.        do_extend(ap1,psize,size,0);
  2444.          make_legal(ap1,flags,size);
  2445. }
  2446.          freeop(ap2);
  2447.         return ap1;
  2448. }
  2449. flush_for_libcall();
  2450. if (op == op_divs) {
  2451.          ap1 = gen_expr(node->v.p[1],F_ALL,-4);
  2452. }
  2453. else {
  2454.          ap1 = gen_expr(node->v.p[1],F_ALL,4);
  2455. }
  2456. ap4 = xalloc(sizeof(AMODE));
  2457.         ap2 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,siz1);
  2458. ap4->mode = ap2->mode;
  2459. ap4->preg = ap2->preg;
  2460. ap4->sreg = ap2->sreg;
  2461. ap4->tempflag = ap2->tempflag;
  2462. ap4->offset = ap2->offset;
  2463. if (node->v.p[0]->nodetype == en_bits)
  2464. ap2 = get_bitval(ap2,node->v.p[0],siz1);
  2465. if (op == op_divs) {
  2466. do_extend(ap2,siz1, - 4,F_ALL);
  2467. }
  2468. else {
  2469. do_extend(ap2,siz1, 4,F_ALL);
  2470. }
  2471. gen_code(op_move,4,ap2,push);
  2472. gen_code(op_move,4,ap1,push);
  2473.         freeop(ap2);
  2474. freeop(ap1);
  2475. if (modflag)
  2476. if (op == op_divs)
  2477. ap1=call_library("__mods",8);
  2478. else
  2479. ap1=call_library("__modu",8);
  2480. else
  2481. if (op == op_divs)
  2482. ap1=call_library("__divs",8);
  2483. else
  2484. ap1=call_library("__divu",8);
  2485. make_legal(ap1,flags,size);
  2486. if (node->v.p[0]->nodetype == en_bits)
  2487. bit_move(ap1,ap4,node->v.p[0],flags,siz1,size);
  2488. else
  2489.          gen_code(op_move,siz1,ap1,ap4);
  2490. if (flags & F_NOVALUE)
  2491. freeop(ap1);
  2492. else {
  2493.       do_extend(ap1,siz1,size,0);
  2494.         make_legal(ap1,flags,size);
  2495. }
  2496. freeop(ap4);
  2497.         return ap1;
  2498. }
  2499. AMODE *gen_moveblock(ENODE *node, int flags, int size)
  2500. {
  2501. AMODE *ap1, *ap2, *ap3;
  2502. int lbl;
  2503. long v,tp,sz;
  2504. if (!(sz=node->size))
  2505. return(0);
  2506. if (sz & 1) {
  2507. tp = 1;
  2508. }
  2509. else if (sz & 2) {
  2510. tp = 2;
  2511. }
  2512. else {
  2513. tp = 4;
  2514. }
  2515. v = sz/tp;
  2516. if (v < 65536)
  2517. v--;
  2518. lbl = nextlabel++;
  2519. ap2 = gen_expr(node->v.p[0], F_AREG | F_VOL, 4);
  2520. mark();
  2521. ap3 = gen_expr(node->v.p[1], F_AREG | F_VOL,4);
  2522. ap1 = temp_data();
  2523. ap2->mode = am_ainc;
  2524. ap3->mode = am_ainc;
  2525. gen_code(op_move,v < 65536 ? 2 : 4,make_immed(v),ap1);
  2526. gen_label(lbl);
  2527. gen_code(op_move,tp,ap3,ap2);
  2528. if (v < 65536) 
  2529. gen_code(op_dbra,0,ap1,make_label(lbl));
  2530. else {
  2531. gen_code(op_sub,4,make_immed(1),ap1);
  2532. gen_code(op_bne,0,make_label(lbl),0);
  2533. }
  2534. freeop(ap3);
  2535. freeop(ap1);
  2536. freeop(ap2);
  2537. return(ap2);
  2538. release();
  2539. }
  2540. int count_regs(AMODE *ap1, AMODE *ap2)
  2541. {
  2542. int r = 0;
  2543. switch(ap1->mode) {
  2544. case am_baseindxaddr:
  2545. if (ap1->sreg < cf_freeaddress && ap1->sreg != -1)
  2546. r++;
  2547. case am_baseindxdata:
  2548. case am_ind:
  2549. case am_indx:
  2550. case am_areg:
  2551. if (ap1->preg < cf_freeaddress && ap1->preg != -1)
  2552. r++;
  2553. break;
  2554. }
  2555. switch(ap2->mode) {
  2556. case am_baseindxaddr:
  2557. if (ap2->sreg < cf_freeaddress && ap2->sreg != -1)
  2558. r++;
  2559. case am_baseindxdata:
  2560. case am_ind:
  2561. case am_indx:
  2562. case am_areg:
  2563. if (ap2->preg < cf_freeaddress && ap2->preg != -1)
  2564. r++;
  2565. break;
  2566. }
  2567. return r;
  2568. }
  2569. AMODE    *gen_assign(ENODE *node, int flags, int size)
  2570. /*
  2571.  *      generate code for an assignment node. if the size of the
  2572.  *      assignment destination is larger than the size passed then
  2573.  *      everything below this node will be evaluated with the
  2574.  *      assignment size.
  2575.  */
  2576. {       AMODE    *ap1, *ap2,*ap3;
  2577.         int             ssize,rsize;
  2578. int q = node->v.p[0]->nodetype;
  2579. rsize = natural_size(node->v.p[1]);
  2580. if (q == en_bits)
  2581. q = node->v.p[0]->v.p[0]->nodetype;
  2582.         switch( q )        
  2583.                 {
  2584. case en_bits:
  2585. ssize = natural_size(node->v.p[0]);
  2586. break;
  2587.                 case en_ub_ref:
  2588. case en_cub:
  2589.                         ssize = 1;
  2590.                         break;
  2591.                 case en_b_ref:
  2592. case en_cb:
  2593.                         ssize = -1;
  2594.                         break;
  2595.                 case en_uw_ref:
  2596. case en_cuw:
  2597.                         ssize = 2;
  2598.                         break;
  2599.                 case en_w_ref:
  2600. case en_cw:
  2601.                         ssize = -2;
  2602.                         break;
  2603.                 case en_l_ref:
  2604. case en_cl:
  2605. ssize = -4;
  2606. break;
  2607.                 case en_ul_ref:
  2608. case en_cul:
  2609. case en_cp:
  2610.                         ssize = 4;
  2611.                         break;
  2612.                 case en_tempref:
  2613.                 case en_regref:
  2614. ssize = node->v.p[0]->v.i >> 8;
  2615. break;
  2616. case en_floatref:
  2617. case en_cf:
  2618. ssize = 6;
  2619. break;
  2620. case en_doubleref:
  2621. case en_cd:
  2622. ssize = 8;
  2623. break;
  2624. case en_longdoubleref:
  2625. case en_cld:
  2626. ssize = 10;
  2627. break;
  2628.                 }
  2629.         if (chksize( size , rsize ))
  2630.                 rsize = size;
  2631.         ap2 = gen_expr(node->v.p[1],F_DREG | F_FREG | F_IMMED,rsize);
  2632. do_extend(ap2,rsize,ssize,flags);
  2633. mark();
  2634.         ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,ssize);
  2635. if (ssize > 4) {
  2636. gen_codef(op_fmove,ssize,ap2,ap1);
  2637. }
  2638. else {
  2639. if (node->v.p[0]->nodetype ==en_bits)
  2640. bit_move(ap2,ap1,node->v.p[0],flags,ssize,size);
  2641. else
  2642.          gen_code(op_move,ssize,ap2,ap1);
  2643. }
  2644. freeop(ap1);
  2645. release();
  2646. if (flags & F_NOVALUE) 
  2647. freeop(ap2);
  2648. else {
  2649. do_extend(ap2,ssize,size,flags);
  2650. make_legal(ap2,flags,size);
  2651. }
  2652.         return ap2;
  2653. }
  2654. AMODE    *gen_refassign(ENODE *node, int flags, int size)
  2655. /*
  2656.  *      generate code for an assignment node. if the size of the
  2657.  *      assignment destination is larger than the size passed then
  2658.  *      everything below this node will be evaluated with the
  2659.  *      assignment size.
  2660.  */
  2661. {       AMODE    *ap1, *ap2,*ap4;
  2662.         int             ssize,rsize;
  2663. int q = node->v.p[0]->nodetype;
  2664. rsize = natural_size(node->v.p[1]);
  2665. if (q == en_bits)
  2666. q = node->v.p[0]->v.p[0]->nodetype;
  2667.         switch( q )        
  2668.                 {
  2669. case en_bits:
  2670. ssize = natural_size(node->v.p[0]);
  2671. break;
  2672.                 case en_ub_ref:
  2673. case en_cub:
  2674.                         ssize = 1;
  2675.                         break;
  2676.                 case en_b_ref:
  2677. case en_cb:
  2678.                         ssize = -1;
  2679.                         break;
  2680.                 case en_uw_ref:
  2681. case en_cuw:
  2682.                         ssize = 2;
  2683.                         break;
  2684.                 case en_w_ref:
  2685. case en_cw:
  2686.                         ssize = -2;
  2687.                         break;
  2688.                 case en_l_ref:
  2689. case en_cl:
  2690. ssize = -4;
  2691. break;
  2692.                 case en_ul_ref:
  2693. case en_cul:
  2694. case en_cp:
  2695.                         ssize = 4;
  2696.                         break;
  2697.                 case en_tempref:
  2698.                 case en_regref:
  2699. ssize = node->v.p[0]->v.i >> 8;
  2700. break;
  2701. case en_floatref:
  2702. case en_cf:
  2703. ssize = 6;
  2704. break;
  2705. case en_doubleref:
  2706. case en_cd:
  2707. ssize = 8;
  2708. break;
  2709. case en_longdoubleref:
  2710. case en_cld:
  2711. ssize = 10;
  2712. break;
  2713.                 }
  2714.         if (chksize( size , rsize ))
  2715.                 rsize = size;
  2716.         ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,ssize);
  2717. mark();
  2718.         ap2 = gen_expr(node->v.p[1],F_ALL,rsize);
  2719. ap4 = xalloc(sizeof(AMODE));
  2720. ap4->mode = am_ind;
  2721. ap4->preg = ap1->preg;
  2722. make_legal(ap2,flags,ssize);
  2723. if (ssize > 4) {
  2724. if (ap1->mode != am_freg && ap2->mode != am_freg) {
  2725. AMODE *ap3 = temp_float();
  2726. gen_codef(op_fmove,ssize,ap2,ap3);
  2727.          gen_codef(op_fmove,ssize,ap3,ap4);
  2728. freeop(ap1);
  2729. freeop(ap2);
  2730. return(ap3);
  2731. }
  2732. else 
  2733. gen_codef(op_fmove,ssize,ap2,ap4);
  2734. }
  2735. else
  2736. if (node->v.p[0]->nodetype ==en_bits)
  2737. bit_move(ap2,ap4,node->v.p[0],flags,ssize,size);
  2738. else
  2739.          gen_code(op_move,ssize,ap2,ap4);
  2740. freeop(ap2);
  2741. release();
  2742. do_extend(ap1,ssize,size,flags);
  2743. make_legal(ap1,flags,size);
  2744.         return ap1;
  2745. }
  2746. AMODE    *gen_aincdec(ENODE *node, int flags, int size, int op)
  2747. /*
  2748.  *      generate an auto increment or decrement node. op should be
  2749.  *      either op_add (for increment) or op_sub (for decrement).
  2750.  */
  2751. {       AMODE    *ap1, *ap2, *ap3;
  2752.         int             siz1;
  2753.         siz1 = natural_size(node->v.p[0]);
  2754.         if( flags & F_NOVALUE )         /* dont need result */
  2755.                 {
  2756.          ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,siz1);
  2757. if (node->v.p[0]->nodetype == en_bits) {
  2758. ap2 = get_bitval(ap1,node->v.p[0],siz1);
  2759. gen_code(op,siz1,make_immed(1),ap2);
  2760. bit_move(ap2,ap1,node->v.p[0],flags,siz1,size);
  2761. }
  2762. else {
  2763.                  gen_code(op,siz1,make_immed((long)node->v.p[1]),ap1);
  2764. }
  2765.                 freeop(ap1);
  2766.                 return ap1;
  2767.                 }
  2768. if (flags & F_DREG)
  2769. ap3 = temp_data();
  2770. else if (flags & F_AREG)
  2771. ap3 = temp_addr();
  2772. ap3->tempflag = 1;
  2773.         ap1 = gen_expr(node->v.p[0],F_ALL | F_NOBIT,siz1);
  2774. if (node->v.p[0]->nodetype == en_bits) {
  2775. ap2 = get_bitval(ap1,node->v.p[0],siz1);
  2776. gen_code(op_move,siz1,ap2,ap3);
  2777. gen_code(op,siz1,make_immed(1),ap2);
  2778. bit_move(ap2,ap1,node->v.p[0],flags,siz1,size);
  2779.          do_extend(ap3,siz1,size,0);
  2780. make_legal(ap3,flags,size);
  2781. freeop(ap2);
  2782. }
  2783. else {
  2784. if (siz1 <=4 && ap1->mode == am_areg && ap1->preg >= cf_freeaddress && op == op_add) {
  2785. if (op == op_add) {
  2786. freeop(ap3);
  2787. ap3 = ap1;
  2788. ap3->mode = am_ainc;
  2789. flags |= F_INDX;
  2790. }
  2791. }
  2792. else {
  2793. gen_code(op_move,siz1,ap1,ap3);
  2794.              gen_code(op,siz1,make_immed((long)node->v.p[1]),ap1);
  2795. freeop(ap1);
  2796. }
  2797. }
  2798.         do_extend(ap3,siz1,size,0);
  2799. make_legal(ap3,flags,size);
  2800.         return ap3;
  2801. }
  2802. int push_param(ENODE *ep,int size)
  2803. /*
  2804.  *      push the operand expression onto the stack.
  2805.  */
  2806. {       AMODE    *ap,*ap1;
  2807. int rv;
  2808. switch (ep->nodetype) {
  2809.                 case en_napccon:
  2810. ep->v.p[0] = ((SYM *)ep->v.p[0])->name;
  2811.                 case en_labcon:
  2812.                         ap = xalloc(sizeof(AMODE));
  2813. if (prm_rel)
  2814.                   ap->mode = am_pcindx;
  2815. else {
  2816. ap->mode = am_adirect;
  2817. if (prm_smallcode)
  2818. ap->preg = 2;
  2819. else
  2820. ap->preg = 4;
  2821. }
  2822.                         ap->offset = ep;     /* use as constant node */
  2823.                         gen_code(op_pea,0,ap,0);
  2824. rv = 4;
  2825. break;
  2826. case en_absacon:
  2827.                         ap = xalloc(sizeof(AMODE));
  2828.                         ap->mode = am_adirect;
  2829. ep->v.i = ((SYM *)ep->v.p[0])->value.i;
  2830. ap->preg = isshort(ep) ? 2 : 4;
  2831.                         ap->offset = ep;     /* use as constant node */
  2832.                         gen_code(op_pea,0,ap,0);
  2833. rv = 4;
  2834. break;
  2835.                 case en_nacon:
  2836. ep->v.p[0] = ((SYM *)ep->v.p[0])->name;
  2837. case en_nalabcon:
  2838.                         ap = xalloc(sizeof(AMODE));
  2839. if (prm_rel) {
  2840.                         ap->preg = basereg;          /* frame pointer */
  2841. if (prm_largedata) {
  2842. ap1 = temp_addr();
  2843. ap->mode = am_areg;
  2844. gen_code(op_move,4,ap,ap1);
  2845. ap->mode = am_immed;
  2846. ap->offset = ep;
  2847. gen_code(op_add,4,ap,ap1);
  2848. ap = ap1;
  2849. ap->mode = am_ind;
  2850.                           gen_code(op_move,4,ap,push);
  2851.     ap->mode = am_areg;
  2852. freeop(ap);
  2853. }
  2854. else {
  2855.                          ap->mode = am_indx;
  2856.                          ap->offset = ep;     /* use as constant node */
  2857. gen_code(op_pea,0,ap,0);
  2858. }
  2859. }
  2860. else {
  2861. ap->mode = am_adirect;
  2862.                ap->offset = ep;
  2863. if (prm_smalldata) {
  2864. ap->preg = 2;
  2865. }
  2866. else {
  2867. ap->preg = 4;
  2868. }
  2869.   gen_code(op_pea,0,ap,0);
  2870. }
  2871. rv = 4;
  2872. break;
  2873. case en_cf:
  2874. case en_floatref:
  2875. ap = gen_expr(ep,F_FREG|F_INDX,6);
  2876. if (ap->mode == am_freg)
  2877. gen_codef(op_fmove,6,ap,push);
  2878. else
  2879. gen_code(op_move,4,ap,push);
  2880. rv = 4;
  2881. break;
  2882. case en_cd:
  2883. case en_doubleref:
  2884. ap = gen_expr(ep,F_FREG,8);
  2885. gen_codef(op_fmove,8,ap,push);
  2886. rv = 8;
  2887. break;
  2888. case en_cld:
  2889. case en_longdoubleref:
  2890. ap = gen_expr(ep,F_FREG,8);
  2891. gen_codef(op_fmove,10,ap,push);
  2892. rv = 8;
  2893. break;
  2894. case en_rcon:
  2895. case en_fcon:
  2896. case en_lrcon:
  2897. gen_codef(op_fmove,size,ap,push);
  2898. rv = size;
  2899. break;
  2900. default:
  2901. rv = 4;
  2902.           ap = gen_expr(ep,F_ALL,4);
  2903. if (ap->mode == am_freg)
  2904. gen_codef(op_fmove,4,ap,push);
  2905. else
  2906. gen_code(op_move,4,ap,push);
  2907. break;
  2908. }
  2909.         freeop(ap);
  2910. stackdepth += rv;
  2911. return(rv);
  2912. }
  2913. int push_stackblock(ENODE *ep)
  2914. {
  2915. AMODE *ap, *ap1, *ap2;
  2916. int lbl;
  2917. long sz = ep->size, tp;
  2918. long v;
  2919. if (!sz)
  2920. return(0);
  2921. if (sz & 1) {
  2922. tp = 1;
  2923. }
  2924. else if (sz & 2) {
  2925. tp = 2;
  2926. }
  2927. else {
  2928. tp = 4;
  2929. }
  2930. switch (ep->nodetype) {
  2931.                 case en_napccon:
  2932. ep->v.p[0] = ((SYM *)ep->v.p[0])->name;
  2933.                 case en_labcon:
  2934.                         ap = xalloc(sizeof(AMODE));
  2935. if (prm_rel)
  2936.                   ap->mode = am_pcindx;
  2937. else {
  2938. ap->mode = am_adirect;
  2939. if (prm_smallcode)
  2940. ap->preg = 2;
  2941. else
  2942. ap->preg = 4;
  2943. }
  2944.                         ap->offset = makenode(en_add,ep,makenode(en_icon,(char *)sz,0));     /* use as constant node */
  2945.                         gen_lea(0,ap,ap2 = temp_addr());
  2946. break;
  2947. case en_absacon:
  2948. ep->v.i = ((SYM *)ep->v.p[0])->value.i;
  2949.                         ap = xalloc(sizeof(AMODE));
  2950.                         ap->mode = am_adirect;
  2951. ap->preg = isshort(ep) ? 2 : 4;
  2952.                         ap->offset = makenode(en_add,ep,makenode(en_icon,(char *)sz,0));     /* use as constant node */
  2953.                         gen_lea(0,ap,ap2 = temp_addr());
  2954. break;
  2955.                 case en_nacon:
  2956. ep->v.p[0] = ((SYM *)ep->v.p[0])->name;
  2957. case en_nalabcon:
  2958. ap1 = 0;
  2959.                         ap = xalloc(sizeof(AMODE));
  2960. if (prm_rel) {
  2961.                         ap->preg = basereg;          /* frame pointer */
  2962. if (prm_largedata) {
  2963. ap1 = temp_addr();
  2964. ap->mode = am_areg;
  2965. gen_code(op_move,4,ap,ap1);
  2966. ap->mode = am_immed;
  2967. ap->offset = ep;
  2968. gen_code(op_add,4,ap,ap1);
  2969. ap = ap1;
  2970. ap->mode = am_ind;
  2971. }
  2972. else {
  2973.                          ap->mode = am_indx;
  2974.                          ap->offset = ep;     /* use as constant node */
  2975. }
  2976. }
  2977. else {
  2978. ap->mode = am_adirect;
  2979.                ap->offset = ep;
  2980. if (prm_smalldata) {
  2981. ap->preg = 2;
  2982. }
  2983. else {
  2984. ap->preg = 4;
  2985. }
  2986. }
  2987.                         ap->offset = makenode(en_add,ep,makenode(en_icon,(char *)sz,0));     /* use as constant node */
  2988.                         gen_lea(0,ap,ap2=temp_addr());
  2989. if (ap1) {
  2990. ap1->mode = am_areg;
  2991. freeop(ap1);
  2992. }
  2993. break;
  2994.                 case en_autocon:
  2995.                 case en_autoreg:
  2996. ep->v.i = ((SYM *)ep->v.p[0])->value.i;
  2997.                         ap = xalloc(sizeof(AMODE));
  2998.                         ap->mode = am_indx;
  2999. if (prm_linkreg && !currentfunc->intflag) {
  3000.                  ap->preg = linkreg;
  3001.                          ap->offset = makenode(en_add,ep,makenode(en_icon,(char *)sz,0));     /* use as constant node */
  3002. }
  3003.   else if (((SYM *)ep->v.p[0])->funcparm ) {
  3004. if (prm_phiform || currentfunc->intflag) {
  3005.                          ap->preg = linkreg;          /* frame pointer */
  3006.                          ap->offset = makenode(en_add,ep,makenode(en_icon,(char *)sz,0));     /* use as constant node */
  3007. }
  3008. else {
  3009. ap->preg = 7;
  3010.                          ap->offset = makenode(en_add,ep,makenode(en_icon,(char *)(sz+stackdepth+framedepth),0));     /* use as constant node */
  3011. }
  3012.                  }
  3013. else {
  3014. ap->preg = 7;
  3015.                          ap->offset = makenode(en_add,ep,makenode(en_icon,(char *)(sz+stackdepth+lc_maxauto),0));     /* use as constant node */
  3016. }
  3017.                         gen_lea(0,ap,ap2 = temp_addr());
  3018. break;
  3019. default:
  3020. ap = 0;
  3021.           ap2 = gen_expr(ep,F_AREG | F_VOL,4);
  3022. gen_code(op_add,4,make_immed(sz),ap2);
  3023. break;
  3024. }
  3025. lbl = nextlabel++;
  3026. ap1 = temp_data();
  3027.   v = sz/tp;
  3028. if (v < 65536)
  3029. v--;
  3030. gen_code(op_move,v < 65536 ? 2 : 4,make_immed(v),ap1);
  3031. gen_label(lbl);
  3032. ap2->mode = am_adec;
  3033. gen_code(op_move,tp,ap2,push);
  3034. if (v < 65536) {
  3035. gen_code(op_dbra,0,ap1,make_label(lbl));
  3036. }
  3037. else {
  3038. gen_code(op_sub,4,make_immed(1),ap1);
  3039. gen_code(op_bne,0,make_label(lbl),0);
  3040. }
  3041. freeop(ap1);
  3042. freeop(ap2);
  3043. if (ap)
  3044.    freeop(ap);
  3045. stackdepth += sz;
  3046. return(sz);
  3047. }
  3048. int     gen_parms(ENODE *plist,int size)
  3049. /*
  3050.  *      push a list of parameters onto the stack and return the
  3051.  *      size of parameters pushed.
  3052.  */
  3053. {       int     i;
  3054.         i = 0;
  3055.         while( plist != 0 )
  3056.                 {         
  3057. if (plist->nodetype == en_stackblock)
  3058. i+=push_stackblock(plist->v.p[0]);
  3059. else
  3060.                  i+=push_param(plist->v.p[0],size);
  3061.                 plist = plist->v.p[1];
  3062.                 }
  3063.         return i;
  3064. }
  3065. AMODE    *gen_fcall(ENODE *node,int flags, int size)
  3066. /*
  3067.  *      generate a function call node and return the address mode
  3068.  *      of the result.
  3069.  */
  3070. {       AMODE    *ap, *result, *ap1;
  3071.         int             i,siz1;
  3072.         result = temp_addr();
  3073.         temp_addr();                    /* push any used addr temps */
  3074.         freeop(result); freeop(result);
  3075.         result = temp_data();
  3076.         temp_data(); temp_data();      /* push any used data registers */
  3077.         freeop(result); freeop(result); freeop(result);
  3078. result = temp_float();  temp_float(); temp_float();
  3079.         freeop(result); freeop(result); freeop(result);
  3080. if (node->nodetype == en_callblock) {
  3081. i = gen_parms(node->v.p[1]->v.p[1]->v.p[1]->v.p[0],size);
  3082.        ap = gen_expr(node->v.p[0],F_ALL,4);
  3083. gen_code(op_move,4,ap,push);
  3084. i+=4;
  3085. stackdepth+=4;
  3086. node=node->v.p[1];
  3087. freeop(ap);
  3088. siz1 = 4;
  3089. }
  3090. else {
  3091.         i = gen_parms(node->v.p[1]->v.p[1]->v.p[0],size);    /* generate parameters */
  3092. siz1 = node->v.p[0]->v.i;
  3093. }
  3094. if ((prm_phiform || node->nodetype == en_trapcall || node->nodetype == en_intcall) && i)
  3095. gen_code(op_move,4,makeareg(7),makeareg(0));
  3096. if (node->nodetype == en_trapcall) {
  3097. gen_code(op_trap,0,make_immed(node->v.p[1]->v.p[0]->v.i),0);
  3098. }
  3099. else if (node->nodetype == en_intcall) {
  3100. /* This is one case where we can generate code that will run
  3101.  * on a 68000 but not on a 68020 or vice versa*/
  3102. int curlabel = nextlabel++;
  3103. DIAG("Direct calls to interrups not portable across processors");
  3104. if (prm_68020) {
  3105. gen_code(op_clr,2,push,0);
  3106. }
  3107. else
  3108. ap1 = make_label(curlabel);
  3109. if (prm_rel)
  3110.      ap1->mode = am_pcindx;
  3111. else {
  3112. ap1->mode = am_adirect;
  3113.   if (prm_smallcode)
  3114. ap1->preg = 2;
  3115. else
  3116. ap1->preg = 4;
  3117. }
  3118. gen_code(op_pea,4,ap1,0);
  3119. ap1 = xalloc(sizeof(AMODE));
  3120. ap1->mode = am_sr;
  3121. gen_code(op_move,2,ap1,push); /* May cause an exception on an 020 */
  3122. gen_code(op_bra,0,make_offset(node->v.p[1]->v.p[0]),0);
  3123. gen_label(curlabel);
  3124. freeop(ap1);
  3125. }
  3126.         else if( node->v.p[1]->v.p[0]->nodetype == en_nacon || node->v.p[1]->v.p[0]->nodetype == en_napccon ) {
  3127. SYM * sp = node->v.p[1]->v.p[0]->v.p[0];
  3128. if (sp->inreg) {
  3129. if (sp->value.i < 8)
  3130. ap1 = makedreg(sp->value.i);
  3131. else
  3132. ap1 = makeareg(sp->value.i & 7);
  3133. make_legal(ap1,F_AREG,size);
  3134. ap1->mode = am_ind;
  3135. gen_code(op_jsr,0,ap1,0);
  3136. }
  3137. else {
  3138. node->v.p[1]->v.p[0]->v.p[0] = sp->name;
  3139. if (prm_rel)
  3140.              gen_code(op_bsr,0,make_offset(node->v.p[1]->v.p[0]),0);
  3141. else {
  3142. ap1 = xalloc(sizeof(AMODE));
  3143. ap1->mode = am_adirect;
  3144.            ap1->offset = node->v.p[1]->v.p[0];
  3145. if (prm_smallcode) {
  3146. ap1->preg = 2;
  3147. }
  3148. else {
  3149. ap1->preg = 4;
  3150. }
  3151. gen_code(op_jsr,0,ap1,0);
  3152. }
  3153. }
  3154.     }
  3155.         else
  3156.                 {
  3157.                 ap = gen_expr(node->v.p[1]->v.p[0],F_AREG,4);
  3158. ap->mode = am_ind;
  3159.                 freeop(ap);
  3160.                 gen_code(op_jsr,0,ap,0);
  3161.                 }
  3162.         if( i != 0 ) {
  3163. if (i > 8) {
  3164. AMODE *ap = xalloc(sizeof(AMODE)); 
  3165. ap->mode = am_indx;
  3166. ap->offset = makenode(en_icon,(char *)i,0);
  3167. ap->preg = 7;
  3168.                  gen_lea(0,ap,makeareg(7));
  3169. }
  3170. else
  3171.                  gen_code(op_add,4,make_immed(i),makeareg(7));
  3172. stackdepth -= i;
  3173. }
  3174. if (siz1 > 4) {
  3175. result = temp_float();
  3176. if (result->preg != 0)
  3177. gen_codef(op_fmove,8,makefreg(0),result);
  3178. }
  3179. else {
  3180.           result = temp_data();
  3181.          if( result->preg != 0)
  3182.                 gen_code(op_move,4,makedreg(0),result);
  3183. }
  3184. result->tempflag = 1;
  3185. do_extend(result,siz1,size,flags);
  3186. make_legal(result,flags,size);
  3187.         return result;
  3188. }
  3189. AMODE    *gen_pfcall(ENODE *node,int flags, int size)
  3190. /*
  3191.  *      generate a function call node for pascal function calls
  3192. * and return the address mode of the result.
  3193.  */
  3194. {       AMODE    *ap, *result, *ap1;
  3195.         int             i,siz1;
  3196. ENODE * invnode = 0,*anode;
  3197. /* invert the parameter list */
  3198. if (node->nodetype == en_pcallblock)
  3199. anode = node->v.p[1]->v.p[1]->v.p[1]->v.p[0];
  3200. else
  3201. anode = node->v.p[1]->v.p[1]->v.p[0];
  3202. while (anode) {
  3203. invnode = makenode(anode->nodetype,anode->v.p[0],invnode);
  3204. anode = anode->v.p[1];
  3205. }
  3206.         result = temp_addr();
  3207.         temp_addr();                    /* push any used addr temps */
  3208.         freeop(result); freeop(result);
  3209.         result = temp_data();
  3210.         temp_data(); temp_data();      /* push any used data registers */
  3211.         freeop(result); freeop(result); freeop(result);
  3212. result = temp_float();  temp_float(); temp_float();
  3213.         freeop(result); freeop(result); freeop(result);
  3214. if (node->nodetype == en_pcallblock) {
  3215.        ap = gen_expr(node->v.p[0],F_ALL,4);
  3216. gen_code(op_move,4,ap,push);
  3217. freeop(ap);
  3218. i =4;
  3219. stackdepth+=4;
  3220. i += gen_parms(invnode,size);
  3221. node=node->v.p[1];
  3222. siz1 = 4;
  3223. }
  3224. else {
  3225.         i = gen_parms(invnode,size);    /* generate parameters */
  3226. siz1 = node->v.p[0]->v.i;
  3227. }
  3228. if ((prm_phiform || node->nodetype == en_trapcall || node->nodetype == en_intcall) && i)
  3229. gen_code(op_move,4,makeareg(7),makeareg(0));
  3230.         if( node->v.p[1]->v.p[0]->nodetype == en_nacon || node->v.p[1]->v.p[0]->nodetype == en_napccon ) {
  3231. SYM * sp = node->v.p[1]->v.p[0]->v.p[0];
  3232. if (sp->inreg) {
  3233. if (sp->value.i < 8)
  3234. ap1 = makedreg(sp->value.i);
  3235. else
  3236. ap1 = makeareg(sp->value.i & 7);
  3237. make_legal(ap1,F_AREG,size);
  3238. ap1->mode = am_ind;
  3239. gen_code(op_jsr,0,ap1,0);
  3240. }
  3241. else {
  3242. node->v.p[1]->v.p[0]->v.p[0] = sp->name;
  3243. if (prm_rel)
  3244.              gen_code(op_bsr,0,make_offset(node->v.p[1]->v.p[0]),0);
  3245. else {
  3246. ap1 = xalloc(sizeof(AMODE));
  3247. ap1->mode = am_adirect;
  3248.            ap1->offset = node->v.p[1]->v.p[0];
  3249. if (prm_smallcode) {
  3250. ap1->preg = 2;
  3251. }
  3252. else {
  3253. ap1->preg = 4;
  3254. }
  3255. gen_code(op_jsr,0,ap1,0);
  3256. }
  3257. }
  3258.     }
  3259.         else
  3260.                 {
  3261.                 ap = gen_expr(node->v.p[1]->v.p[0],F_AREG,4);
  3262. ap->mode = am_ind;
  3263.                 freeop(ap);
  3264.                 gen_code(op_jsr,0,ap,0);
  3265.                 }
  3266. stackdepth -= i;
  3267. if (siz1 > 4) {
  3268. result = temp_float();
  3269. if (result->preg != 0)
  3270. gen_codef(op_fmove,8,makefreg(0),result);
  3271. }
  3272. else {
  3273.           result = temp_data();
  3274.          if( result->preg != 0)
  3275.                 gen_code(op_move,4,makedreg(0),result);
  3276. }
  3277. result->tempflag = 1;
  3278. do_extend(result,siz1,size,flags);
  3279. make_legal(result,flags,size);
  3280.         return result;
  3281. }
  3282. AMODE    *gen_expr(ENODE *node, int flags, int size)
  3283. /*
  3284.  *      general expression evaluation. returns the addressing mode
  3285.  *      of the result.
  3286.  */
  3287. {
  3288. AMODE    *ap1, *ap2;
  3289.         int             lab0, lab1;
  3290.         int             natsize;
  3291.         if( node == 0 )
  3292.                 {
  3293.                 DIAG("null node in gen_expr.");
  3294.                 return 0;
  3295.                 }
  3296.         switch( node->nodetype )
  3297.                 {
  3298. case en_cb: 
  3299. case en_cub:
  3300. case en_cw: 
  3301. case en_cuw:
  3302. case en_cl: 
  3303. case en_cul:
  3304. case en_cf: 
  3305. case en_cd: 
  3306. case en_cld: 
  3307. case en_cp:
  3308. ap1 = gen_expr(node->v.p[0],flags | F_INDX | F_DREG | F_FREG,natural_size(node->v.p[0]));
  3309.                  do_extend(ap1,natural_size(node->v.p[0]),size,flags);
  3310. make_legal(ap1,flags,size);
  3311. return ap1;
  3312.                 case en_napccon:
  3313. node->v.p[0] = ((SYM *)node->v.p[0])->name;
  3314.                 case en_labcon:
  3315.                         ap1 = temp_addr();
  3316. ap1->tempflag = TRUE;
  3317.                         ap2 = xalloc(sizeof(AMODE));
  3318. if (prm_rel)
  3319.      ap2->mode = am_pcindx;
  3320. else {
  3321. ap2->mode = am_adirect;
  3322.   if (prm_smallcode)
  3323. ap2->preg = 2;
  3324. else
  3325. ap2->preg = 4;
  3326. }
  3327.                         ap2->offset = node;     /* use as constant node */
  3328.                         gen_lea(0,ap2,ap1);
  3329.                         make_legal(ap1,flags,size);
  3330.                         return ap1;             /* return reg */
  3331. case en_absacon:
  3332. node->v.i = ((SYM *)node->v.p[0])->value.i;
  3333.                         ap1 = temp_addr();
  3334. ap1->tempflag = TRUE;
  3335.                         ap2 = xalloc(sizeof(AMODE));
  3336.                         ap2->mode = am_adirect;
  3337. ap2->preg = isshort(node) ? 2 : 4;
  3338.                         ap2->offset = node;     /* use as constant node */
  3339.                         gen_lea(0,ap2,ap1);
  3340.                         make_legal(ap1,flags,size);
  3341.                         return ap1;             /* return reg */
  3342.                 case en_nacon:
  3343. node->v.p[0] = ((SYM *)node->v.p[0])->name;
  3344. case en_nalabcon:
  3345.                       ap1 = temp_addr();
  3346. ap1->tempflag = TRUE;
  3347.                        ap2 = xalloc(sizeof(AMODE));
  3348. if (prm_rel) {
  3349.                         ap2->preg = basereg;          /* frame pointer */
  3350. if (prm_largedata) {
  3351. ap2->mode = am_areg;
  3352. gen_code(op_move,0,ap2,ap1);
  3353. ap2->mode = am_immed;
  3354. ap2->offset = node;
  3355. gen_code(op_add,0,ap2,ap1);
  3356. }
  3357. else {
  3358.                          ap2->mode = am_indx;
  3359.                           ap2->offset = node;     /* use as constant node */
  3360.                          gen_lea(0,ap2,ap1);
  3361. }
  3362. }
  3363. else {
  3364. ap2->mode = am_adirect;
  3365.                ap2->offset = node;
  3366. if (prm_smalldata) {
  3367. ap2->preg = 2;
  3368. }
  3369. else {
  3370. ap2->preg = 4;
  3371. }
  3372.                        gen_lea(0,ap2,ap1);
  3373. }
  3374.                         make_legal(ap1,flags,size);
  3375.                         return ap1;             /* return reg */
  3376.                 case en_icon:
  3377. case en_lcon: 
  3378. case en_lucon: 
  3379. case en_iucon: 
  3380. case en_ccon:                 
  3381. case en_rcon:
  3382. case en_lrcon: case en_fcon:
  3383.                         ap1 = xalloc(sizeof(AMODE));
  3384.                         ap1->mode = am_immed;
  3385.                         ap1->offset = node;
  3386.                         make_legal(ap1,flags,size);
  3387.                         return ap1;
  3388.                 case en_autocon:
  3389.                 case en_autoreg:
  3390.                         ap1 = temp_addr();
  3391. ap1->tempflag = TRUE;
  3392.                         ap2 = xalloc(sizeof(AMODE));
  3393.                         ap2->mode = am_indx;
  3394. if (prm_linkreg && !currentfunc->intflag) {
  3395.                  ap2->preg = linkreg;
  3396.                   ap2->offset = makenode(en_icon,(char *)((SYM *)node->v.p[0])->value.i,0);
  3397. }
  3398.   else if (((SYM *)node->v.p[0])->funcparm ) {
  3399. if (prm_phiform || currentfunc->intflag) {
  3400.                          ap2->preg = linkreg;          /* frame pointer */
  3401. ap2->offset = makenode(en_icon,(char *)(((SYM *)node->v.p[0])->value.i),0);
  3402. }
  3403. else {
  3404. ap2->preg = 7;
  3405. ap2->offset = makenode(en_icon,(char *)(((SYM *)node->v.p[0])->value.i+stackdepth+framedepth),0);
  3406. }
  3407.                  }
  3408. else {
  3409. ap2->preg = 7;
  3410. ap2->offset = makenode(en_icon,(char *)(((SYM *)node->v.p[0])->value.i+stackdepth+lc_maxauto),0);
  3411. }
  3412.                         gen_lea(0,ap2,ap1);
  3413.                         make_legal(ap1,flags,size);
  3414.                         return ap1;             /* return reg */
  3415.                 case en_b_ref:
  3416.                 case en_w_ref:
  3417.                 case en_ub_ref:
  3418.                 case en_uw_ref:
  3419.                 case en_l_ref:
  3420.                 case en_ul_ref:
  3421. case en_floatref:
  3422. case en_doubleref:
  3423. case en_longdoubleref:
  3424.                         ap1 = gen_deref(node,flags,size,FALSE);
  3425. return ap1;
  3426.                 case en_tempref:
  3427.                 case en_regref:
  3428.                         ap1 = xalloc(sizeof(AMODE));
  3429.                         if( (node->v.i & 0xff) < 16 )
  3430.                                 {
  3431.                                 ap1->mode = am_dreg;
  3432.                                 ap1->preg = node->v.i & 0xff;
  3433.                                 }
  3434.                         else
  3435. if ((node->v.i &0xff) < 32)
  3436.                                 {
  3437.                                 ap1->mode = am_areg;
  3438.                                 ap1->preg = (node->v.i & 0xff) - 16;
  3439.                                 }
  3440. else
  3441.                                 {
  3442.                                 ap1->mode = am_freg;
  3443.                                 ap1->preg = (node->v.i &0xff)- 32;
  3444.                                 }
  3445.                         ap1->tempflag = 0;      /* not a temporary */
  3446.                  do_extend(ap1,node->v.i >> 8,size,flags);
  3447.                         make_legal(ap1,flags,size);
  3448.                         return ap1;
  3449. case en_bits:
  3450. size = natural_size(node->v.p[0]);
  3451. ap1 = gen_expr(node->v.p[0],F_ALL,size);
  3452. if (!(flags & F_NOBIT))
  3453. bit_legal(ap1,node,size);
  3454. return ap1;
  3455.                 case en_uminus:
  3456.                         return gen_unary(node,flags,size,op_neg, op_fneg);
  3457.                 case en_compl:
  3458.                         return gen_unary(node,flags,size,op_not, op_not);
  3459.                 case en_add:
  3460.                         return gen_binary(node,flags,size,op_add,op_fadd);
  3461.                 case en_sub:
  3462.                         return gen_binary(node,flags,size,op_sub,op_fsub);
  3463.                 case en_and:
  3464.                         return gen_binary(node,flags,size,op_and,op_and);
  3465.                 case en_or:
  3466.                         return gen_binary(node,flags,size,op_or,op_or);
  3467. case en_xor:
  3468. return gen_xbin(node,flags,size,op_eor,op_eor);
  3469. case en_pmul:
  3470. return gen_pmul(node,flags,size);
  3471. case en_pdiv:
  3472. return gen_pdiv(node,flags,size);
  3473.                 case en_mul:
  3474.                         return gen_mul(node,flags,size,op_muls);
  3475.                 case en_umul:
  3476.                         return gen_mul(node,flags,size,op_mulu);
  3477.                 case en_div:
  3478.                         return gen_modiv(node,flags,size,op_divs,0);
  3479.                 case en_udiv:
  3480.                         return gen_modiv(node,flags,size,op_divu,0);
  3481.                 case en_mod:
  3482.                         return gen_modiv(node,flags,size,op_divs,1);
  3483.                 case en_umod:
  3484.                         return gen_modiv(node,flags,size,op_divu,1);
  3485.                 case en_alsh:
  3486.                         return gen_shift(node,flags,size,op_asl);
  3487.                 case en_arsh:
  3488.                         return gen_shift(node,flags,size,op_asr);
  3489.                 case en_lsh:
  3490.                         return gen_shift(node,flags,size,op_lsl);
  3491.                 case en_rsh:
  3492.                         return gen_shift(node,flags,size,op_lsr);
  3493.                 case en_asadd:
  3494.                         return gen_asadd(node,flags,size,op_add,op_fadd);
  3495.                 case en_assub:
  3496.                         return gen_asadd(node,flags,size,op_sub,op_fsub);
  3497.                 case en_asand:
  3498.                         return gen_aslogic(node,flags,size,op_and);
  3499.                 case en_asor:
  3500.                         return gen_aslogic(node,flags,size,op_or);
  3501.                 case en_asxor:
  3502.                         return gen_aslogic(node,flags,size,op_eor);
  3503.                 case en_aslsh:
  3504.                         return gen_asshift(node,flags,size,op_lsl);
  3505.                 case en_asrsh:
  3506.                         return gen_asshift(node,flags,size,op_lsr);
  3507.                 case en_asalsh:
  3508.                         return gen_asshift(node,flags,size,op_asl);
  3509.                 case en_asarsh:
  3510.                         return gen_asshift(node,flags,size,op_asr);
  3511.                 case en_asmul:
  3512.                         return gen_asmul(node,flags,size, op_muls);
  3513.                 case en_asumul:
  3514.                         return gen_asmul(node,flags,size,op_mulu);
  3515.                 case en_asdiv:
  3516.                         return gen_asmodiv(node,flags,size,op_divs,FALSE);
  3517.                 case en_asudiv:
  3518.                         return gen_asmodiv(node,flags,size,op_divu,FALSE);
  3519.                 case en_asmod:
  3520.                         return gen_asmodiv(node,flags,size,op_divs,TRUE);
  3521.                 case en_asumod:
  3522.                         return gen_asmodiv(node,flags,size,op_divu,TRUE);
  3523.                 case en_assign:
  3524.                         return gen_assign(node,flags,size);
  3525.                 case en_refassign:
  3526.                         return gen_refassign(node,flags | F_NOVALUE,size);
  3527.                 case en_moveblock:
  3528.                         return gen_moveblock(node,flags,size);
  3529.                 case en_ainc:
  3530.                         return gen_aincdec(node,flags,size,op_add);
  3531.                 case en_adec:
  3532.                         return gen_aincdec(node,flags,size,op_sub);
  3533.                 case en_land:   case en_lor:
  3534.                 case en_eq:     case en_ne:
  3535.                 case en_lt:     case en_le:
  3536.                 case en_gt:     case en_ge:
  3537.                 case en_ult:    case en_ule:
  3538.                 case en_ugt:    case en_uge:
  3539.                 case en_not:
  3540.                         lab0 = nextlabel++;
  3541.                         lab1 = nextlabel++;
  3542.                         falsejp(node,lab0);
  3543.                         ap1 = temp_data();
  3544.                         gen_code(op_moveq,0,make_immed(1),ap1);
  3545.                         gen_code(op_bra,0,make_label(lab1),0);
  3546.                         gen_label(lab0);
  3547.                         gen_code(op_clr,4,ap1,0);
  3548.                         gen_label(lab1);
  3549.                         return ap1;
  3550.                 case en_cond:
  3551.                         return gen_hook(node,flags,size);
  3552.                 case en_void:
  3553.                         natsize = natural_size(node->v.p[0]);
  3554.                         freeop(gen_expr(node->v.p[0],F_ALL | F_NOVALUE,natsize));
  3555.                         return gen_expr(node->v.p[1],flags,size);
  3556. case en_pfcall: case en_pfcallb:
  3557. case en_pcallblock:
  3558.                         return gen_pfcall(node,flags,size);
  3559.                 case en_fcall:  case en_callblock: case en_fcallb:
  3560.                 case en_intcall: 
  3561.                 case en_trapcall:
  3562.                         return gen_fcall(node,flags,size);
  3563.                 default:
  3564.                         DIAG("uncoded node in gen_expr.");
  3565.                         return 0;
  3566.                 }
  3567. }
  3568. int     natural_size(ENODE *node)
  3569. /*
  3570.  *      return the natural evaluation size of a node.
  3571.  */
  3572. {       int     siz0, siz1;
  3573.         if( node == 0 )
  3574.                 return 0;
  3575.         switch( node->nodetype )
  3576.                 {
  3577. case en_bits:
  3578. return stdintsize;
  3579.                 case en_icon:
  3580. case en_lcon: 
  3581. case en_lucon: 
  3582.                 case en_iucon:
  3583. return 0;
  3584. case en_ccon:                 
  3585. return 0;
  3586. case en_rcon:
  3587. case en_doubleref:
  3588. return 8;
  3589. case en_lrcon:
  3590. case en_longdoubleref:
  3591. return stdldoublesize;
  3592. case en_fcon:
  3593. case en_floatref:
  3594. return 6;
  3595. case en_trapcall:
  3596.                 case en_labcon:
  3597.                 case en_nacon:  case en_autocon:  case en_autoreg:
  3598.                 case en_napccon:  case en_absacon: case en_nalabcon:
  3599. return stdaddrsize;
  3600. case en_l_ref:
  3601. case en_cl:
  3602. return -4;
  3603. case en_pfcall: case en_pfcallb: /* ignore pascal style now */
  3604. case en_pcallblock:
  3605. case en_fcall: case en_callblock: case en_fcallb:
  3606. case en_intcall:
  3607. return natural_size(node->v.p[1]);
  3608. case en_tempref:
  3609. case en_regref:
  3610. return node->v.i >> 8;
  3611.                 case en_ul_ref:
  3612. case en_cul:
  3613.                         return 4;
  3614. case en_cp:
  3615. return stdaddrsize;
  3616.                 case en_ub_ref:
  3617. case en_cub:
  3618. return 1;
  3619.                 case en_b_ref:
  3620. case en_cb:
  3621.                         return -1;
  3622.                 case en_uw_ref:
  3623. case en_cuw:
  3624. return 2;
  3625.                 case en_cw:
  3626.                 case en_w_ref:
  3627.                         return -2;
  3628. case en_cd:
  3629. return 8;
  3630. case en_cld:
  3631. return 10;
  3632. case en_cf:
  3633. return 6;
  3634.                 case en_not:    case en_compl:
  3635.                 case en_uminus: case en_assign: case en_refassign:
  3636.                 case en_ainc:   case en_adec:
  3637. case en_moveblock: case en_stackblock:
  3638.                         return natural_size(node->v.p[0]);
  3639.                 case en_add:    case en_sub:
  3640. case en_umul: case en_udiv: case en_umod: case en_pmul:
  3641.                 case en_mul:    case en_div:  case en_pdiv:
  3642.                 case en_mod:    case en_and:
  3643.                 case en_or:     case en_xor:
  3644. case en_asalsh: case en_asarsh: case en_alsh: case en_arsh:
  3645.                 case en_lsh:    case en_rsh:
  3646.                 case en_eq:     case en_ne:
  3647.                 case en_lt:     case en_le:
  3648.                 case en_gt:     case en_ge:
  3649. case en_ugt: case en_uge: case en_ult: case en_ule:
  3650.                 case en_land:   case en_lor:
  3651.                 case en_asadd:  case en_assub:
  3652.                 case en_asmul:  case en_asdiv:
  3653.                 case en_asmod:  case en_asand:
  3654. case en_asumod: case en_asudiv: case en_asumul:
  3655.                 case en_asor:   case en_aslsh:  case en_asxor:
  3656.                 case en_asrsh:
  3657.                         siz0 = natural_size(node->v.p[0]);
  3658.                         siz1 = natural_size(node->v.p[1]);
  3659.                         if( chksize(siz1,siz0))
  3660.                                 return siz1;
  3661.                         else
  3662.                                 return siz0;
  3663.                 case en_void:   case en_cond:
  3664.                         return natural_size(node->v.p[1]);
  3665.                 default:
  3666.                         DIAG("natural size error.");
  3667.                         break;
  3668.                 }
  3669.         return 0;
  3670. }
  3671. void gen_compare(ENODE *node, int btype1, int btype2, int btype3, int btype4, int label)
  3672. /*
  3673.  *      generate code to do a comparison of the two operands of
  3674.  *      node.
  3675.  */
  3676. {       AMODE    *ap1, *ap2,  *ap3;
  3677.         int             size;
  3678. int btype = btype1;
  3679. ap3 = 0;
  3680.         size = natural_size(node);
  3681. if (size > 4) {
  3682.          ap1 = gen_expr(node->v.p[0],F_FREG,size);
  3683. mark();
  3684.          ap2 = gen_expr(node->v.p[1],F_ALL,size);
  3685.          gen_code(op_fcmp,size,ap2,ap1);
  3686.          gen_code(btype3,0,make_label(label),0);
  3687. freeop(ap2);
  3688. freeop(ap1);
  3689. release();
  3690. return;
  3691. }
  3692.         ap1 = gen_expr(node->v.p[0],F_ALL,size);
  3693. mark();
  3694.         ap2 = gen_expr(node->v.p[1],F_ALL,size);
  3695. if (ap1->mode != am_dreg && ap1->mode != am_areg) {
  3696. if (ap2->mode == am_immed)  {
  3697. if (ap1->mode == am_immed)
  3698. goto cmp2;
  3699. }
  3700. else {
  3701. if (ap2->mode == am_dreg || ap2->mode == am_areg) {
  3702. swapit:
  3703. ap3 = ap2;
  3704. ap2 = ap1;
  3705. ap1 = ap3;
  3706. ap3 = 0;
  3707. btype = btype2;
  3708. }
  3709. else  
  3710. if (ap1->mode == am_immed) {
  3711. goto swapit;
  3712. }
  3713. else {
  3714. cmp2:
  3715. ap3 = ap1;
  3716.                ap1 = temp_data();
  3717. gen_code(op_move,size,ap3,ap1);
  3718.                make_legal(ap1,F_DREG,size);
  3719. }
  3720. }
  3721. }
  3722.         gen_code(op_cmp,size,ap2,ap1);
  3723.         gen_code(btype,0,make_label(label),0);
  3724. if (ap3) {
  3725. freeop(ap1);
  3726. freeop(ap2);
  3727. freeop(ap3);
  3728. }
  3729. else {
  3730.          freeop(ap2);
  3731.          freeop(ap1);
  3732. }
  3733. release();
  3734. }
  3735. void truejp(ENODE *node, int label)
  3736. /*
  3737.  *      generate a jump to label if the node passed evaluates to
  3738.  *      a true condition.
  3739.  */
  3740. {       AMODE    *ap1;
  3741.         int             siz1;
  3742.         int             lab0;
  3743.         if( node == 0 )
  3744.                 return;
  3745.         switch( node->nodetype )
  3746.                 {
  3747.                 case en_eq:
  3748.                         gen_compare(node,op_beq,op_beq,op_fbeq,op_fbeq,label);
  3749.                         break;
  3750.                 case en_ne:
  3751.                         gen_compare(node,op_bne,op_bne,op_fbne,op_fbne,label);
  3752.                         break;
  3753.                 case en_lt:
  3754.                         gen_compare(node,op_blt,op_bgt,op_fblt,op_fbgt,label);
  3755.                         break;
  3756.                 case en_le:
  3757.                         gen_compare(node,op_ble,op_bge,op_fble,op_fbge,label);
  3758.                         break;
  3759.                 case en_gt:
  3760.                         gen_compare(node,op_bgt,op_blt,op_fbgt,op_fblt,label);
  3761.                         break;
  3762.                 case en_ge:
  3763.                         gen_compare(node,op_bge,op_ble,op_fbge,op_fble,label);
  3764.                         break;
  3765.                 case en_ult:
  3766.                         gen_compare(node,op_blo,op_bhi,op_fblt,op_fbgt,label);
  3767.                         break;
  3768.                 case en_ule:
  3769.                         gen_compare(node,op_bls,op_bhs,op_fble,op_fbge,label);
  3770.                         break;
  3771.                 case en_ugt:
  3772.                         gen_compare(node,op_bhi,op_blo,op_fbgt,op_fblt,label);
  3773.                         break;
  3774.                 case en_uge:
  3775.                         gen_compare(node,op_bhs,op_bls,op_fbge,op_fble,label);
  3776.                         break;
  3777.                 case en_land:
  3778.                         lab0 = nextlabel++;
  3779.                         falsejp(node->v.p[0],lab0);
  3780.                         truejp(node->v.p[1],label);
  3781.                         gen_label(lab0);
  3782.                         break;
  3783.                 case en_lor:
  3784.                         truejp(node->v.p[0],label);
  3785.                         truejp(node->v.p[1],label);
  3786.                         break;
  3787.                 case en_not:
  3788.                         falsejp(node->v.p[0],label);
  3789.                         break;
  3790.                 default:
  3791.                         siz1 = natural_size(node);    
  3792. if (isintconst(node->nodetype)) {
  3793. if (node->v.i != 0)
  3794.                          gen_code(op_bra,0,make_label(label),0);
  3795.               break;
  3796. }
  3797. else {
  3798. if (siz1 > 4)
  3799.                          ap1 = gen_expr(node,F_FREG,siz1);
  3800. else
  3801.                          ap1 = gen_expr(node,F_DREG | F_INDX,siz1);
  3802. }
  3803. if (siz1 > 4) {
  3804.                          gen_codef(op_ftst,siz1,ap1,0);
  3805.                          freeop(ap1);
  3806.                          gen_code(op_fbne,0,make_label(label),0);
  3807. }
  3808. else {
  3809.                          gen_code(op_tst,siz1,ap1,0);
  3810.                          freeop(ap1);
  3811.                          gen_code(op_bne,0,make_label(label),0);
  3812. }
  3813.                         break;
  3814.                 }
  3815. }
  3816. void falsejp(ENODE *node, int label)
  3817. /*
  3818.  *      generate code to execute a jump to label if the expression
  3819.  *      passed is false.
  3820.  */
  3821. {       AMODE    *ap;
  3822.         int             siz1;
  3823.         int             lab0;
  3824.         if( node == 0 )
  3825.                 return;
  3826.         switch( node->nodetype )
  3827.                 {
  3828.                 case en_eq:
  3829.                         gen_compare(node,op_bne,op_bne,op_fbne,op_fbne,label);
  3830.                         break;
  3831.                 case en_ne:
  3832.                         gen_compare(node,op_beq,op_beq,op_fbeq,op_fbeq,label);
  3833.                         break;
  3834.                 case en_lt:
  3835.                         gen_compare(node,op_bge,op_ble,op_fbge,op_fble,label);
  3836.                         break;
  3837.                 case en_le:
  3838.                         gen_compare(node,op_bgt,op_blt,op_fbgt,op_fblt,label);
  3839.                         break;
  3840.                 case en_gt:
  3841.                         gen_compare(node,op_ble,op_bge,op_fble,op_fbge,label);
  3842.                         break;
  3843.                 case en_ge:
  3844.                         gen_compare(node,op_blt,op_bgt,op_fblt,op_fbgt,label);
  3845.                         break;
  3846.                 case en_ult:
  3847.                         gen_compare(node,op_bhs,op_bls,op_fbge,op_fble,label);
  3848.                         break;
  3849.                 case en_ule:
  3850.                         gen_compare(node,op_bhi,op_blo,op_fbgt,op_fblt,label);
  3851.                         break;
  3852.                 case en_ugt:
  3853.                         gen_compare(node,op_bls,op_bhs,op_fble,op_fbge,label);
  3854.                         break;
  3855.                 case en_uge:
  3856.                         gen_compare(node,op_blo,op_bhi,op_fblt,op_fbgt,label);
  3857.                         break;
  3858.                 case en_land:
  3859.                         falsejp(node->v.p[0],label);
  3860.                         falsejp(node->v.p[1],label);
  3861.                         break;
  3862.                 case en_lor:
  3863.                         lab0 = nextlabel++;
  3864.                         truejp(node->v.p[0],lab0);
  3865.                         falsejp(node->v.p[1],label);
  3866.                         gen_label(lab0);
  3867.                         break;
  3868.                 case en_not:
  3869.                         truejp(node->v.p[0],label);
  3870.                         break;
  3871.                 default:
  3872.                         siz1 = natural_size(node);    
  3873. if (isintconst(node->nodetype)) {
  3874. if (node->v.i == 0)
  3875.                          gen_code(op_bra,0,make_label(label),0);
  3876.               break;
  3877. }
  3878. else{
  3879. if (siz1 > 4)
  3880.                          ap = gen_expr(node,F_FREG,siz1);
  3881. else
  3882.                          ap = gen_expr(node,F_DREG | F_INDX,siz1);
  3883. }
  3884. if (siz1 > 4) {
  3885.                          gen_codef(op_ftst,siz1,ap,0);
  3886.                          freeop(ap);
  3887.                          gen_code(op_fbeq,0,make_label(label),0);
  3888. }
  3889. else {
  3890.                          gen_code(op_tst,siz1,ap,0);
  3891.                          freeop(ap);
  3892.                          gen_code(op_beq,0,make_label(label),0);
  3893. }
  3894.                         break;
  3895.                 }
  3896. }