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

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