home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 357_01 / cstar1.exe / IN.C < prev    next >
C/C++ Source or Header  |  1991-06-18  |  11KB  |  474 lines

  1. /*    C* input qualification routines.
  2.  
  3.     source:  in.c
  4.     started: October 26, 1985
  5.     version:
  6.         February 22, 1989
  7.  
  8.     PUBLIC DOMAIN SOFTWARE
  9.  
  10.     The CSTAR program was placed in    the public domain on June 15, 1991,
  11.     by its author and sole owner,
  12.  
  13.         Edward K. Ream
  14.         1617 Monroe Street
  15.         Madison, WI 53711
  16.         (608) 257-0802
  17.  
  18.     CSTAR may be used for any commercial or non-commercial purpose.
  19.  
  20.     See cstar.h or cstar.c for a DISCLAIMER OF WARRANTIES.
  21. */
  22. #include "cstar.h"
  23.  
  24. /*
  25.     Declare routines of this file.
  26. */
  27. bool        is_reserved    (register char * name, int length);
  28. struct x_ex *    x_exists    (struct node *q);
  29.  
  30. static bool    am_match(register int mode, register struct node * loc);
  31. static bool    is_mpc    (register struct node *p);
  32. static bool    is_m0    (register struct node *p);
  33. static bool    is_m1    (register struct node *p);
  34. static bool    is_m2    (register struct node *p);
  35. static bool    is_m3    (register struct node *p);
  36. static bool    is_m4    (register struct node *p);
  37. static bool    is_m5    (register struct node *p);
  38. static bool    is_m6    (register struct node *p);
  39. static bool    is_m70    (register struct node *p);
  40. static bool    is_m71    (register struct node *p);
  41. static bool    is_m72    (register struct node *p);
  42. static bool    is_m73    (register struct node *p);
  43. static bool    is_m74    (register struct node *p);
  44.  
  45. /*
  46.     Declare existence table defined in t2.s.
  47. */
  48. extern int * x_lookup[];
  49.  
  50. /*
  51.     Declare the reserved word index table which are defined in t1.s
  52.     The dimension 2 is just a dummy value.
  53. */
  54. #ifdef DRI
  55. extern char * rwx_tab [2];
  56. #else
  57. extern struct t1_tab_struct * rwx_tab [2];
  58. #endif
  59.  
  60. /*
  61.     Use the tables in t1.s to see if name[] contains a reserved word.
  62.     If so, set t_type, t_subtype and return TRUE.
  63.     Otherwise, set t_type to NULL and return FALSE.
  64. */
  65. bool
  66. is_reserved(register char * name, int length)
  67. {
  68. #ifdef DRI
  69.     register byte * p;
  70.     register char c;
  71. #else
  72.     char c;
  73.     register struct t1_tab_struct   * p;
  74.     register struct t1_entry_struct * e;
  75.     register int i, n;
  76.     int t;
  77. #endif
  78.  
  79.     TRACEP("is_reserved", printf("(%s, %d)\n", name, length));
  80.  
  81.     c = *name;
  82.     if (c == '\0') {
  83.         goto not_found;
  84.     }
  85.  
  86. #ifdef DRI
  87.     /* Fetch the pointer. */
  88.     p = rwx_tab [c - 'A'];
  89.  
  90.  
  91.     /* Search for the proper subtable. */
  92.     for (;;) {
  93.  
  94.         TRACEP("is_reserved", printf("rwx_tab subtable: p = %p\n", p));
  95.  
  96.         if (p == NULL) {
  97.             goto not_found;
  98.         }
  99.  
  100.         if (*(int *)p > length) {
  101.             goto not_found;
  102.         }
  103.         else if (length == *(int *)p) {
  104.             break;
  105.         }
  106.         else {
  107.             /* Point at the address of the next subtable. */
  108.             p += 2;
  109.  
  110.             /* Fetch the address of the next subtable. */
  111.             p = * (char **) p;
  112.         }
  113.     }
  114.  
  115.     TRACEP("is_reserved", printf("subtable found: p = %p\n", p));
  116.  
  117.     while (*p != '\0') {
  118.  
  119.         TRACEP("is_reserved", printf("compare: %s, %s\n", name, p));
  120.         TRACEP("is_reserved", printf("note: length = %d\n", length, p));
  121.  
  122.         if(str_eq(name, p)) {
  123.  
  124.             /* Found. */
  125.             p         += length + 1;
  126.             t_type     = (int) *p++;
  127.             t_subtype  = (int) *p;
  128.             t_type    &= 0xff;
  129.             t_subtype &= 0xff;
  130.  
  131.             TRACEP("is_reserved",
  132.             printf("return %d, %d\n", t_type, t_subtype));
  133.  
  134.             return TRUE;
  135.         }
  136.         /* Skip over the entry. */
  137.         p += length + 3;
  138.  
  139.         TRACEP("is_reserved", printf("skip to: p = %p\n", p));
  140.     }
  141.  
  142. #else
  143.  
  144.     /* Search for the proper subtable. */
  145.     for (p = rwx_tab [c - 'A']; ; p++) {
  146.  
  147.         TRACEP("is_reserved", printf("p = %p\n", p));
  148.  
  149.         if (p == NULL) {
  150.             goto not_found;
  151.         }
  152.  
  153.         TRACEP("is_reserved", printf("p -> t_strlen = %d\n",
  154.             p -> t_strlen));
  155.  
  156.         if (p == NULL || p -> t_strlen > length) {
  157.             goto not_found;
  158.         }
  159.         else if (p -> t_strlen == length) {
  160.             break;
  161.         }
  162.     }
  163.  
  164.     /* A subtable with the right length has been found. */
  165.     n = p  -> t_entries;
  166.     for (i = 0, e = p  -> t_entry; i < n; e++, i++) {
  167.  
  168.         TRACEP("is_reserved",
  169.             printf("compare: %s, %s\n", name, e -> e_string));
  170.  
  171.         t = strcmp(name, e -> e_string);
  172.         if (t == 0) {
  173.  
  174.             /* Found. */
  175.             t_type    = ((int) (e -> e_arg1)) & 0xff;
  176.             t_subtype = ((int) (e -> e_arg2)) & 0xff;
  177.  
  178.             TRACEP("is_reserved",
  179.                 printf("return %d, %d\n", t_type, t_subtype));
  180.  
  181.             return TRUE;
  182.         }
  183.         /* -----
  184.         else if (t > 0) {
  185.             goto not_found;
  186.         }
  187.         ----- */
  188.     }
  189. #endif
  190.  
  191. not_found:
  192.     t_type = 0;
  193.     t_subtype = 0;
  194.  
  195.     TRACEP("is_reserved_ret", printf("ISR: returns 0\n"));
  196.     return FALSE;
  197. }
  198.  
  199.  
  200. /*
  201.     Use the tables in t2.s to determine whether a particular
  202.     operator operand combination exists
  203.  
  204.     Return a pointer to a static structure containing various
  205.     results of the operation, including an operation
  206.     length to attach to the code node, a machine code, etc.
  207.  
  208.     Return NULL if not found.
  209.  
  210.     Op is the desired X_TOK, and arg1 and arg2 the arguments, if any.
  211. */
  212. struct x_ex *
  213. x_exists(struct node *q)
  214. {
  215.     register struct node * arg1, * arg2;
  216.     register unsigned int val;
  217.     register int *p;
  218.     int op, l1, l2;
  219.     static struct x_ex x;
  220.  
  221.     TRACEP("x_exists", printf("(%d, %p, %p)\n", op, arg1, arg2));
  222.  
  223.     op = q -> n_xtype;
  224.     arg1 = q -> n_arg1;
  225.     arg2 = q -> n_arg2;
  226.     for (p = x_lookup[op]; p[0] >= 0 ;p += X_T_FRAME) {
  227.  
  228.         TRACE("x_exists", printf("entry: %d, %d, %d, %d, %d, %d\n",
  229.                 p[0], p[1], p[2], p[3], p[4], p[5]));
  230.  
  231.         /* here we check address modes and continue if no good */
  232.         if (!am_match(p[3], arg1) || !am_match(p[4], arg2)) {
  233.             continue;
  234.         }
  235.         x.xlen = 0;
  236.  
  237.         TRACEP("x_exists", printf("entry accepted\n"));
  238.  
  239.         /* check up on first argument */
  240.         if (p[1] != NONE_AM) {
  241.             l1 = mlen(arg1);
  242.             if (p[1] > ANY_AM) {
  243.                 /* is mode1 or mode2, and am_match will check */
  244.                 /* see note in t2.c */
  245.             }
  246.             else if (l1 & ~p[1]) {
  247.                 g_error(q, "argument length error");
  248.                 return NULL;
  249.             }
  250.             if (p[0] == 1) {
  251.                 x.xlen = (byte) l1;
  252.             }
  253.         }
  254.  
  255.         /* check up on second argument */
  256.         if (p[2] != NONE_AM) {
  257.             l2 = mlen(arg2);
  258.             if (p[2] > ANY_AM) {
  259.                 if (p[2] == AS_1_AM && l1 != l2) {
  260.                     g_error(q, "length mismatch");
  261.                     return NULL;
  262.                 }
  263.             }
  264.             else if (l2 & ~p[2]) {
  265.                 g_error(q, "argument length error");
  266.                 return NULL;
  267.             }
  268.             if (p[0] == 2) {
  269.                 x.xlen = (byte) l2;
  270.             }
  271.         }
  272.         return &x;
  273.     }
  274.     g_error(q, "opcode doesn't apply to operand combination");
  275.     return NULL;
  276. }
  277.  
  278. /*
  279.     Return TRUE if loc_node is of the indicated address mode.
  280. */
  281. static bool
  282. am_match(register int mode, register struct node * loc)
  283. {
  284.     TRACEP("am_match", printf("(mode %d, loc %p)\n", mode, loc));
  285.  
  286.     /* make sure loc is nonnull */
  287.     if (loc == NULL) {
  288.         return mode == NONE_AM;
  289.     }
  290.     else if (loc -> n_type != ID_TOK) {
  291.         g_error(NULL, "internal: am_match: not a loc_node");
  292.         return FALSE;
  293.     }
  294.  
  295.     /* here, loc is guaranteed to be nonnull */
  296.     /* WARNING: loc is a ULABEL?? (ULABELS don't even get looked up now) */
  297.     switch (mode) {
  298.  
  299.     case NONE_AM:    return    FALSE;
  300.     case GEN_AM:    return    TRUE;
  301.     case MEM_AM:    return    !is_m0(loc) && !is_m1(loc);
  302.     case ALT_AM:    return    !is_mpc(loc) && !is_m74(loc);
  303.     case DALT_AM:    return    !is_m1(loc);
  304.     case MALT_AM:    return    !is_m0(loc) && !is_m1(loc) &&
  305.                 !is_mpc(loc) && !is_m74(loc);
  306.     case DATA_AM:    return    !is_m1(loc);
  307.     case INC_AM:    return    is_m3(loc);
  308.     case DEC_AM:    return    is_m4(loc);
  309.     case DISP_AM:    return    is_m5(loc);
  310.     case CONTROL_AM: return    !is_m0(loc) && !is_m1(loc) &&
  311.                 !is_m3(loc) && !is_m4(loc) &&
  312.                 !is_m74(loc);
  313.     case AN_AM:    return    is_m1(loc);
  314.     case DN_AM:    return    is_m0(loc);
  315.     case USP_AM:    return  0;        /* WARNING: */
  316.  
  317.     case IMM_AM:    return    is_m74(loc);
  318.  
  319.     /* 
  320.         WARNING: these next tests will malfunction under some 
  321.         circumstances when the local-name option is on, since they 
  322.         don't check the offset implied by the name.  
  323.  
  324.         See x_addpsi(), resolve(), or gen_pp() for examples of how 
  325.         this is done; it involves finding the offset in the parent
  326.         ID node.  The interpretation and treatment of such offsets
  327.         depends somewhat on the storage class.  If equates are put
  328.         in, a new storage class should be created for them.
  329.     */
  330.     case IMM8_AM:    return    is_m74(loc) && !loc -> n_cid &&
  331.                 loc -> n_const >= -128 && loc -> n_const <= 127;
  332.     case IMM16_AM:    return    is_m74(loc) && !loc -> n_cid &&
  333.             loc -> n_const >= -32768 && loc -> n_const <= 32767;
  334.     case Q8BIT_AM:    return    is_m74(loc) && !loc -> n_cid &&
  335.                 loc -> n_const >= -128 && loc -> n_const <= 127;
  336.     case QUICK8_AM:    return    is_m74(loc) && !loc -> n_cid &&
  337.                 loc -> n_const >= 1 && loc -> n_const <= 8;
  338.     case BIT31_AM:    return    is_m74(loc) && !loc -> n_cid &&
  339.                 loc -> n_const >= 0 && loc -> n_const <= 31;
  340.     case TRAP15_AM:    return    is_m74(loc) && !loc -> n_cid &&
  341.                 loc -> n_const >= 0 && loc -> n_const <= 15;
  342.  
  343.             /* WARNING: how do we represent a reg list??? */
  344.     case MOVEM2R_AM:
  345.     case MOVER2M_AM:
  346.     case REGLIST_AM: return    FALSE;
  347.     
  348.     case CCR_AM:    return    loc && loc -> n_reg1 == R_CCR;
  349.     case SR_AM:    return    loc && loc -> n_reg1 == R_SR;
  350.  
  351.     default:
  352.         printf("am_match: bad mode %d\n", mode);
  353.         fatal("");
  354.     }
  355. }
  356.  
  357. /*
  358.     The following 16 routines follow page 79 of the 68000 book.
  359.  
  360.     What they will eventually return, of course, is an index into a
  361.     set of sub-opcode bit masks.
  362. */
  363. static bool
  364. is_mpc(register struct node *p)
  365. {
  366.     SL_DISABLE();
  367.     return    p -> n_reg1 == R_PC;
  368. }
  369.  
  370. static bool
  371. is_m0(register struct node *p)
  372. {
  373.     SL_DISABLE();
  374.         /* Data register. */
  375.     return    !(p -> n_mode) && is_dreg(p -> n_reg1) && !p -> n_reg2;
  376. }
  377.  
  378. static bool
  379. is_m1(register struct node *p)
  380. {
  381.     SL_DISABLE();
  382.         /* Address register. */
  383.     return    !(p -> n_mode) && is_areg(p -> n_reg1) && !p -> n_reg2;
  384. }
  385.  
  386. static bool
  387. is_m2(register struct node *p)
  388. {
  389.     SL_DISABLE();
  390.         /* Address register indirect. */
  391.     return    p -> n_mode == EA_MODE && is_areg(p -> n_reg1) &&
  392.         !(p -> n_reg2) && !(p -> n_const);
  393. }
  394.  
  395. static bool
  396. is_m3(register struct node *p)
  397. {
  398.     SL_DISABLE();
  399.         /* Address register indirect with post increment. */
  400.     return p -> n_mode == EAPSI_MODE;
  401. }
  402.  
  403. static bool
  404. is_m4(register struct node *p)
  405. {
  406.     SL_DISABLE();
  407.         /* Address register indirect with pre decrement. */
  408.     return p -> n_mode == EAPRD_MODE;
  409. }
  410.  
  411. static bool
  412. is_m5(register struct node *p)
  413. {
  414.     SL_DISABLE();
  415.         /* Address register indirect with displacement. */
  416.     return    p -> n_mode == EA_MODE &&
  417.         is_areg(p -> n_reg1) && !(p -> n_reg2) && p -> n_const;
  418. }
  419.  
  420. static bool
  421. is_m6(register struct node *p)
  422. {
  423.     SL_DISABLE();
  424.         /* Address register indirect with index. */
  425.     return    p -> n_mode == EA_MODE &&
  426.         is_areg(p -> n_reg1) && p -> n_reg2;
  427. }
  428.  
  429. static bool
  430. is_m70(register struct node *p)
  431. {
  432.     SL_DISABLE();
  433.         /* Absolute short. */
  434.  
  435.     /* WARNING:  all abolute long for now; this will take fiddling. */
  436.     /* note that since p is a loc_node, its C type is available, and
  437.         the constant value is also available */
  438.     return FALSE;
  439. }
  440.  
  441. static bool
  442. is_m71(register struct node *p)
  443. {
  444.     SL_DISABLE();
  445.         /* Absolute long. */
  446.     return    !(p -> n_mode) && p -> n_cid;
  447. }
  448.  
  449. static bool
  450. is_m72(register struct node *p)
  451. {
  452.     SL_DISABLE();
  453.         /* Program counter with displacement. */
  454.     return    p -> n_mode == EA_MODE &&
  455.         p -> n_reg1 == R_PC && !(p -> n_reg2);
  456. }
  457.  
  458. static bool
  459. is_m73(register struct node *p)
  460. {
  461.     SL_DISABLE();
  462.         /* Program counter with index. */
  463.     return    p -> n_mode == EA_MODE &&
  464.         p -> n_reg1 == R_PC && p -> n_reg2;
  465. }
  466.  
  467. static bool
  468. is_m74(register struct node *p)
  469. {
  470.     SL_DISABLE();
  471.         /* Immediate. */
  472.     return    !(p -> n_mode) && !(p -> n_reg1);
  473. }
  474.