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

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