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

Go to the documentation of this file.
00001 # define DEBUG
00002 /* 
00003  *  This is a highly simplified code generator.  It works only
00004  * for functions referring only to  local or level 0 identifiers,
00005  * containing no type modifications, declarations, loops,
00006  * type constructions, or function constructions, and
00007  * containing only applications of functions which can be
00008  * expanded inline, or are just as simple.
00009  *  The generated code uses a JSB calling sequence.  No registers
00010  * other than r0 and r1 are used.
00011  */
00012 # include "parm.h"
00013 # include <stdio.h>
00014 # include "stree/ststructs.mh"
00015 # include "codeutil.h"
00016 # include "pass4/sigs.h"
00017 # include "../runtime/runtime.h"
00018 
00019 extern int yydebug;
00020 extern int yynerrs;
00021 extern boolean Pflag;  /* generate profiling code */
00022 extern boolean Tflag;  /* generate trace code */
00023 
00024 extern long int_const_val;
00025 
00026 char str_code_buf[MAXSTRCODELEN]; /* used for strings, "special" fns */
00027                                   /* and by find_inline              */
00028 
00029 NODE * Vcurrent;
00030 FILE * Voutfile;
00031 
00032 int SP_offset;  /* current offset of sp from the return address in long words */
00033 
00034 /*
00035  * Generate code for the body of the function construction p.
00036  */
00037 Ffuncbody(p)
00038 NODE * p;
00039 {
00040 /* 
00041  *      Enter scope of new function construction
00042  */
00043         
00044         fprintf(Voutfile,"\t.globl\tF%s\n",p -> fc_code_label);
00045         CODE ("\t.align  1");
00046         fprintf(Voutfile, "F%s:\n",p -> fc_code_label);
00047         SP_offset = 0;
00048 
00049         if (Pflag) {
00050           /* generate profiling code */
00051             Vcall_mcount();
00052         }
00053 
00054         if (Tflag) {
00055           /* Generate calls to entry trace routines */
00056             Ventry_trace(p -> fc_code_label,
00057                          p -> signature -> fsig_param_list, TRUE);
00058         }
00059 
00060     /* recursively descend */
00061         Fexpression( p -> fc_body );
00062 
00063     /* Generate the epilog:  r0 <- top of stack */
00064         if (Tflag) {
00065           /* Generate call to exit trace routine */
00066             Vexit_trace();
00067         }
00068         POP ("r0","# function value to r0");
00069         fprintf(Voutfile,"\trsb\n");
00070 }
00071 
00072 /*
00073  * Generate code for the expression tree headed by p.
00074  */
00075 Fexpression (p)
00076 register NODE * p;
00077 {
00078     int i;
00079     switch ( p -> kind ) {
00080 
00081         case OPRID :
00082         case LETTERID :
00083                 {
00084                     register NODE * v;
00085                     char * display_reg; /* name of reg used for a.r. pointer */
00086                     char * r10 = "r10";
00087                     
00088                     v = p -> id_last_definition;
00089                     if (p -> sel_type == NIL) {
00090                         ASSERT2 (v != NIL, "Fexpression: id %s not declared\n", 
00091                                  getname(p -> id_str_table_index)
00092                         );
00093                         ASSERT2 (v -> kind == DECLARATION 
00094                              || v -> kind == PARAMETER
00095                              || v -> kind == MODPRIMARY
00096                                 && v -> mp_type_modifier -> kind == WITHLIST,
00097                               "Fexpression: id %x not declaration or parameter\n",v
00098                         );
00099                         putcomment1("\t\t\t# Identifier %s",
00100                                      getname(p -> id_str_table_index));
00101                         if (is_int_const(p)) {
00102                             fprintf(Voutfile, "\tmovzwl\t$%d,-(sp)\n",
00103                                               (short) int_const_val);
00104                         } else if (v -> level == 0) {
00105                             PUSH_DISP (L0fp, v->displacement,
00106                                               "# referenced object");
00107                         } else {
00108                             fprintf(Voutfile,"\tpushl\t%d(sp)\n",
00109                                              4*(SP_offset + v->displacement));
00110                         }
00111                         SP_offset++;
00112                     }
00113                     else {
00114                         putcomment1("\t\t\t# Selection of %s",
00115                                      getname(p->id_str_table_index));
00116                         Fexpression (p -> sel_type);
00117                         POP ("r0","# type value to r0");
00118                         PUSH_DISP ("r0",p -> sel_index,
00119                                 "# push selected function value");
00120                     }
00121                     break;
00122                 }
00123 
00124         case QSTR:
00125         case UQSTR:
00126                 {
00127                     NODE * sig = p -> sel_type -> signature;
00128 
00129                     ASSERT(sig -> kind == TYPESIGNATURE,
00130                            "codegen: bad string type\n");
00131                     if (sig -> ts_string_code != NIL 
00132                         && sig -> ts_element_code != NIL
00133                         && strlen(p -> str_string) <= MAXSTRLEN) {
00134                         /* build body of in-line expansion */
00135                           char *r = p -> str_string;
00136                           char *q = str_code_buf;
00137                           while (*r != '\0') {
00138                             sprintf(q, sig -> ts_element_code, *r);
00139                             /* position q at trailing 0 */
00140                               q += strlen(q);
00141                             r++;
00142                           }
00143                         fprintf(Voutfile, sig -> ts_string_code, str_code_buf);
00144                         fprintf(Voutfile, "\n");
00145                         SP_offset++;
00146                     } else {
00147                         dbgmsg("Fexpression: bad string\n");
00148                     }
00149                 }
00150                 break;
00151                 
00152         case APPLICATION :
00153                 {
00154                     char * in_line;     /* in-line code, NIL if not known */
00155                     NODE * construction  =  p -> ap_operator -> signature
00156                                               -> fsig_construction;
00157                     NODE * op_sig = p -> ap_operator -> signature;
00158 
00159 
00160                     /* determine type of calling sequence */
00161                       in_line = op_sig -> fsig_inline_code;
00162                     /* push arguments in reverse order */
00163                       maprlist(p -> ap_args, Fexpression);
00164                     if (in_line != NIL) {
00165                       fprintf(Voutfile, in_line, 0,0);
00166                       fprintf(Voutfile, "\n");
00167                     } else {
00168                       int l = length(p -> ap_args);
00169                       /* Construction known and we can use jsb calling seq */
00170                       fprintf(Voutfile, "\tjsb\tF%s\n",
00171                                         construction -> fc_code_label);
00172                       /* pop arguments */
00173                         if (l > 0) {
00174                           fprintf(Voutfile,"\taddl2\t$%d,sp\n", 4*l);
00175                         }
00176                       fprintf(Voutfile, "\tpushl\tr0\t# push return value\n");
00177                     }
00178                     SP_offset -= (length(p -> ap_args) - 1);
00179                     break;
00180                 }
00181 
00182         case BLOCKDENOTATION :
00183                 {
00184                     /* Declaration list is guaranteed to be empty */
00185                     /* see get_complexity.                        */
00186                     maplist (v,p->bld_den_seq, {
00187                         Fexpression(v);
00188                         if (v != last(p -> bld_den_seq)) {
00189                             POP ("r0","# trash value");
00190                             SP_offset--;
00191                         }
00192                     });
00193                     break;
00194                 }
00195                 
00196         case GUARDEDLIST :
00197                 {
00198                     char * L0;
00199                     register NODE * v;
00200                     int save_SP_offset = SP_offset;
00201 
00202                     L0=Vnewlabel("guard_exit");
00203                     maplist (v,p->gl_list, {
00204                         char * L1;
00205                         
00206                         ASSERT (v->kind == GUARDEDELEMENT,
00207                                         "Fcodegen.c: bad guard list");
00208                         SP_offset = save_SP_offset;
00209                         Fexpression(v->ge_guard);
00210                         L1 = Vnewlabel ("guard");
00211                         POP ("r0","# value of guard");
00212                         SP_offset--;
00213                         fprintf(Voutfile,"\tjeql\t%s", L1);
00214                         putcomment ("# branch on false");
00215                         Fexpression(v->ge_element);
00216                         fprintf(Voutfile,"\tjbr\t%s",L0);
00217                         putcomment ("# leave guarded list");
00218                         fprintf(Voutfile,"%s:",L1);
00219                         putcomment ("# next case");
00220                     });
00221                     fprintf(Voutfile,"\tcalls\t$0,_cond_error\n");
00222                     fprintf (Voutfile,"%s:\n",L0);
00223                     break;
00224                 }
00225 
00226         case WORDELSE :
00227                 {
00228                     PUSH ("$1","# Else = constant 1");
00229                     SP_offset++;
00230                     break;
00231                 }
00232                 
00233 
00234         case USELIST :
00235                 {
00236                     maplist (v,p->usl_den_seq, {
00237                         Fexpression(v);
00238                         if (v != last(p -> usl_den_seq)) {
00239                           POP ("r0","# trash value");
00240                           SP_offset--;
00241                         }
00242                     });
00243                     break;
00244                 }
00245 
00246 #       ifdef DEBUG
00247           default :
00248             dbgmsg("Fcodegen: bad kind\n");
00249             abort();
00250 #       endif
00251     }
00252 }

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