home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume5 / smallc / part1 / codem68k.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  11.0 KB  |  846 lines

  1. /*    File codem68k.c: 1.2 (84/11/28,10:15:09) */
  2. /*% cc -O -c %
  3.  *
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "defs.h"
  8. #include "data.h"
  9.  
  10. #ifdef    unix
  11. #ifdef    m68k
  12. #define    ASNM    "as -o "
  13. #define    LDNM    "ld -o a.out /lib/crt0.o "
  14. #endif
  15. #ifdef    pyr
  16. #define    ASNM    "/u1/cx/bin/m68kas -o "
  17. #define    LDNM    "/u1/cx/bin/m68kld -o a.out /u1/cx/lib/m68kcrt0.o "
  18. #endif
  19. #endif
  20.  
  21. int    needr0;
  22. int    needh;
  23. /*
  24.  *    Some predefinitions:
  25.  *
  26.  *    INTSIZE is the size of an integer in the target machine
  27.  *    BYTEOFF is the offset of an byte within an integer on the
  28.  *        target machine. (ie: 8080,pdp11 = 0, 6809 = 1,
  29.  *        360 = 3)
  30.  *    This compiler assumes that an integer is the SAME length as
  31.  *    a pointer - in fact, the compiler uses INTSIZE for both.
  32.  */
  33. #define    INTSIZE    4
  34. #define    BYTEOFF    3
  35.  
  36. /*
  37.  *    print all assembler info before any code is generated
  38.  *
  39.  */
  40. header ()
  41. {
  42.     outstr("#\tSmall C M68000\n#\tCoder (1.2,84/11/28)\n#");
  43.     FEvers();
  44.     nl ();
  45.     ol ("global\tTlneg");
  46.     ol ("global\tTcase");
  47.     ol ("global\tTeq");
  48.     ol ("global\tTne");
  49.     ol ("global\tTlt");
  50.     ol ("global\tTle");
  51.     ol ("global\tTgt");
  52.     ol ("global\tTge");
  53.     ol ("global\tTult");
  54.     ol ("global\tTule");
  55.     ol ("global\tTugt");
  56.     ol ("global\tTuge");
  57.     ol ("global\tTbool");
  58.     ol ("global\tTmult");
  59.     ol ("global\tTdiv");
  60.     ol ("global\tTmod");
  61. }
  62.  
  63. nl()
  64. {
  65.     if (needh) {
  66.         ol ("word\t0");
  67.         needh = 0;
  68.     }
  69.     if (needr0) {
  70.         needr0 = 0;
  71.         outstr(",%d0");
  72.     }
  73.     outbyte(EOL);
  74. }
  75.  
  76. initmac() {
  77.     defmac("m68k\t1");
  78.     defmac("unix\t1");
  79.     defmac("smallc\t1");
  80. }
  81.  
  82. galign(t)
  83. int t;
  84. {
  85.     int sign;
  86.     if (t < 0) {
  87.         sign = 1;
  88.         t = -t;
  89.     } else
  90.         sign = 0;
  91.     t = (t + INTSIZE - 1) & ~(INTSIZE - 1);
  92.     t = sign? -t: t;
  93.     return (t);
  94. }
  95.  
  96.  
  97.  
  98. /*
  99.  *    return size of an integer
  100.  */
  101. intsize() {
  102.     return(INTSIZE);
  103. }
  104.  
  105. /*
  106.  *    return offset of ls byte within word
  107.  *    (ie: 8080 & pdp11 is 0, 6809 is 1, 360 is 3)
  108.  */
  109. byteoff() {
  110.     return(BYTEOFF);
  111. }
  112.  
  113. /*
  114.  *    Output internal generated label prefix
  115.  */
  116. olprfix() {
  117.     outstr("LL");
  118. }
  119.  
  120. /*
  121.  *    Output a label definition terminator
  122.  */
  123. col ()
  124. {
  125.     outstr (":\n");
  126. }
  127.  
  128. /*
  129.  *    begin a comment line for the assembler
  130.  *
  131.  */
  132. comment ()
  133. {
  134.     outbyte ('#');
  135. }
  136.  
  137. /*
  138.  *    Output a prefix in front of user labels
  139.  */
  140. prefix () {
  141. /*    outbyte ('_'); */
  142. }
  143.  
  144.  
  145. /*
  146.  *    print any assembler stuff needed after all code
  147.  *
  148.  */
  149. trailer ()
  150. {
  151. }
  152.  
  153. /*
  154.  *    function prologue
  155.  */
  156. prologue ()
  157. {
  158.     /* this is where we'd put splimit stuff */
  159. }
  160.  
  161. /*
  162.  *    text (code) segment
  163.  */
  164. gtext ()
  165. {
  166.     ol ("text");
  167. }
  168.  
  169. /*
  170.  *    data segment
  171.  */
  172. gdata ()
  173. {
  174.     ol ("data");
  175. }
  176.  
  177. /*
  178.  *  Output the variable symbol at scptr as an extrn or a public
  179.  */
  180. ppubext(scptr) char *scptr; {
  181.     if (scptr[STORAGE] == STATIC) return;
  182.     ot ("global\t");
  183.     prefix ();
  184.     outstr (scptr);
  185.     nl();
  186. }
  187.  
  188. /*
  189.  * Output the function symbol at scptr as an extrn or a public
  190.  */
  191. fpubext(scptr) char *scptr; {
  192.     ppubext(scptr);
  193. }
  194.  
  195. /*
  196.  *  Output a decimal number to the assembler file
  197.  */
  198. onum(num) int num; {
  199.     outdec(num);    /* pdp11 needs a "." here */
  200. }
  201.  
  202.  
  203. /*
  204.  *    fetch a static memory cell into the primary register
  205.  */
  206. getmem (sym)
  207. char    *sym;
  208. {
  209.     int ischr;
  210.     if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
  211.         ischr = 1;
  212.         ot ("mov.b\t");
  213.         prefix ();
  214.         outstr (sym + NAME);
  215.     } else {
  216.         ischr = 0;
  217.         ot ("mov.l\t");
  218.         prefix ();
  219.         outstr (sym + NAME);
  220.     }
  221.     outstr(",%d0\n");
  222.     if (ischr)
  223.         ol ("ext.b\t%d0");
  224. }
  225.  
  226. /*
  227.  *    fetch the address of the specified symbol into the primary register
  228.  *
  229.  */
  230. getloc (sym)
  231. char    *sym;
  232. {
  233.     if (sym[STORAGE] == LSTATIC) {
  234.         immed();
  235.         printlabel(glint(sym));
  236.         nl();
  237.     } else {
  238.         ot ("lea.l\t");
  239.         onum (glint(sym) - stkp);
  240.         outstr (",%a0\n");
  241.         ol ("mov.l\t%a0,%d0");
  242.     }
  243. }
  244.  
  245. /*
  246.  *    store the primary register into the specified static memory cell
  247.  *
  248.  */
  249. putmem (sym)
  250. char    *sym;
  251. {
  252.     if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) {
  253.         ot ("mov.b\t%d0,");
  254.     } else
  255.         ot ("mov.l\t%d0,");
  256.     prefix ();
  257.     outstr (sym + NAME);
  258.     nl ();
  259. }
  260.  
  261. /*
  262.  *    store the specified object type in the primary register
  263.  *    at the address on the top of the stack
  264.  *
  265.  */
  266. putstk (typeobj)
  267. char    typeobj;
  268. {
  269.     ol ("mov.l\t(%sp)+,%a0");
  270.     if (typeobj == CCHAR)
  271.         ol ("mov.b\t%d0,(%a0)");
  272.     else
  273.         ol ("mov.l\t%d0,(%a0)");
  274.     stkp = stkp + INTSIZE;
  275. }
  276.  
  277. /*
  278.  *    fetch the specified object type indirect through the primary
  279.  *    register into the primary register
  280.  *
  281.  */
  282. indirect (typeobj)
  283. char    typeobj;
  284. {
  285.     ol ("mov.l\t%d0,%a0");
  286.     if (typeobj == CCHAR)
  287.         ol ("mov.b\t(%a0),%d0");
  288.     else
  289.         ol ("mov.l\t(%a0),%d0");
  290. }
  291.  
  292. /*
  293.  *    swap the primary and secondary registers
  294.  *
  295.  */
  296. swap ()
  297. {
  298.     ol ("mov.l\t%d0,%d2\n\tmov.l\t%d1,%d0\n\tmov.l\t%d2,%d1");
  299. }
  300.  
  301. /*
  302.  *    print partial instruction to get an immediate value into
  303.  *    the primary register
  304.  *
  305.  */
  306. immed ()
  307. {
  308.     ot ("mov.l\t&");
  309.     needr0 = 1;
  310. }
  311.  
  312. /*
  313.  *    push the primary register onto the stack
  314.  *
  315.  */
  316. gpush ()
  317. {
  318.     ol ("mov.l\t%d0,-(%sp)");
  319.     stkp = stkp - INTSIZE;
  320. }
  321.  
  322. /*
  323.  *    pop the top of the stack into the secondary register
  324.  *
  325.  */
  326. gpop ()
  327. {
  328.     ol ("mov.l\t(%sp)+,%d1");
  329.     stkp = stkp + INTSIZE;
  330. }
  331.  
  332. /*
  333.  *    swap the primary register and the top of the stack
  334.  *
  335.  */
  336. swapstk ()
  337. {
  338.     ol ("mov.l\t(%sp)+,%d2\nmov.l\t%d0,-(%sp)\nmov.l\t%d2,%d0");
  339. }
  340.  
  341. /*
  342.  *    call the specified subroutine name
  343.  *
  344.  */
  345. gcall (sname)
  346. char    *sname;
  347. {
  348.     if (*sname == '^') {
  349.         ot ("jsr\tT");
  350.         outstr (++sname);
  351.     } else {
  352.         ot ("jsr\t");
  353.         prefix ();
  354.         outstr (sname);
  355.     }
  356.     nl ();
  357. }
  358.  
  359. /*
  360.  *    return from subroutine
  361.  *
  362.  */
  363. gret ()
  364. {
  365.     ol ("rts");
  366. }
  367.  
  368. /*
  369.  *    perform subroutine call to value on top of stack
  370.  *
  371.  */
  372. callstk ()
  373. {
  374.     ol ("jsr\t(%sp)+");
  375.     stkp = stkp + INTSIZE;
  376. }
  377.  
  378. /*
  379.  *    jump to specified internal label number
  380.  *
  381.  */
  382. jump (label)
  383. int    label;
  384. {
  385.     ot ("jmp\t");
  386.     printlabel (label);
  387.     nl ();
  388. }
  389.  
  390. /*
  391.  *    test the primary register and jump if false to label
  392.  *
  393.  */
  394. testjump (label, ft)
  395. int    label,
  396.     ft;
  397. {
  398.     ol ("cmp.l\t%d0,&0");
  399.     if (ft)
  400.         ot ("beq\t");
  401.     else
  402.         ot ("bne\t");
  403.     printlabel (label);
  404.     nl ();
  405. }
  406.  
  407. /*
  408.  *    print pseudo-op  to define a byte
  409.  *
  410.  */
  411. defbyte ()
  412. {
  413.     ot ("byte\t");
  414. }
  415.  
  416. /*
  417.  *    print pseudo-op to define storage
  418.  *
  419.  */
  420. defstorage ()
  421. {
  422.     ot ("space\t");
  423. }
  424.  
  425. /*
  426.  *    print pseudo-op to define a word
  427.  *
  428.  */
  429. defword ()
  430. {
  431.     ot ("long\t");
  432. }
  433.  
  434. /*
  435.  *    modify the stack pointer to the new value indicated
  436.  *
  437.  */
  438. modstk (newstkp)
  439. int    newstkp;
  440. {
  441.     int    k;
  442.  
  443.     k = newstkp - stkp;
  444.     if (k % INTSIZE)
  445.         error("Bad stack alignment (compiler error)");
  446.     if (k == 0)
  447.         return (newstkp);
  448.     ot ("add.l\t&");
  449.     onum (k);
  450.     outstr (",sp");
  451.     nl();
  452.     return (newstkp);
  453. }
  454.  
  455. /*
  456.  *    multiply the primary register by INTSIZE
  457.  */
  458. gaslint ()
  459. {
  460.     ol ("asl.l\t&2,%d0");
  461. }
  462.  
  463. /*
  464.  *    divide the primary register by INTSIZE
  465.  */
  466. gasrint()
  467. {
  468.     ol ("asr.l\t&2,%d0");
  469. }
  470.  
  471. /*
  472.  *    Case jump instruction
  473.  */
  474. gjcase() {
  475.     gcall ("^case");
  476. }
  477.  
  478. /*
  479.  *    add the primary and secondary registers
  480.  *    if lval2 is int pointer and lval is int, scale lval
  481.  */
  482. gadd (lval, lval2) int *lval, *lval2;
  483. {
  484.     if (dbltest (lval2, lval)) {
  485.         ol ("asl.l\t&2,(%sp)");
  486.     }
  487.     ol ("add.l\t(%sp)+,%d0");
  488.     stkp = stkp + INTSIZE;
  489. }
  490.  
  491. /*
  492.  *    subtract the primary register from the secondary
  493.  *
  494.  */
  495. gsub ()
  496. {
  497.     ol ("mov.l\t(%sp)+,%d2");
  498.     ol ("sub.l\t%d0,%d2");
  499.     ol ("mov.l\t%d2,%d0");
  500.     stkp = stkp + INTSIZE;
  501. }
  502.  
  503. /*
  504.  *    multiply the primary and secondary registers
  505.  *    (result in primary)
  506.  *
  507.  */
  508. gmult ()
  509. {
  510.     gcall ("^mult");
  511.     stkp = stkp + INTSIZE;
  512. }
  513.  
  514. /*
  515.  *    divide the secondary register by the primary
  516.  *    (quotient in primary, remainder in secondary)
  517.  *
  518.  */
  519. gdiv ()
  520. {
  521.     gcall ("^div");
  522.     stkp = stkp + INTSIZE;
  523. }
  524.  
  525. /*
  526.  *    compute the remainder (mod) of the secondary register
  527.  *    divided by the primary register
  528.  *    (remainder in primary, quotient in secondary)
  529.  *
  530.  */
  531. gmod ()
  532. {
  533.     gcall ("^mod");
  534.     stkp = stkp + INTSIZE;
  535. }
  536.  
  537. /*
  538.  *    inclusive 'or' the primary and secondary registers
  539.  *
  540.  */
  541. gor ()
  542. {
  543.     ol ("or.l\t(%sp)+,%d0");
  544.     stkp = stkp + INTSIZE;
  545. }
  546.  
  547. /*
  548.  *    exclusive 'or' the primary and secondary registers
  549.  *
  550.  */
  551. gxor ()
  552. {
  553.     ol ("mov.l\t(%sp)+,%d1");
  554.     ol ("eor.l\t%d1,%d0");
  555.     stkp = stkp + INTSIZE;
  556. }
  557.  
  558. /*
  559.  *    'and' the primary and secondary registers
  560.  *
  561.  */
  562. gand ()
  563. {
  564.     ol ("and.l\t(%sp)+,%d0");
  565.     stkp = stkp + INTSIZE;
  566. }
  567.  
  568. /*
  569.  *    arithmetic shift right the secondary register the number of
  570.  *    times in the primary register
  571.  *    (results in primary register)
  572.  *
  573.  */
  574. gasr ()
  575. {
  576.     ol ("mov.l\t(%sp)+,%d1");
  577.     ol ("asr.l\t%d0,%d1");
  578.     ol ("mov.l\t%d1,%d0");
  579.     stkp = stkp + INTSIZE;
  580. }
  581.  
  582. /*
  583.  *    arithmetic shift left the secondary register the number of
  584.  *    times in the primary register
  585.  *    (results in primary register)
  586.  *
  587.  */
  588. gasl ()
  589. {
  590.     ol ("mov.l\t(%sp)+,%d1");
  591.     ol ("asl.l\t%d0,%d1");
  592.     ol ("mov.l\t%d1,%d0");
  593.     stkp = stkp + INTSIZE;
  594. }
  595.  
  596. /*
  597.  *    two's complement of primary register
  598.  *
  599.  */
  600. gneg ()
  601. {
  602.     ol ("neg.l\t%d0");
  603. }
  604.  
  605. /*
  606.  *    logical complement of primary register
  607.  *
  608.  */
  609. glneg ()
  610. {
  611.     gcall ("^lneg");
  612. }
  613.  
  614. /*
  615.  *    one's complement of primary register
  616.  *
  617.  */
  618. gcom ()
  619. {
  620.     ol ("not\t%d0");
  621. }
  622.  
  623. /*
  624.  *    convert primary register into logical value
  625.  *
  626.  */
  627. gbool ()
  628. {
  629.     gcall ("^bool");
  630. }
  631. /*
  632.  *    increment the primary register by 1 if char, INTSIZE if
  633.  *      int
  634.  */
  635. ginc (lval) int lval[];
  636. {
  637.     if (lval[2] == CINT)
  638.         ol ("addq.l\t&4,%d0");
  639.     else
  640.         ol ("addq.l\t&1,%d0");
  641. }
  642.  
  643. /*
  644.  *    decrement the primary register by one if char, INTSIZE if
  645.  *    int
  646.  */
  647. gdec (lval) int lval[];
  648. {
  649.     if (lval[2] == CINT)
  650.         ol ("subq.l\t&4,%d0");
  651.     else
  652.         ol ("subq.l\t&1,%d0");
  653. }
  654.  
  655. /*
  656.  *    following are the conditional operators.
  657.  *    they compare the secondary register against the primary register
  658.  *    and put a literl 1 in the primary if the condition is true,
  659.  *    otherwise they clear the primary register
  660.  *
  661.  */
  662.  
  663. /*
  664.  *    equal
  665.  *
  666.  */
  667. geq ()
  668. {
  669.     gcall ("^eq");
  670.     stkp = stkp + INTSIZE;
  671. }
  672.  
  673. /*
  674.  *    not equal
  675.  *
  676.  */
  677. gne ()
  678. {
  679.     gcall ("^ne");
  680.     stkp = stkp + INTSIZE;
  681. }
  682.  
  683. /*
  684.  *    less than (signed)
  685.  *
  686.  */
  687. glt ()
  688. {
  689.     gcall ("^lt");
  690.     stkp = stkp + INTSIZE;
  691. }
  692. /*
  693.  *    less than or equal (signed)
  694.  *
  695.  */
  696. gle ()
  697. {
  698.     gcall ("^le");
  699.     stkp = stkp + INTSIZE;
  700. }
  701.  
  702. /*
  703.  *    greater than (signed)
  704.  *
  705.  */
  706. ggt ()
  707. {
  708.     gcall ("^gt");
  709.     stkp = stkp + INTSIZE;
  710. }
  711.  
  712. /*
  713.  *    greater than or equal (signed)
  714.  *
  715.  */
  716. gge ()
  717. {
  718.     gcall ("^ge");
  719.     stkp = stkp + INTSIZE;
  720. }
  721.  
  722. /*
  723.  *    less than (unsigned)
  724.  *
  725.  */
  726. gult ()
  727. {
  728.     gcall ("^ult");
  729.     stkp = stkp + INTSIZE;
  730. }
  731.  
  732. /*
  733.  *    less than or equal (unsigned)
  734.  *
  735.  */
  736. gule ()
  737. {
  738.     gcall ("^ule");
  739.     stkp = stkp + INTSIZE;
  740. }
  741.  
  742. /*
  743.  *    greater than (unsigned)
  744.  *
  745.  */
  746. gugt ()
  747. {
  748.     gcall ("^ugt");
  749.     stkp = stkp + INTSIZE;
  750. }
  751.  
  752. /*
  753.  *    greater than or equal (unsigned)
  754.  *
  755.  */
  756. guge ()
  757. {
  758.     gcall ("^uge");
  759.     stkp = stkp + INTSIZE;
  760. }
  761.  
  762. inclib() {
  763. #ifdef    flex
  764.     return("B.");
  765. #endif
  766. #ifdef    unix
  767.     return(INCDIR);
  768. #endif
  769. #ifdef    cpm
  770.     return("B:");
  771. #endif
  772. }
  773.  
  774. /*    Squirrel away argument count in a register that modstk/getloc/stloc
  775.     doesn't touch.
  776. */
  777.  
  778. gnargs(d)
  779. int    d; {
  780.     ot ("mov.l\t&");
  781.     onum(d);
  782.     outstr(",%d3\n");
  783. }
  784.  
  785. #ifndef    NOASLD
  786. char    assems[400];
  787. int    assinit;
  788. assemble(s)
  789. char    *s; {
  790. #ifdef    ASNM
  791.     char    cmd[100],buf[100];
  792.     char    *p;
  793.     int    ex, rc, delaft;
  794. #ifdef    unix
  795.     p = strrchr(s, '/');
  796.     if (p)
  797.         strcat(buf, p+1);
  798.     else
  799. #endif
  800.         strcat(buf, s);
  801.     p = buf + strlen(buf) - 1;
  802.     rc = typeof(s);
  803.     delaft = (rc == 'c');
  804.     if (rc == 'c' || rc == 's') {
  805.         ex = 0;
  806.         *p = 'o';
  807.     } else
  808.         ex = 1;
  809.     if (!assinit) {
  810.         strcat(assems, LDNM);
  811.         assinit = 1;
  812.     }
  813.     strcat(assems, buf);
  814.     strcat(assems, " ");
  815.     if (ex)
  816.         return(0);
  817.     strcpy(cmd, ASNM);
  818.     strcat(cmd, buf);
  819.     strcat(cmd, " ");
  820.     *p = 's';
  821.     strcat(cmd, buf);
  822.     rc = system(cmd);
  823.     if (!rc && delaft)
  824.         unlink(buf);
  825.     return(rc);
  826. #else
  827.     return(0);
  828. #endif
  829. }
  830.  
  831. link() {
  832. #ifdef    LDNM
  833. #ifdef    unix
  834. #ifdef    m68k
  835.     strcat(assems, " -lc");
  836. #else
  837.     strcat(assems, " /u1/cx/lib/libc.a");
  838. #endif
  839. #endif
  840.     return(system(assems));
  841. #else
  842.     return(0);
  843. #endif
  844. }
  845. #endif
  846.