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

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