C:/Users/Dennis/src/lang/russell.orig/src/pass5c/codeutil.c

Go to the documentation of this file.
00001 #include "parm.h"
00002 
00003 #include "stree/ststructs.mh"
00004 
00005 #include "pass4/sigs.h"
00006 
00007 #include "codeutil.h"
00008 #include <stdio.h>
00009 
00010 #define UNDEFNAME 0
00011 
00012 extern FILE * Voutfile;
00013 
00014 extern int comp_index;
00015 
00016 extern char * entry_name;
00017 
00018 char *
00019 Vnewlabel (name)
00020 char * name;
00021 {
00022     static int unique=0;
00023     char strbuff[128];
00024     char * result;
00025 
00026 #ifdef DEBUG
00027     sprintf (strbuff, "l_%s_%d_%s", entry_name, unique++,name);
00028 #else
00029     sprintf (strbuff, "L_%s_%d", entry_name, unique++);
00030 #endif
00031     result = (char *)malloc (strlen(strbuff)+1);
00032     strcpy (result,strbuff);
00033     return (result);
00034 }
00035 
00036 char *
00037 new_global_label (name)
00038 char * name;
00039 {
00040     static int unique=0;
00041     char strbuff[128];
00042     char * result;
00043 
00044     sprintf (strbuff, "G_%s_%d_%s", entry_name, unique++, name);
00045     result = (char *)malloc (strlen(strbuff)+1);
00046     strcpy (result,strbuff);
00047     return (result);
00048 }
00049 
00050 /* Generate a call to mcount to count function calls */
00051 void
00052 Vcall_mcount()
00053 {
00054     char * count_ptr = Vnewlabel("mcount_tmp");
00055 
00056     /* Allocate temporary */
00057         fputs("\t.data\n\t.align\t2\n", Voutfile);
00058         fprintf(Voutfile, "%s:\t.long\t0\n", count_ptr);
00059         fputs("\t.text\n", Voutfile);
00060     /* Generate call */
00061         fprintf(Voutfile, "\tmovab\t%s,r0\n", count_ptr);
00062         fputs("\t.globl\tmcount\n\tjsb\tmcount\n", Voutfile);
00063 }
00064 
00065 /*
00066  *  Given a parameter node, return either a type checked selection
00067  * of put from the parameter type, or NIL if no appropriate function
00068  * exists.  (Used for trace code).  NIL is also returned if the
00069  * parameter type is not an identifier.  If Flag is true, only
00070  * global identifiers will be accepted.
00071  */
00072 NODE *
00073 mk_put_selection(p, Fflag)
00074 NODE * p;
00075 boolean Fflag;
00076 {
00077     NODE * arg_id;
00078     NODE * arg_list;
00079     NODE * appl;
00080     NODE * type;
00081     NODE * comp_sig;  /* Signature of put */
00082     NODE * result;
00083     extern NODE * id_put;
00084 
00085     ASSERT(p -> kind == PARAMETER, "mk_put_selection: bad parameter\n");
00086     switch (p -> par_signature -> kind) {
00087         case VARSIGNATURE:
00088             type = p -> par_signature -> var_denotation;
00089             break;
00090         case VALSIGNATURE:
00091             type = p -> par_signature -> val_denotation;
00092             break;
00093         default:
00094             return(NIL);
00095     }
00096     if (type -> kind != LETTERID && type -> kind != OPRID
00097         || type -> sel_type != NIL) return(NIL);
00098     tl_findsig(type);
00099     if (Fflag) {
00100         if (type -> id_last_definition -> level != 0) {
00101             return (NIL);
00102         }
00103     }
00104     if (type -> signature == ERR_SIG) return(NIL);
00105 
00106     if (p -> par_id != NIL) {
00107         arg_id = copynode(p -> par_id);
00108     } else {
00109         arg_id = mknode(LETTERID, UNDEFNAME);
00110     }
00111     arg_id -> id_last_definition = p;
00112     arg_id -> id_def_found = TRUE;
00113     arg_id -> signature = p -> par_signature;
00114     arg_id -> sig_done = SIG_DONE;
00115     arg_list = mklist(arg_id, -1);
00116     result = copynode(id_put);
00117     result -> sel_type = type;
00118     appl = lock(mknode(APPLICATION, result, arg_list));
00119     comp_sig =
00120       getcomp(type -> signature, id_put, type, NIL, NIL, appl, TRUE);
00121     vfree(unlock(appl));
00122     if (comp_sig == NIL) {
00123         return(NIL);
00124     }
00125     result -> sel_index = comp_index;
00126     result -> id_def_found = TRUE;
00127     result -> signature = comp_sig;
00128     result -> sig_done = SIG_DONE;
00129     return(result);
00130 }
00131 
00132 char * Gbase;       /* implicit parameters to the following */
00133 boolean GFflag;
00134 int Goffset;
00135 
00136 /*
00137  *  Generate call to trace an argument
00138  *         param is the parameter node
00139  *         Gbase is a base register for accessing argument
00140  *              - the first argument should be at an offset of 4
00141  *         Goffset is the current offset from Gbase; it is decremented
00142  *              by this routine
00143  *         GFflag is true iff we are generating jsb code.
00144  */
00145 Varg_trace(param)
00146 NODE * param;
00147 {
00148     NODE * put_sel = mk_put_selection(param, GFflag);
00149 
00150     /* Push print function value */
00151       if (put_sel != NIL) {
00152         Vexpression(put_sel);
00153       } else {
00154         fputs("\t.globl\t_FV_put_any\n\tpushl\t$_FV_put_any\n", Voutfile);
00155       }
00156 
00157     /* Push argument value */
00158       fprintf(Voutfile, "\tpushl\t%d(%s)\n", Goffset, Gbase);
00159       Goffset -= 4;
00160 
00161     /* Call add_arg_entry */
00162       fputs("\t.globl\t_add_arg_entry\n\tcalls\t$2, _add_arg_entry\n",
00163             Voutfile);
00164 }
00165 
00166 /*
00167  *  Generate calls to trace function entry
00168  *         name is the name of the routine being entered
00169  *         params is the parameter list to the function construction
00170  *         Fflag is true iff we are generating jsb code.
00171  */
00172 Ventry_trace(name, params, Fflag)
00173 char * name;
00174 NODE * params;
00175 boolean Fflag;
00176 {
00177     char * name_loc = Vnewlabel("rn");
00178 
00179     /* Add argument information in reverse order */
00180         if (Fflag) {
00181             Gbase = "sp";
00182             Goffset = 4 * length(params) + 4 /* compensate for print fn */;
00183         } else {
00184             Gbase = "ap";
00185             Goffset = 4 * length(params);
00186         }
00187         GFflag = Fflag;
00188         maprlist(params, Varg_trace);
00189 
00190     fputs("\t.data\n", Voutfile);
00191     fprintf(Voutfile, "%s:\t.ascii\t\"%s\\0\"\n", name_loc, name);
00192     fputs("\t.text\n", Voutfile);
00193     fprintf(Voutfile, "\tpushl\t$%s\n", name_loc);
00194     fputs("\t.globl\t_add_func_entry\n\tcalls\t$1,_add_func_entry\n",
00195           Voutfile);
00196 }
00197 
00198 /* Generate call to trace function exit */
00199 Vexit_trace()
00200 {
00201     fputs("\t.globl\t_rem_func_entry\n\tcalls\t$0,_rem_func_entry\n",
00202           Voutfile);
00203 }
00204 
00205 /*
00206  *  allocate temporary register and return the register name
00207  *
00208  *  "register name" may be a label if there are no registers
00209  * available.
00210  *
00211  *   Vreg_bit is set to the mask bit corresponding to the register,
00212  * or 0 if a memory location is used.
00213  */
00214 
00215 # define NREGS 3
00216 
00217 static char * regs[NREGS] = {"r6","r7","r8"};
00218 
00219 static int mask_bit[NREGS] = {R6, R7, R8};
00220 
00221 static boolean reg_free[NREGS] = {TRUE, TRUE, TRUE};
00222                                  /* reg_free[i] is TRUE if */
00223                                  /* regs[i] is available   */
00224 
00225 int Vreg_bit;
00226 
00227 char * Vnewreg()
00228 {
00229     register int i;
00230     for (i = 0; i < NREGS && !reg_free[i];) i++;
00231     if (i < NREGS) {
00232         reg_free[i] = FALSE;
00233         Vreg_bit = mask_bit[i];
00234         Ventry_mask |= Vreg_bit;
00235         return(regs[i]);
00236     } else {
00237         char * tmp = Vnewlabel("tmp");
00238         fprintf(Voutfile, "\t.lcomm\t%s,4\n", tmp);
00239         Vreg_bit = 0;
00240         return(tmp);
00241     }
00242 }
00243 
00244 /*
00245  *   Return register to pool of available registers
00246  * Argument must be a pointer to a string returned by
00247  * Vnewreg.
00248  *   The register is removed from Vgc_mask.
00249  */   
00250 
00251 void Vretreg(r)
00252 char *r;
00253 {
00254     register int i;
00255     
00256     for (i = 0; i < NREGS && r != regs[i];) i++;
00257     if (i < NREGS) {
00258         reg_free[i] = TRUE;
00259         Vgc_mask &= ~mask_bit[i];
00260     }
00261 }

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