C:/Users/Dennis/src/lang/russell.orig/src/RIC_to_C/loc_tab.c

Go to the documentation of this file.
00001 /* A table containing information associated with virtual registers.    */
00002 /* Currently this simply maps locations to temporary names and possibly */
00003 /* expressions representing the current register value.                 */
00004 /* We use a chained hash table representation.                          */
00005 
00006 # define VERBOSE /* Print messages about unusual, but not illegal, situations */
00007 # undef VERBOSE
00008 
00009 # include <stdio.h>
00010 # include "../parm.h"
00011 # include "strings.h"
00012 # include "tables.h"
00013 # include "op_codes.h"
00014 
00015 extern char * tmp_name();
00016 extern int get_next_free();
00017 extern void free_tmp();
00018 
00019 # define HT_SIZE 16        /* Size of location hash table.                  */
00020                            /* Should be small, since traversals are common. */
00021 # define MOD_HT_SIZE(n) ((n) & (HT_SIZE - 1))
00022 # define RE_NIL ((struct reg_entry *)0)
00023 
00024 struct reg_entry {
00025     long vr;            /* Virtual register number */
00026     char * tmp_name;    /* Name of temporary implementing this virtual */
00027                         /* register.                                   */
00028                         /* Filled in only when requested.              */
00029     long tmp_num;       /* The number that is part of the preceding    */
00030                         /* temporary name.                             */
00031                         /* Valid only if tmp_name is not CS_NIL.       */
00032 #   define PREDEF_TMP -1
00033     char * vr_exp;        /* A C expression that evaluates to the contents */
00034                           /* of this temporary.                            */
00035                           /* Tmp_name is valid for reading only if this is */
00036                           /* CS_NIL.                                       */
00037     struct reg_entry * next; /* Next entry corr. to this hash bucket.  */
00038 };
00039 
00040 struct reg_entry * reg_tab[HT_SIZE];
00041 
00042 char * tl_expr;     /* Current expression to compute the value of TL */
00043                     /* This may contain other variables, and is thus */
00044                     /* handled seperately.                           */
00045 
00046 /* Apply f to each entry in reg_tab.  Return the concatenation of the */
00047 /* results.  Returns a string of the strings.[ch] variety, not a C    */
00048 /* string.                                                            */
00049 char * for_each_vr(f)
00050 char *((*f)());
00051 {
00052     register int i;
00053     register struct reg_entry *p;
00054     char * result = "";
00055 
00056     for (i = 0; i < HT_SIZE; i++) {
00057         for (p = reg_tab[i]; p != RE_NIL; p = p -> next) {
00058             result = concat(result, f(p));
00059         }
00060     }
00061     return(result);
00062 }
00063 
00064 /* Return code to insure that the contents of virtual register p are   */
00065 /* reflected in its associated temporary (or a new one if it had none) */
00066 char * flush_expr(p)
00067 struct reg_entry *p;
00068 {
00069     char * result;
00070 
00071     char * assign;
00072     if (p -> vr_exp != CS_NIL) {
00073         if (p -> tmp_name == CS_NIL) {
00074             int tmp = get_next_free();
00075 
00076             p -> tmp_num = tmp;
00077             p -> tmp_name = tmp_name(tmp);
00078         }
00079         if (p -> vr == AR || p -> vr == GF) {
00080             assign = " = (word *)";
00081         } else {
00082             assign = " = (word)";
00083         }
00084         result = concat(concat(p -> tmp_name, assign),
00085                         concat(p -> vr_exp, ";\n"));
00086         p -> vr_exp = CS_NIL;
00087     } else {
00088         result = "";
00089     }
00090     return(result);
00091 }
00092 
00093 static long special_reg;
00094 
00095 /* The same, but ignore special_reg */
00096 char * flush_expr_except_special_reg(p)
00097 struct reg_entry *p;
00098 {
00099     if (p -> vr != special_reg) {
00100         return(flush_expr(p));
00101     } else {
00102         return("");
00103     }
00104 }
00105 
00106 /* Flush, unless the expression is a constant.            */
00107 /* We assume that compound expressions are parenthesized. */
00108 char * flush_expr_except_const(p)
00109 struct reg_entry * p;
00110 {
00111     char * exp = p -> vr_exp;
00112     register char first;
00113     
00114     if (exp != CS_NIL) {
00115         GET_FIRST(exp, first);
00116         if (first != '-' && first != '"' && (first > '9' || first < '0')) {
00117             return(flush_expr(p));
00118         } else {
00119             return("");
00120         }
00121     } else {
00122         return("");
00123     }
00124 }
00125 
00126 /* The same, but ignore special_reg */
00127 char * flush_non_const_except_special_reg(p)
00128 struct reg_entry *p;
00129 {
00130     if (p -> vr != special_reg) {
00131         return(flush_expr_except_const(p));
00132     } else {
00133         return("");
00134     }
00135 }
00136 
00137 
00138 /* Return code to store all virtual register values in appropriate */
00139 /* temporaries.                                                    */
00140 char * flush_all_exprs()
00141 {
00142     return(for_each_vr(flush_expr));
00143 }
00144 
00145 /* The same, but exclude vr */
00146 char * flush_all_except(vr_no)
00147 long vr_no;
00148 {
00149     special_reg = vr_no;
00150     return(for_each_vr(flush_expr_except_special_reg));
00151 }
00152 
00153 /* Flush all nonconstant expressions */
00154 char * flush_all_non_const()
00155 {
00156     return(for_each_vr(flush_expr_except_const));
00157 }
00158 
00159 /* The same, but exclude vr */
00160 char * flush_all_non_const_except(vr_no)
00161 long vr_no;
00162 {
00163     special_reg = vr_no;
00164     return(for_each_vr(flush_non_const_except_special_reg));
00165 }
00166 
00167 /* Return code to store the given virtual register in its temporary */
00168 char * flush_vr(vr_no)
00169 long vr_no;
00170 {
00171     int indx = MOD_HT_SIZE(vr_no);
00172     register struct reg_entry * p = reg_tab[indx];
00173 
00174     while(p != RE_NIL && p -> vr != vr_no) p = p -> next;
00175     if (p == RE_NIL) {
00176         /* Doesn't exist.  We assume it's dead. */
00177         if (!(vr_no & ARG_FLAG)) {
00178             fprintf(stderr, "Removing nonexistent virtual register %d\n",
00179                     vr_no);
00180         }
00181         return("");
00182     } else {
00183         return(flush_expr(p));
00184     }
00185 }
00186 
00187 /* Return the entry corresponding to a given register number, or RE_NIL */
00188 /* if there is none.                                                    */
00189 struct reg_entry * get_entry(vr_no)
00190 long vr_no;
00191 {
00192     int indx = MOD_HT_SIZE(vr_no);
00193     register struct reg_entry * p = reg_tab[indx];
00194 
00195     while(p != RE_NIL && p -> vr != vr_no) p = p -> next;
00196     return(p);
00197 }
00198 
00199 /* Return the temporary name associated with a virtual register. */
00200 char * get_name(vr_no)
00201 long vr_no;
00202 {
00203     struct reg_entry * p = get_entry(vr_no);
00204 
00205     if (p == RE_NIL) {
00206         fprintf(stderr, "No temporary for register %d\n", vr_no);
00207         return("tmp???");
00208     } else {
00209         if (p -> tmp_name == CS_NIL) {
00210             int tmp = get_next_free();
00211 
00212             p -> tmp_num = tmp;
00213             p -> tmp_name = tmp_name(tmp);
00214         }
00215         return(p -> tmp_name);
00216     }
00217 }
00218 
00219 /* Return the temporary name or expression associated with a */
00220 /* virtual register.                                         */
00221 char * get_expr(vr_no)
00222 long vr_no;
00223 {
00224     struct reg_entry * p = get_entry(vr_no);
00225 
00226     if (p == RE_NIL) {
00227         fprintf(stderr, "No temporary for register %d\n", vr_no);
00228         return("tmp???");
00229     } else {
00230         if (p -> vr_exp != CS_NIL) {
00231             return(p -> vr_exp);
00232         }
00233         if (p -> tmp_name == CS_NIL) {
00234             int tmp = get_next_free();
00235 
00236             fprintf(stderr, "Referencing uninitialized temporary %d\n", vr_no);
00237             p -> tmp_num = tmp;
00238             p -> tmp_name = tmp_name(tmp);
00239         }
00240         return(p -> tmp_name);
00241     }
00242 }
00243 
00244 /* Add a mapping of a virtual register to the given temporary name */
00245 /* and number.                                                     */
00246 void add_vr(vr_no, name, num)
00247 long vr_no;
00248 char * name;
00249 long num;
00250 {
00251     int indx = MOD_HT_SIZE(vr_no);
00252     register struct reg_entry * p = reg_tab[indx];
00253     register struct reg_entry * q = p;
00254 
00255     while(q != RE_NIL && q -> vr != vr_no) q = q -> next;
00256     if (q != RE_NIL) {
00257         fprintf(stderr, "Redefinition of register %d\n", vr_no);
00258         p -> tmp_name = name;
00259         p -> tmp_num = num;
00260     } else {
00261         q = (struct reg_entry *) GC_malloc( sizeof (struct reg_entry) );
00262         q -> vr = vr_no;
00263         q -> tmp_name = name;
00264         q -> tmp_num = num;
00265         q -> next = p;
00266         reg_tab[indx] = q;
00267     }
00268 }
00269 
00270 /* Add an expression for the value of a virtual register that was previously */
00271 /* entered into the table.                                                   */
00272 void add_vr_def(vr_no, expr)
00273 long vr_no;
00274 char * expr;
00275 {
00276     int indx = MOD_HT_SIZE(vr_no);
00277     register struct reg_entry * p = reg_tab[indx];
00278 
00279     while(p != RE_NIL && p -> vr != vr_no) p = p -> next;
00280     if (p == RE_NIL) {
00281         fprintf(stderr, "Adding definition of undeclared v. register %d\n",
00282                 vr_no);
00283         add_undef_vr(vr_no);
00284         add_vr_def(vr_no, expr);
00285         return;
00286     }
00287     p -> vr_exp = expr;
00288 }
00289 
00290 /* Remove the expression associated with a virtual register. */
00291 void rem_vr_def(vr_no)
00292 long vr_no;
00293 {
00294     int indx = MOD_HT_SIZE(vr_no);
00295     register struct reg_entry * p = reg_tab[indx];
00296 
00297     while(p != RE_NIL && p -> vr != vr_no) p = p -> next;
00298     if (p == RE_NIL) {
00299 #       ifdef VERBOSE
00300           fprintf(stderr, "Removing definition of undeclared v. register %d\n",
00301                   vr_no);
00302 #       endif
00303         return;
00304     }
00305     p -> vr_exp = CS_NIL;
00306 }
00307 
00308 
00309 /* Remove the mapping for the given virtual register.  Mark the */
00310 /* corresponding temporary as free.                             */
00311 /* If the register is predefined, just invalidate the           */
00312 /* expression for its contents.                                 */
00313 void rem_vr(vr_no)
00314 long vr_no;
00315 {
00316     int indx = MOD_HT_SIZE(vr_no);
00317     register struct reg_entry **current_p = reg_tab + indx;
00318     register struct reg_entry * current = *current_p;
00319 
00320     while (current != RE_NIL && current -> vr != vr_no) {
00321         current_p = &(current -> next);
00322         current = *current_p;
00323     }
00324     if (current == RE_NIL) {
00325 #       ifdef VERBOSE
00326           fprintf(stderr,
00327                   "Deleted nonexistent virtual register mapping for %d\n",
00328                   vr_no);
00329 #       endif
00330     } else {
00331         if (current -> tmp_name != CS_NIL) {
00332             if (current -> tmp_num  ==  PREDEF_TMP) {
00333                 current -> vr_exp = CS_NIL;
00334             } else {
00335                 dead_tmp(current -> tmp_num);
00336                 *current_p = current -> next;
00337             }
00338         } else {
00339             *current_p = current -> next;
00340         }
00341     }
00342 }
00343 
00344 /* Add a definition of a predefined virtual register */
00345 # define add_predef(vr_no, name) add_vr(vr_no, name, PREDEF_TMP, CS_NIL);
00346 
00347 void init_tmps()
00348 {
00349     add_predef(AR, "AR");
00350     add_predef(GF, "GF");
00351     add_predef(UN, "0x0");
00352     add_predef(SP, "sp??");  /* Should not be used */
00353     add_predef(RL, "RL");
00354     add_predef(TL, "TL");  /* Rarely used, we hope */
00355     add_predef(C0, "0L");
00356     add_predef(C1, "1L");
00357     add_predef(C2, "2L");
00358     add_predef(C3, "3L");
00359     add_predef(C4, "4L");
00360 }

Generated on Fri Jan 25 10:39:47 2008 for russell by  doxygen 1.5.4