00001 # include "parm.h"
00002 # include <stdio.h>
00003 # include "stree/ststructs.mh"
00004 # include "codegen.h"
00005 # include "op_codes.h"
00006
00007 void Ggen_special();
00008
00009 # ifdef DEBUG
00010 # define IFDEBUG(x) x
00011 # else
00012 # define IFDEBUG(x)
00013 # endif
00014
00015 extern int yydebug;
00016 extern int yynerrs;
00017
00018 extern char str_code_buf[];
00019
00020 extern int avail_loc;
00021
00022 extern int Glevel;
00023
00024 extern FILE * Goutfile;
00025
00026
00027
00028
00029 void type_constr(p, rloc)
00030 NODE *p;
00031 int rloc;
00032 {
00033 int env_loc;
00034 int i;
00035
00036 if (p -> kind == EXTENSION) {
00037 int new_tp_ptr = avail_loc++;
00038 int old_tp_ptr = avail_loc++;
00039 int identity_loc = avail_loc++;
00040 int sz_loc = avail_loc++;
00041 int len = tsig_length(p -> signature);
00042
00043
00044 gen2(DCL, sz_loc, DCL_INT);
00045 gen2(LDN, len, sz_loc);
00046 gen2(DCL, new_tp_ptr, DCL_ADDR);
00047 gen2(ALH, sz_loc, new_tp_ptr);
00048 gen1(UDC, sz_loc);
00049 gen2(MOV, new_tp_ptr, rloc);
00050
00051 gen2(DCL, old_tp_ptr, DCL_ADDR);
00052 Gexpression(p -> ext_denotation, old_tp_ptr, FALSE);
00053
00054 gen2(DCL, identity_loc, DCL_ADDR);
00055 Ggen_special(special(IDENTITY, 0), identity_loc, 0);
00056
00057
00058
00059 ASSERT(p -> In_index < p -> Out_index,
00060 "type_constr: bad In, Out indicees\n");
00061
00062 for (i = 0; i < p -> In_index; i++) {
00063 gen3(LDI, old_tp_ptr, i, T1);
00064 gen3(STI, new_tp_ptr, i, T1);
00065 }
00066
00067 gen3(STI, new_tp_ptr, p->In_index, identity_loc);
00068
00069 for (i = p -> In_index + 1; i < p -> Out_index; i++) {
00070 gen3(LDI, old_tp_ptr, i-1, T1);
00071 gen3(STI, new_tp_ptr, i, T1);
00072 }
00073
00074 gen3(STI, new_tp_ptr, p -> Out_index, identity_loc);
00075
00076 for (i = p -> Out_index + 1; i < len; i++) {
00077 gen3(LDI, old_tp_ptr, i-2, T1);
00078 gen3(STI, new_tp_ptr, i, T1);
00079 }
00080
00081
00082 gen1(UDC, new_tp_ptr);
00083 gen1(UDC, old_tp_ptr);
00084 gen1(UDC, identity_loc);
00085 return;
00086 }
00087 if (p -> kind == RECORDCONSTRUCTION) {
00088 int n_components = length(p -> rec_component_list);
00089 int i;
00090 int sz_loc = avail_loc++;
00091 int tp_loc = avail_loc++;
00092 int tmp_loc = avail_loc++;
00093
00094 env_loc = avail_loc++;
00095
00096
00097
00098 gen2(DCL, sz_loc, DCL_INT);
00099 gen2(DCL, env_loc, DCL_ADDR);
00100 gen2(LDN, 3*n_components, sz_loc);
00101 gen2(ALH, sz_loc, env_loc);
00102 gen1(UDC, sz_loc);
00103
00104 i = 0;
00105 maplist(s, p -> rec_component_list, {
00106
00107 gen2(DCL, tp_loc, DCL_ADDR);
00108 Gexpression(s -> re_denotation, tp_loc, FALSE);
00109
00110 gen2(DCL, tmp_loc, DCL_INT);
00111 gen3(LDI, tp_loc, s -> re_assign_index, tmp_loc);
00112 gen3(STI, env_loc, i, tmp_loc);
00113 gen1(UDC, tmp_loc);
00114
00115 gen2(DCL, tmp_loc, DCL_INT);
00116 gen3(LDI, tp_loc, s -> re_New_index, tmp_loc);
00117 gen3(STI, env_loc, i+1, tmp_loc);
00118 gen1(UDC, tmp_loc);
00119
00120 gen2(DCL, tmp_loc, DCL_INT);
00121 gen3(LDI, tp_loc, s -> re_ValueOf_index, tmp_loc);
00122 gen3(STI, env_loc, i+2, tmp_loc);
00123 gen1(UDC, tmp_loc);
00124 i += 3;
00125 gen1(UDC, tp_loc);
00126 });
00127
00128
00129 }
00130 {
00131 NODE * clist = p -> signature -> ts_clist;
00132 int len = tsig_length(p -> signature);
00133 int sz_loc = avail_loc++;
00134 int tmp_loc = avail_loc++;
00135
00136
00137 gen2(DCL, sz_loc, DCL_INT);
00138 gen2(LDN, len, sz_loc);
00139 gen2(ALH, sz_loc, rloc);
00140 gen1(UDC, sz_loc);
00141
00142
00143 i = 0;
00144
00145 {
00146 NODE * dcs = first(clist);
00147
00148 ASSERT(dcs -> kind == DEFCHARSIGS, "type_const: bad DCS node\n");
00149 if (dcs -> dcs_exceptions != NIL) {
00150 maplist(s, dcs -> dcs_exceptions, {
00151 gen2(DCL, tmp_loc, DCL_INT);
00152 Ggen_special(s -> dcse_special,
00153 tmp_loc, env_loc);
00154 gen3(STI, rloc, i++, tmp_loc);
00155 gen1(UDC, tmp_loc);
00156 });
00157 }
00158 }
00159 maplist(s, clist, {
00160 switch(s -> kind) {
00161 case TSCOMPONENT:
00162 gen2(DCL, tmp_loc, DCL_INT);
00163 Ggen_special(s -> tsc_signature -> fsig_special,
00164 tmp_loc, env_loc);
00165 gen3(STI, rloc, i++, tmp_loc);
00166 gen1(UDC, tmp_loc);
00167 break;
00168 IFDEBUG(
00169 case DEFCHARSIGS:
00170
00171 break;
00172 default:
00173 dbgmsg("type_constr: bad type constr. sig\n");
00174 )
00175 }
00176 });
00177 }
00178 if (p -> kind == RECORDCONSTRUCTION) {
00179
00180 gen1(UDC, env_loc);
00181 }
00182 }
00183
00184
00185
00186
00187
00188 void Ggen_special(spcl, rloc, pe_loc)
00189 unsigned spcl;
00190 int rloc;
00191 int pe_loc;
00192 {
00193 char * routine_name;
00194 int n_args;
00195 boolean explicit_ep = FALSE;
00196 int tmp_loc = avail_loc++;
00197
00198
00199
00200
00201 switch(special_tp(spcl)) {
00202 case PROD_PROJ:
00203 case RECORD_VAL_FIELD:
00204 case RECORD_VAR_FIELD:
00205 routine_name = "_P_R_ith";
00206 n_args = 1;
00207 break;
00208
00209 case RECORD_MK:
00210 case PROD_MK:
00211 routine_name = "_P_R_Make";
00212
00213
00214 n_args = special_val(spcl);
00215 break;
00216
00217 case PROD_NEW:
00218 case UNION_NEW:
00219 routine_name = "_P_U_New";
00220 n_args = 0;
00221 break;
00222
00223 case RECORD_NEW:
00224 routine_name = "_Record_New";
00225 n_args = 0;
00226 explicit_ep = TRUE;
00227 break;
00228
00229 case ENUM_NEW:
00230 routine_name = "_E_New";
00231 n_args = 0;
00232 break;
00233
00234 case PROD_ASSIGN:
00235 case UNION_ASSIGN:
00236 case ENUM_ASSIGN:
00237 routine_name = "_CF_PUE_Assign";
00238 n_args = 2;
00239 break;
00240
00241 case RECORD_ASSIGN:
00242 routine_name = "_Record_Assign";
00243 n_args = 2;
00244 explicit_ep = TRUE;
00245 break;
00246
00247 case PROD_VALUEOF:
00248 case UNION_VALUEOF:
00249 case ENUM_VALUEOF:
00250 routine_name = "_CF_PUE_ValueOf";
00251 n_args = 1;
00252 break;
00253
00254 case RECORD_VALUEOF:
00255 routine_name = "_Record_ValueOf";
00256 n_args = 1;
00257 explicit_ep = TRUE;
00258 break;
00259
00260 case UNION_PROJ:
00261 routine_name = "_Union_Proj";
00262 n_args = 1;
00263 break;
00264
00265 case UNION_INJ:
00266 routine_name = "_Union_Inj";
00267 n_args = 1;
00268 break;
00269
00270 case UNION_INQ:
00271 routine_name = "_Union_Inq";
00272 n_args = 1;
00273 break;
00274
00275 case ENUM_EQ:
00276 routine_name = "_CF_Enum_eq";
00277 n_args = 2;
00278 break;
00279
00280 case ENUM_NE:
00281 routine_name = "_CF_Enum_ne";
00282 n_args = 2;
00283 break;
00284
00285 case ENUM_ELEMENT:
00286 routine_name = "_Enum_Element";
00287 n_args = 0;
00288 break;
00289
00290 case ENUM_CARD:
00291 routine_name = "_Enum_Card";
00292 n_args = 0;
00293 break;
00294
00295 case ENUM_PRED:
00296 routine_name = "_CF_Enum_Pred";
00297 n_args = 1;
00298 break;
00299
00300 case ENUM_SUCC:
00301 routine_name = "_Enum_Succ";
00302 n_args = 1;
00303 break;
00304
00305 case IDENTITY:
00306 routine_name = "_CF_Identity";
00307 n_args = 1;
00308 break;
00309
00310 # ifdef DEBUG
00311 default:
00312 dbgmsg("Ggen_special: Unknown special function\n");
00313 # endif
00314 }
00315
00316 ALLOC_FO(rloc);
00317 if (!explicit_ep) {
00318
00319 gen2(DCL, tmp_loc, DCL_INT);
00320 gen2(LDN, special_val(spcl), tmp_loc);
00321 gen3(STI, rloc, FO_EP, tmp_loc);
00322 gen1(UDC, tmp_loc);
00323 } else {
00324 gen3(STI, rloc, FO_EP, pe_loc);
00325 }
00326
00327 genl(EXT, routine_name);
00328 gen2(DCL, tmp_loc, DCL_ADDR);
00329 genl(LBA, routine_name);
00330 gen1(LDL, tmp_loc);
00331 gen3(STI, rloc, FO_IP, tmp_loc);
00332 gen1(UDC, tmp_loc);
00333
00334 gen2(DCL, tmp_loc, DCL_INT);
00335 gen2(LDN, n_args + 1, tmp_loc);
00336 gen3(STI, rloc, FO_SIZE, tmp_loc);
00337 gen1(UDC, tmp_loc);
00338 }
00339