00001 # define DEBUG
00002 # define OBSOLETE
00003 # undef OBSOLETE
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 # include "parm.h"
00014 # include <stdio.h>
00015 # include "stree/ststructs.mh"
00016 # include "codegen.h"
00017 # include "op_codes.h"
00018 # include "pass4/sigs.h"
00019 # include "pass3/is_local.h"
00020
00021 FILE * Goutfile;
00022
00023 extern int yydebug;
00024 extern int yynerrs;
00025
00026 extern boolean Vflag;
00027
00028 extern boolean Oflag;
00029
00030 extern boolean Fflag;
00031
00032 extern boolean sl_available;
00033
00034
00035 extern int avail_loc;
00036
00037 extern char str_code_buf[];
00038
00039
00040
00041
00042 extern NODE * Gcurrent;
00043
00044 extern int Glevel;
00045
00046 extern boolean copied_globals;
00047
00048 extern int n_globals;
00049
00050 extern boolean is_int_const();
00051
00052 char * Gnewlabel();
00053
00054 extern FILE * unparse_file;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 NODE * equiv_expr(p)
00070 NODE * p;
00071 {
00072 NODE * d;
00073 NODE * q;
00074 while (p -> kind == LETTERID || p -> kind == OPRID) {
00075 if (p -> sel_type == NIL ) {
00076 d = p -> id_last_definition;
00077 switch(d -> kind) {
00078 case DECLARATION:
00079 q = d -> decl_denotation;
00080 break;
00081 case PARAMETER:
00082 if (is_real_def(d -> par_only_def)) {
00083 q = d -> par_only_def;
00084 } else {
00085 return(p);
00086 }
00087 break;
00088 default:
00089 return(p);
00090 }
00091 if (q -> kind != OPRID && q -> kind != LETTERID
00092 || q -> sel_type != NIL
00093 || q -> id_last_definition -> pre_num < d -> pre_num) {
00094
00095 p = q;
00096 } else {
00097 return(q);
00098 }
00099 } else {
00100 NODE * nt = equiv_expr(p -> sel_type);
00101 NODE * new_id;
00102
00103 if (p -> signature -> kind == FUNCSIGNATURE
00104 && (p -> signature -> fsig_construction != NIL
00105 || p -> signature -> fsig_inline_code != NIL)) {
00106
00107 return(p);
00108 }
00109 nt = equiv_expr(p -> sel_type);
00110 if (nt == p -> sel_type) {
00111 return(p);
00112 } else {
00113 if (!is_unique(nt -> signature, p -> id_str_table_index)) {
00114
00115
00116
00117 return(p);
00118 }
00119 new_id = copynode(p);
00120 new_id -> sel_type = nt;
00121 new_id -> signature = getcomp(nt -> signature, new_id,
00122 p -> sel_type, NIL, NIL, NIL, TRUE);
00123 new_id -> sig_done = SIG_DONE;
00124 if (new_id -> signature == NIL) {
00125 dbgmsg("equiv_expr: getcomp failed\n");
00126 return(p);
00127 } else {
00128 new_id -> signature = sig_structure(new_id -> signature);
00129 return(new_id);
00130 }
00131 }
00132 }
00133 }
00134 return(p);
00135 }
00136
00137 Gident(p, rloc)
00138 NODE *p;
00139 int rloc;
00140 {
00141 register NODE * v;
00142 int display_reg;
00143
00144 if (Oflag? is_int_const(equiv_expr(p)) : is_int_const(p)) {
00145 extern long int_const_val;
00146
00147 gen2(LDN, int_const_val, rloc);
00148 return;
00149 }
00150 v = p -> id_last_definition;
00151 if (p -> sel_type == NIL) {
00152 ASSERT2 (v != NIL, "ident: id %s not declared\n",
00153 getname(p -> id_str_table_index)
00154 );
00155 ASSERT2 (v -> kind == DECLARATION
00156 || v -> kind == PARAMETER
00157 || v -> kind == MODPRIMARY
00158 && v -> mp_type_modifier -> kind == WITHLIST,
00159 "ident: id %x not declaration or parameter\n",v);
00160 ASSERT (v -> kind != DECLARATION
00161 || !(v -> decl_special & VAR_IN_REG),
00162 "Taking address of register variable\n");
00163 if (v -> kind == DECLARATION && (v -> decl_special & ID_IN_REG)) {
00164 # ifdef DEBUG
00165 if(v -> level < Gcurrent -> ar_static_level) {
00166 dbgmsg("Nonlocal register access\n");
00167 fprintf(stderr,
00168 "- to %s declared at level %d from level %d; declaration:\n",
00169 getname(p -> id_str_table_index), v -> level, Glevel);
00170 unparse_file = stderr;
00171 if (v -> kind == DECLARATION) {
00172 unparse(v -> decl_denotation);
00173 } else {
00174 unparse(v);
00175 }
00176 fprintf(stderr, "\n");
00177 errmsg0(p, "Nonlocal access");
00178 abort(p, v);
00179 }
00180 # endif
00181 gen2(MOV, v -> displacement, rloc);
00182 } else if (sl_available || v -> level == 0) {
00183 if (!copied_globals || v -> level == 0 || v -> level == Glevel) {
00184 ASSERT2(v -> level == 0 || v -> level >= Gcurrent -> ar_static_level
00185 || (Gcurrent -> fc_complexity & SL_ACC),
00186 "Indirecting through nonexistent static link for %s\n",
00187 getname(p -> id_str_table_index));
00188 # ifdef DEBUG
00189 if (v -> level > Glevel) {
00190 dbgmsg("Accessing identifier %s at nesting level %d from level %d\n",
00191 getname(p -> id_str_table_index), v -> level, Glevel);
00192 abort();
00193 }
00194 # endif
00195 DISPLAY ( display_reg, v -> level);
00196 if (v -> kind == DECLARATION
00197 && (v -> decl_special & VAR_ON_STACK)) {
00198 switch(v -> displacement) {
00199 case 1:
00200 gen3(ADP, display_reg, C1, rloc);
00201 break;
00202 case 2:
00203 gen3(ADP, display_reg, C2, rloc);
00204 break;
00205 case 3:
00206 gen3(ADP, display_reg, C3, rloc);
00207 break;
00208 default:
00209 gen2(LDN, v -> displacement, T1);
00210 gen3(ADP, display_reg, T1, rloc);
00211 gen1(UDC, T1);
00212 }
00213 } else {
00214 gen3 (LDI, display_reg, v->displacement, rloc);
00215 }
00216 UNDISPLAY ( display_reg );
00217 } else {
00218 switch(n_globals) {
00219 case 0:
00220 dbgmsg("ident: unexpected non-local: %s\n",
00221 getname(p -> id_str_table_index));
00222 fprintf(stderr, "Current function: %s\n",
00223 Gcurrent -> fc_code_label);
00224 abort();
00225 case 1:
00226
00227 gen3(LDI, AR, 0, rloc);
00228 break;
00229 default:
00230
00231
00232 {
00233 int cl_ptr = avail_loc++;
00234 int index;
00235
00236 index = 1;
00237 maplist(s, Gcurrent -> fc_free_vars, {
00238 if (s -> id_last_definition -> pre_num
00239 == v -> pre_num) {
00240 break;
00241 }
00242 index ++;
00243 });
00244 # ifdef DEBUG
00245 if(index > n_globals) {
00246 dbgmsg("ident: couldn't find non-local id %s\n",
00247 getname(p -> id_str_table_index));
00248 printf("Free variables for %s are:\n",
00249 Gcurrent -> fc_code_label);
00250 maplist(s, Gcurrent -> fc_free_vars, {
00251 printf("\t%s\n",
00252 getname(s -> id_str_table_index));
00253 });
00254 abort("couldnt find free var");
00255 }
00256 # endif
00257 gen2(DCL, cl_ptr, DCL_ADDR);
00258 gen3(LDI, AR, 0, cl_ptr);
00259 gen3(LDI, cl_ptr, 2+index, rloc);
00260 gen1(UDC, cl_ptr);
00261 }
00262 }
00263 }
00264 } else {
00265 extern int first_param_loc;
00266
00267 # ifdef OBSOLETE
00268 gen3(LDI, FP, v->displacement+1, rloc);
00269 # else
00270 if (first_param_loc != 0) {
00271
00272 int loc = first_param_loc + v -> displacement - 1;
00273
00274 ASSERT(Fflag || Gcurrent -> fc_complexity & DIR_REC,
00275 "ident: bad first_param_loc\n");
00276 gen2(MOV, loc, rloc);
00277 } else {
00278 gen2(GAR, v -> displacement, rloc);
00279 }
00280 # endif
00281 }
00282 } else {
00283 int type_loc = avail_loc++;
00284
00285 gen2(DCL, type_loc, DCL_ADDR);
00286 Gexpression (p -> sel_type, type_loc, FALSE);
00287 gen3(LDI, type_loc, p -> sel_index, rloc);
00288 gen1(UDC, type_loc);
00289 }
00290 if (p -> id_forward_ref) {
00291 if (p -> signature -> kind == VALSIGNATURE) {
00292 NODE * type_den;
00293 NODE * type_sig;
00294 NODE * new_sig;
00295 extern NODE * id_New;
00296
00297
00298
00299
00300 type_den = p -> signature -> val_denotation;
00301 tl_findsig(type_den, FALSE);
00302 type_sig = type_den -> signature;
00303 if (type_sig == ERR_SIG) {
00304 exit(1);
00305
00306 }
00307 new_sig = getcomp(type_sig, id_New, NIL,
00308 NIL, NIL, NIL, FALSE);
00309 # ifdef VERBOSE
00310 unparse_file = stdout;
00311 printf("Trying to find rep of:\n");
00312 unparse(type_den);
00313 printf("\nWith signature:\n");
00314 unparse(type_sig);
00315 printf("\n");
00316 if (new_sig == NIL) {
00317 printf("No New function\n");
00318 } else {
00319 printf("Special: %X\n", new_sig -> fsig_special);
00320 }
00321 # endif
00322 if (new_sig == NIL
00323 || new_sig -> kind != FUNCSIGNATURE
00324 || special_tp(new_sig -> fsig_special) != PTR_NEW) {
00325 errmsg1(p, "Warning: unchecked possible forward reference to %s",
00326 getname(p -> id_str_table_index));
00327
00328 yynerrs--;
00329 } else {
00330 goto check_undef;
00331 }
00332 } else {
00333 char * tmp_lbl;
00334 check_undef:
00335
00336 tmp_lbl = Gnewlabel("L");
00337 gen2(HINT, OPT, 4);
00338 gen3(EQI, rloc, UN, TL);
00339 genl(BRF, tmp_lbl);
00340 genl(ERR, "_forward_error");
00341 genl(LBL, tmp_lbl);
00342 }
00343 }
00344 }