home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / as32 / symbol.c < prev    next >
C/C++ Source or Header  |  1991-03-22  |  11KB  |  393 lines

  1. /* ----------------------------------------------------------------------
  2.  * FILE: symbol.c
  3.  * PACKAGE: as31 - 8031/8051 Assembler.
  4.  *
  5.  * DESCRIPTION:
  6.  *    This file contains the symbol table search/insertion routines
  7.  *    associated with user defined symbols.
  8.  *
  9.  *    The reserved keyword (instructions/directives) look up routine
  10.  *    is defined here.
  11.  *
  12.  *    The opcode table for all of the instructions is located in this
  13.  *    file.
  14.  *
  15.  * REVISION HISTORY:
  16.  *    Jan. 19, 1990 - Created. (Ken Stauffer)
  17.  *
  18.  * AUTHOR:
  19.  *    All code in this file written by Ken Stauffer (University of Calgary)
  20.  *    January, 1990.
  21.  *
  22.  */
  23.  
  24. #include "as31.h"
  25. #define NULL        (0)
  26.  
  27. #define B(a)        (0xF0+(a))
  28. #define ACC(a)        (0xE0+(a))
  29. #define PSW(a)        (0xD0+(a))
  30. #define T2CON(a)    (0xC8+(a))
  31. #define IP(a)        (0xB8+(a))
  32. #define P3(a)        (0xB0+(a))
  33. #define IE(a)        (0xA8+(a))
  34. #define P2(a)        (0xA0+(a))
  35. #define SCON(a)        (0x98+(a))
  36. #define P1(a)        (0x90+(a))
  37. #define TCON(a)        (0x88+(a))
  38. #define P0(a)        (0x80+(a))
  39.  
  40. /* ---------------------------------------------------------------------- 
  41.  * sinit[]
  42.  *    These symbols are not reserved keywords.
  43.  *    This array contains the initial symbol table entries
  44.  *    for the user symbol table. The symbols are
  45.  *    basically convienient names that make writting
  46.  *    in 8031/8051 bearable.
  47.  *
  48.  *    The function syminit() inserts these entries into the
  49.  *    symbol table.
  50.  *
  51.  */
  52.  
  53. static struct symbol sinit[] = {
  54.     { "AC",        LABEL,        PSW(6),    NULL },
  55.     { "ACC",    LABEL,        ACC(0),    NULL },
  56.     { "B",        LABEL,        B(0),    NULL },
  57.     { "CY",        LABEL,        PSW(7),    NULL },
  58.     { "DPH",    LABEL,        0x83,    NULL },
  59.     { "DPL",    LABEL,        0x82,    NULL },
  60.     { "EA",        LABEL,        IE(7),    NULL },
  61.     { "ES",        LABEL,        IE(4),    NULL },
  62.     { "ET0",    LABEL,        IE(1),    NULL },
  63.     { "ET1",    LABEL,        IE(3),    NULL },
  64.     { "ET2",    LABEL,        IE(5),    NULL },
  65.     { "EX0",    LABEL,        IE(0),    NULL },
  66.     { "EX1",    LABEL,        IE(2),    NULL },
  67.     { "EXEN2",    LABEL,        T2CON(3),NULL },
  68.     { "EXF2",    LABEL,        T2CON(6),NULL },
  69.     { "F0",        LABEL,        PSW(5),    NULL },
  70.     { "IE",        LABEL,        IE(0),    NULL },
  71.     { "IE0",    LABEL,        TCON(1),NULL },
  72.     { "IE1",    LABEL,        TCON(3),NULL },
  73.     { "IP",        LABEL,        IP(0),    NULL },
  74.     { "IT0",    LABEL,        TCON(0),NULL },
  75.     { "IT1",    LABEL,        TCON(2),NULL },
  76.     { "OV",        LABEL,        PSW(2),    NULL },
  77.     { "P",        LABEL,        PSW(0),    NULL },
  78.     { "P0",        LABEL,        P0(0),    NULL },
  79.     { "P1",        LABEL,        P1(0),    NULL },
  80.     { "P2",        LABEL,        P2(0),    NULL },
  81.     { "P3",        LABEL,        P3(0),    NULL },
  82.     { "PCON",    LABEL,        0x87,    NULL },
  83.     { "PS",        LABEL,        IP(4),    NULL },
  84.     { "PSW",    LABEL,        PSW(0),    NULL },
  85.     { "PT0",    LABEL,        IP(1),    NULL },
  86.     { "PT1",    LABEL,        IP(3),    NULL },
  87.     { "PT2",    LABEL,        IP(5),    NULL },
  88.     { "PX0",    LABEL,        IP(0),    NULL },
  89.     { "PX1",    LABEL,        IP(2),    NULL },
  90.     { "RB8",    LABEL,        SCON(2),NULL },
  91.     { "RCAP2H",    LABEL,        0xCB,    NULL },
  92.     { "RCAP2L",    LABEL,        0xCA,    NULL },
  93.     { "RCLK",    LABEL,        T2CON(5),NULL },
  94.     { "REN",    LABEL,        SCON(4),NULL },
  95.     { "RI",        LABEL,        SCON(0),NULL },
  96.     { "RL2",    LABEL,        T2CON(0),NULL },
  97.     { "RS0",    LABEL,        PSW(3),    NULL },
  98.     { "RS1",    LABEL,        PSW(4),    NULL },
  99.     { "SBUF",    LABEL,        0x99,    NULL },
  100.     { "SCON",    LABEL,        SCON(0),NULL },
  101.     { "SM0",    LABEL,        SCON(7),NULL },
  102.     { "SM1",    LABEL,        SCON(6),NULL },
  103.     { "SM2",    LABEL,        SCON(5),NULL },
  104.     { "SP",        LABEL,        0x81,    NULL },
  105.     { "T2CON",    LABEL,        T2CON(0),NULL },
  106.     { "TB8",    LABEL,        SCON(3),NULL },
  107.     { "TCLK",    LABEL,        T2CON(4),NULL },
  108.     { "TCON",    LABEL,        TCON(0),NULL },
  109.     { "TF0",    LABEL,        TCON(5),NULL },
  110.     { "TF1",    LABEL,        TCON(7),NULL },
  111.     { "TF2",    LABEL,        T2CON(7),NULL },
  112.     { "TH0",    LABEL,        0x8C,    NULL },
  113.     { "TH1",    LABEL,        0x8D,    NULL },
  114.     { "TH2",    LABEL,        0xCD,    NULL },
  115.     { "TI",        LABEL,        SCON(1),NULL },
  116.     { "TL0",    LABEL,        0x8A,    NULL },
  117.     { "TL1",    LABEL,        0x8B,    NULL },
  118.     { "TL2",    LABEL,        0xCC,    NULL },
  119.     { "TMOD",    LABEL,        0x89,    NULL },
  120.     { "TR0",    LABEL,        TCON(4),NULL },
  121.     { "TR1",    LABEL,        TCON(6),NULL },
  122.     { "TR2",    LABEL,        T2CON(2),NULL }
  123. };
  124.  
  125. #define SINITSIZE    (sizeof(sinit)/sizeof(sinit[0]))
  126.  
  127. /* ----------------------------------------------------------------------
  128.  * opcode vectors:
  129.  *    These arrays contain the various opcodes for the
  130.  *    various forms an instruction may take.
  131.  *
  132.  *    The ordering of these opcodes is very critical to the
  133.  *    proper fuctioning of the assembler.
  134.  *
  135.  *    When a given form of an instruction is parsed, the parser
  136.  *    indexes one of these arrays by the correct amount and thus
  137.  *    obtains the correct opcode for the particular form.
  138.  *
  139.  */
  140.  
  141. static unsigned char acall[]=    { 0x11 };
  142. static unsigned char add[]=    { 0x28, 0x25, 0x26, 0x24 };
  143. static unsigned char addc[]=    { 0x38, 0x35, 0x36, 0x34 };
  144. static unsigned char ajmp[]=    { 0x01 };
  145. static unsigned char anl[]=    { 0x58, 0x55, 0x56, 0x54, 0x52, 0x53, 0x82,
  146.                   0xb0 };
  147. static unsigned char cjne[]=    { 0xb5, 0xb4, 0xb8, 0xb6 };
  148. static unsigned char clr[]=    { 0xe4, 0xc3, 0xc2 };
  149. static unsigned char cpl[]=    { 0xf4, 0xb3, 0xb2 };
  150. static unsigned char da[]=    { 0xd4 };
  151. static unsigned char dec[]=    { 0x14, 0x18, 0x15, 0x16 };
  152. static unsigned char div[]=    { 0x84 };
  153. static unsigned char djnz[]=    { 0xd8, 0xd5 };
  154. static unsigned char inc[]=    { 0x04, 0x08, 0x05, 0x06, 0xa3 };
  155. static unsigned char jb[]=    { 0x20 };
  156. static unsigned char jbc[]=    { 0x10 };
  157. static unsigned char jc[]=    { 0x40 };
  158. static unsigned char jmp[]=    { 0x73 };
  159. static unsigned char jnb[]=    { 0x30 };
  160. static unsigned char jnc[]=    { 0x50 };
  161. static unsigned char jnz[]=    { 0x70 };
  162. static unsigned char jz[]=    { 0x60 };
  163. static unsigned char lcall[]=    { 0x12 };
  164. static unsigned char ljmp[]=    { 0x02 };
  165. static unsigned char mov[]=    { 0xe8, 0xe5, 0xe6, 0x74, 0xf5, 0x75, 0xf8,
  166.                   0xa8, 0x78, 0x88, 0x85, 0x86, 0xf6, 0xa6,
  167.                   0x76, 0x90, 0xa2, 0x92 };
  168. static unsigned char movc[]=    { 0x93, 0x83 };
  169. static unsigned char movx[]=    { 0xe2, 0xe3, 0xe0, 0xf2, 0xf3, 0xf0 };
  170. static unsigned char mul[]=    { 0xa4 };
  171. static unsigned char nop[]=    { 0x00 };
  172. static unsigned char orl[]=    { 0x48, 0x45, 0x46, 0x44, 0x42, 0x43, 0x72,
  173.                   0xa0 };
  174. static unsigned char pop[]=    { 0xd0 };
  175. static unsigned char push[]=    { 0xc0 };
  176. static unsigned char ret[]=    { 0x22 };
  177. static unsigned char reti[]=    { 0x32 };
  178. static unsigned char rl[]=    { 0x23 };
  179. static unsigned char rlc[]=    { 0x33 };
  180. static unsigned char rr[]=    { 0x03 };
  181. static unsigned char rrc[]=    { 0x13 };
  182. static unsigned char setb[]=    { 0xd3, 0xd2 };
  183. static unsigned char sjmp[]=    { 0x80 };
  184. static unsigned char subb[]=    { 0x98, 0x95, 0x96, 0x94 };
  185. static unsigned char swap[]=    { 0xc4 };
  186. static unsigned char xch[]=    { 0xc8, 0xc5, 0xc6 };
  187. static unsigned char xchd[]=    { 0xd6 };
  188. static unsigned char xrl[]=    { 0x68, 0x65, 0x66, 0x64, 0x62, 0x63 };
  189.  
  190. /* ----------------------------------------------------------------------
  191.  * optable[]
  192.  *    This table contains opcodes, directives and a few reserved
  193.  *    symbols.
  194.  *
  195.  *    The second field is the keywords token value.
  196.  *
  197.  *    Unless the symbol is an opcode, the third field will
  198.  *    be NULL.
  199.  * 
  200.  *    The third field is a pointer to an array of opcode bytes.
  201.  *
  202.  */
  203.  
  204. static struct opcode optable[] = {
  205.     {"a",        A,    NULL        },
  206.     {"ab",        AB,    NULL        },
  207.     {"acall",    ACALL,    acall        },
  208.     {"add",        ADD,    add        },
  209.     {"addc",    ADDC,    addc        },
  210.     {"ajmp",    AJMP,    ajmp        },
  211.     {"anl",        ANL,    anl        },
  212.     {"byte",    D_BYTE,    NULL        },
  213.     {"c",        C,    NULL        },
  214.     {"cjne",    CJNE,    cjne        },
  215.     {"clr",        CLR,    clr        },
  216.     {"cpl",        CPL,    cpl        },
  217.     {"da",        DA,    da        },
  218.     {"dec",        DEC,    dec        },
  219.     {"div",        DIV,    div        },
  220.     {"djnz",    DJNZ,    djnz        },
  221.     {"dptr",    DPTR,    NULL        },
  222.     {"end",        D_END,    NULL        },
  223.     {"equ",        D_EQU,    NULL        },
  224.     {"flag",    D_FLAG,    NULL        },
  225.     {"inc",        INC,    inc        },
  226.     {"jb",        JB,    jb        },
  227.     {"jbc",        JBC,    jbc        },
  228.     {"jc",        JC,    jc        },
  229.     {"jmp",        JMP,    jmp        },
  230.     {"jnb",        JNB,    jnb        },
  231.     {"jnc",        JNC,    jnc        },
  232.     {"jnz",        JNZ,    jnz        },
  233.     {"jz",        JZ,    jz        },
  234.     {"lcall",    LCALL,    lcall        },
  235.     {"ljmp",    LJMP,    ljmp        },
  236.     {"mov",        MOV,    mov        },
  237.     {"movc",    MOVC,    movc        },
  238.     {"movx",    MOVX,    movx        },
  239.     {"mul",        MUL,    mul        },
  240.     {"nop",        NOP,    nop        },
  241.     {"org",        D_ORG,    NULL        },
  242.     {"orl",        ORL,    orl        },
  243.     {"pc",        PC,    NULL        },
  244.     {"pop",        POP,    pop        },
  245.     {"push",    PUSH,    push        },
  246.     {"r0",        R0,    NULL        },
  247.     {"r1",        R1,    NULL        },
  248.     {"r2",        R2,    NULL        },
  249.     {"r3",        R3,    NULL        },
  250.     {"r4",        R4,    NULL        },
  251.     {"r5",        R5,    NULL        },
  252.     {"r6",        R6,    NULL        },
  253.     {"r7",        R7,    NULL        },
  254.     {"ret",        RET,    ret        },
  255.     {"reti",    RETI,    reti        },
  256.     {"rl",        RL,    rl        },
  257.     {"rlc",        RLC,    rlc        },
  258.     {"rr",        RR,    rr        },
  259.     {"rrc",        RRC,    rrc        },
  260.     {"setb",    SETB,    setb        },
  261.     {"sjmp",    SJMP,    sjmp        },
  262.     {"skip",    D_SKIP,    NULL        },
  263.     {"subb",    SUBB,    subb        },
  264.     {"swap",    SWAP,    swap        },
  265.     {"word",    D_WORD,    NULL        },
  266.     {"xch",        XCH,    xch        },
  267.     {"xchd",    XCHD,    xchd        },
  268.     {"xrl",        XRL,    xrl        }
  269. };
  270.  
  271. #define OPTABSIZE    (sizeof(optable)/sizeof(struct opcode))
  272.  
  273. /* ----------------------------------------------------------------------
  274.  * strcase:
  275.  *    A case IN-sensitive string compare.
  276.  *
  277.  */
  278.  
  279. strcase(s,t)
  280. char *s,*t;
  281. {
  282.     for( ; (*s|040) == (*t|040); s++, t++)
  283.         if( *s == '\0') return(0);
  284.     return( (*s|040) - (*t|040) );
  285. }
  286.  
  287. /* ----------------------------------------------------------------------
  288.  * lookop:
  289.  *    Do a binary search through optable[], for a matching
  290.  *    symbol. Return the symbol found or NULL.
  291.  *
  292.  */
  293.  
  294. struct opcode *lookop(s)
  295. char *s;
  296. {
  297.     register int low,high,mid,cond;
  298.  
  299.     low = 0;
  300.     high = OPTABSIZE-1;
  301.     while( low<=high ) {
  302.         mid = (low+high)/2;
  303.         if( (cond = strcase(s,optable[mid].name)) < 0 )
  304.             high = mid-1;
  305.         else if(cond > 0 )
  306.             low = mid+1;
  307.         else
  308.             return(&optable[mid]);
  309.     }
  310.     return(NULL);
  311. }
  312.  
  313. /* ----------------------------------------------------------------------
  314.  * symtab, hash, looksym:
  315.  *    User symbol table routines.
  316.  *    symtab is the hash table for the user symbols.
  317.  *    (chaining is used for collision resolution).
  318.  *
  319.  */
  320.  
  321. static struct symbol *symtab[HASHTABSIZE];
  322.  
  323. static hash(s)
  324. char *s;
  325. {
  326.     register char *p;
  327.     register unsigned h=0,g;
  328.     for(p=s; *p; p++) {
  329.         h = (h<<4) + *p;
  330.         if( g = h&0xf0000000 ) {
  331.             h = h ^ (g >> 24);
  332.             h = h ^ g;
  333.         }
  334.     }
  335.     return( h % HASHTABSIZE );
  336. }
  337.  
  338. struct symbol *looksym(s)
  339. char *s;
  340. {
  341.     register struct symbol *ptr,*prev;
  342.     char *malloc(),*p;
  343.     register int hv;
  344.  
  345.     hv = hash(s);
  346.  
  347.     prev = NULL;
  348.     for(ptr=symtab[hv]; ptr; ptr = ptr->next) {
  349.         if( !strcmp(ptr->name,s) ) {
  350.             if( prev != NULL ) {
  351.                 prev->next = ptr->next;
  352.                 ptr->next = symtab[hv];
  353.                 symtab[hv] = ptr;
  354.             }
  355.             return(ptr);
  356.         }
  357.         prev = ptr;
  358.     }
  359.  
  360.     if( p = malloc(strlen(s)+1) )
  361.         strcpy(p,s);
  362.     else
  363.         error("Cannot allocate %d bytes",strlen(s)+1);
  364.  
  365.     ptr = (struct symbol *) malloc( sizeof(struct symbol) );
  366.     if( ptr == NULL )
  367.         error("Cannot allocate %d bytes",sizeof(struct symbol));
  368.     ptr->name = p;
  369.     ptr->type = UNDEF;
  370.     ptr->next = symtab[hv];
  371.     symtab[hv] = ptr;
  372.     return(ptr);
  373. }
  374.  
  375. /* ----------------------------------------------------------------------
  376.  * syminit:
  377.  *    Initializes the hash table, with the initial symbols from
  378.  *    sinit[]
  379.  *
  380.  */
  381.  
  382. syminit()
  383. {
  384.     register int i,hv;
  385.  
  386.     for(i=0; i<SINITSIZE; i++ ) {
  387.         hv = hash(sinit[i].name);
  388.         if( symtab[hv] )
  389.             sinit[i].next = symtab[hv];
  390.         symtab[hv] = &sinit[i];
  391.     }
  392. }
  393.