00001 # define DEBUG
00002
00003
00004
00005
00006
00007
00008
00009
00010
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;
00022 extern boolean Tflag;
00023
00024 extern long int_const_val;
00025
00026 char str_code_buf[MAXSTRCODELEN];
00027
00028
00029 NODE * Vcurrent;
00030 FILE * Voutfile;
00031
00032 int SP_offset;
00033
00034
00035
00036
00037 Ffuncbody(p)
00038 NODE * p;
00039 {
00040
00041
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
00051 Vcall_mcount();
00052 }
00053
00054 if (Tflag) {
00055
00056 Ventry_trace(p -> fc_code_label,
00057 p -> signature -> fsig_param_list, TRUE);
00058 }
00059
00060
00061 Fexpression( p -> fc_body );
00062
00063
00064 if (Tflag) {
00065
00066 Vexit_trace();
00067 }
00068 POP ("r0","# function value to r0");
00069 fprintf(Voutfile,"\trsb\n");
00070 }
00071
00072
00073
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;
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
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
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;
00155 NODE * construction = p -> ap_operator -> signature
00156 -> fsig_construction;
00157 NODE * op_sig = p -> ap_operator -> signature;
00158
00159
00160
00161 in_line = op_sig -> fsig_inline_code;
00162
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
00170 fprintf(Voutfile, "\tjsb\tF%s\n",
00171 construction -> fc_code_label);
00172
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
00185
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 }