00001 # define DEBUG
00002
00003
00004
00005
00006
00007
00008
00009
00010 # include "parm.h"
00011 # include <stdio.h>
00012 # include "stree/ststructs.mh"
00013 # include "codegen.h"
00014 # include "op_codes.h"
00015 # include "pass4/sigs.h"
00016 # include "pass3/is_local.h"
00017
00018 extern int yydebug;
00019 extern int yynerrs;
00020
00021 extern boolean Pflag;
00022 extern boolean Tflag;
00023 extern boolean Vflag;
00024 extern boolean Oflag;
00025 extern boolean Xflag;
00026 extern boolean xflag;
00027 extern boolean Fflag;
00028
00029 extern char * entry_name;
00030
00031 boolean sl_available = TRUE;
00032
00033
00034 boolean compile_fcs = TRUE;
00035
00036
00037 boolean copied_globals;
00038
00039
00040 int n_globals;
00041
00042
00043
00044 int avail_loc = FIRST_AVAIL_LOC;
00045
00046 int first_param_loc;
00047
00048
00049
00050
00051
00052 void type_expr();
00053
00054 boolean Gpush_size();
00055
00056 char str_code_buf[MAXSTRCODELEN];
00057
00058
00059
00060 char str_code_buf2[MAXSTRCODELEN];
00061
00062 extern FILE * objfilelist;
00063
00064 extern FILE * unparse_file;
00065
00066 #ifdef UNDEFINED
00067 void add_objfile(fn)
00068 char * fn;
00069 {
00070 char *s;
00071
00072 if (objfilelist == NULL) {
00073 objfilelist = fopen(OBJFILELIST, "w");
00074 if (objfilelist == NULL) {
00075 fprintf(stderr, "Can't open %s\n", OBJFILELIST);
00076 exit(1);
00077 }
00078 }
00079 for (s = fn; *s != '\0'; s++) {
00080 putc(*s, objfilelist);
00081 }
00082 putc('\n', objfilelist);
00083 }
00084 #endif
00085
00086
00087
00088
00089
00090 typedef struct Fc_Entry {
00091 NODE * fc_pointer;
00092 int fc_level;
00093 int fc_fast_only;
00094
00095 struct Fc_Entry * fc_next;
00096 } fc_entry;
00097
00098 fc_entry * Gfc_list = NIL;
00099
00100
00101 void Gfc_add(ptr,lvl,fast_only)
00102 NODE * ptr;
00103 int lvl;
00104 int fast_only;
00105 {
00106 fc_entry * p;
00107
00108 if (!compile_fcs) { return; }
00109 p = (fc_entry *)malloc(sizeof (fc_entry));
00110 p -> fc_pointer = ptr;
00111 p -> fc_level = lvl;
00112 p -> fc_fast_only = fast_only;
00113 p -> fc_next = Gfc_list;
00114 Gfc_list = p;
00115 }
00116
00117
00118 void Gfc_delete()
00119 {
00120 fc_entry * p = Gfc_list;
00121
00122 Gfc_list = Gfc_list -> fc_next;
00123 free(p);
00124 }
00125
00126 int Glevel = -1;
00127
00128 NODE * Gcurrent;
00129 FILE * Goutfile;
00130
00131 boolean finished_accessible = FALSE;
00132
00133
00134
00135 void Gcompile_funcs()
00136 {
00137 NODE * fc_ptr;
00138 int fc_lvl;
00139 int fc_fast_only;
00140 int first_avail_loc;
00141
00142 first_avail_loc = avail_loc;
00143 while (Gfc_list != NIL) {
00144 fc_ptr = Gfc_list -> fc_pointer;
00145 fc_lvl = Gfc_list -> fc_level;
00146 fc_fast_only = Gfc_list -> fc_fast_only;
00147 Gfc_delete();
00148 if(!fc_fast_only) {
00149
00150
00151 avail_loc = first_avail_loc;
00152 Gfunc_body(fc_ptr, fc_lvl);
00153 }
00154 if((fc_ptr -> fc_complexity & NO_SL) && fc_lvl != 0) {
00155 boolean old_sl_avail = sl_available;
00156
00157 sl_available = FALSE;
00158 if (!fc_fast_only) { compile_fcs = FALSE; }
00159 avail_loc = first_avail_loc;
00160 Gfunc_body(fc_ptr,fc_lvl);
00161 sl_available = old_sl_avail;
00162 compile_fcs = TRUE;
00163 }
00164 }
00165 }
00166
00167
00168
00169 Ggeneratecode ( f , p )
00170 NODE * p;
00171 FILE * f;
00172 {
00173 Goutfile = f;
00174 p -> fc_code_label = "_russell_top_level";
00175 analyze(p);
00176 accessible(p);
00177 bld_analyze(&p);
00178 Gallocate (p,TRUE);
00179 sl_analyze(p);
00180 finished_accessible = TRUE;
00181 if (Oflag) {
00182
00183 if (Vflag) {
00184 printf("Repeating basic analysis:\n");
00185 }
00186 analyze(p);
00187 }
00188 cl_analyze(p, TRUE);
00189 if (yydebug) prtree(p);
00190 Gfc_add(p,0,FALSE);
00191
00192 Gcompile_funcs();
00193 }
00194
00195
00196
00197 Ggeneratepcode ( f, q, p )
00198 NODE * p;
00199 NODE * q;
00200 FILE * f;
00201 {
00202 extern char * ofname;
00203
00204 Goutfile = f;
00205 q -> fc_code_label = "_russell_top_level";
00206 if (p -> kind != FUNCCONSTR) {
00207 errmsg0(p, "Outermost expression must be function construction");
00208 return;
00209 }
00210 analyze(q);
00211 accessible(q);
00212 bld_analyze(&q);
00213 Gallocate (q,FALSE);
00214 sl_analyze(p);
00215 finished_accessible = TRUE;
00216 if (Oflag) {
00217
00218 if (Vflag) {
00219 printf("Repeating basic analysis:\n");
00220 }
00221 analyze(q);
00222 }
00223 cl_analyze(p, TRUE);
00224 # ifdef DEBUG
00225 if (yydebug) prtree(p);
00226 # endif
00227 if (p -> ar_static_level != 1) {
00228 dbgmsg("user program must be at level 1");
00229 }
00230
00231 sprintf(str_code_buf, "m_%s", entry_name);
00232 genl(EXT,str_code_buf);
00233 genl(BFN,str_code_buf);
00234 Glevel = 0;
00235 Gfuncconstructor(p, RL);
00236 gen0(RTN);
00237
00238 Gcompile_funcs();
00239 }
00240
00241
00242
00243
00244
00245 GgenerateXcode ( f, q, p )
00246 NODE * p;
00247 NODE * q;
00248 FILE * f;
00249 {
00250 NODE * sig = sig_structure(p -> signature);
00251 char name_buf[120];
00252 char ar_name_buf[120];
00253
00254 if (strlen(entry_name) > 100) {
00255 errmsg0(p, "file name too long");
00256 return;
00257 }
00258 Goutfile = f;
00259 q -> fc_code_label = "_russell_top_level";
00260 if (sig -> kind != TYPESIGNATURE) {
00261 errmsg0(p, "-X requires expression with type signature");
00262 return;
00263 }
00264 analyze(q);
00265 accessible(q);
00266 bld_analyze(&q);
00267 Gallocate (q,FALSE);
00268 sl_analyze(q);
00269 finished_accessible = TRUE;
00270 if (Oflag) {
00271
00272 if (Vflag) {
00273 printf("Repeating basic analysis:\n");
00274 }
00275 analyze(q);
00276 }
00277 cl_analyze(q, TRUE);
00278 # ifdef DEBUG
00279 if (yydebug) prtree(p);
00280 # endif
00281
00282 Gcurrent = q;
00283 Glevel = 0;
00284 copied_globals = FALSE;
00285 sl_available = TRUE;
00286
00287
00288 if (xflag) {
00289 sprintf(name_buf, "_XR_run");
00290 } else {
00291 sprintf(name_buf, "_%s_", entry_name);
00292 }
00293 genl(EXT, name_buf);
00294 genl(BSF, name_buf);
00295
00296
00297 gen2(LDN, q -> ar_size, T1);
00298 if (xflag) {
00299 gen2(ARG, 1, T1);
00300 } else {
00301 gen2(ARG, 3, T1);
00302 gen2(GAR, 2, T1);
00303 gen2(ARG, 2, T1);
00304 gen2(GAR, 1, T1);
00305 gen2(ARG, 1, T1);
00306 }
00307 genl(EXT, "_russell_set_up");
00308 genl(LBA, "_russell_set_up");
00309 if (xflag) {
00310 gen1(CLC, 1);
00311 } else {
00312 gen1(CLC, 3);
00313 }
00314 gen1(HINT, GFU);
00315 gen2(MOV, RL, GF);
00316 gen2(MOV, GF, AR);
00317
00318
00319 sprintf(ar_name_buf, "_%s_ar_save_loc", entry_name);
00320 genl(LBA, ar_name_buf);
00321 gen1(IDT, 0);
00322 gen2(DCL, T2, DCL_ADDR);
00323 genl(LBA, ar_name_buf);
00324 gen1(LDL, T2);
00325 gen3(STI, T2, 0, GF);
00326 gen1(UDC, T2);
00327
00328
00329
00330
00331
00332 gen2(HINT, ET, DCL_INT);
00333 genl(EXT, "_global_ar");
00334 # ifdef GEN_C
00335
00336
00337
00338 # else
00339 genl(LBA, "_global_ar");
00340 gen1(IDT, 0);
00341 # endif
00342 if (xflag) {
00343
00344
00345
00346
00347
00348
00349
00350
00351 } else {
00352 gen2(DCL, T2, DCL_ADDR);
00353 genl(LBA, "_global_ar");
00354 gen1(LDL, T2);
00355 gen3(STI, T2, 0, GF);
00356 gen1(UDC, T2);
00357 }
00358
00359 Gexpression( p, T1, FALSE );
00360
00361
00362 sprintf(name_buf, "_%s_save_loc", entry_name);
00363 genl(LBA, name_buf);
00364 gen1(IDT, 0);
00365 gen2(DCL, T2, DCL_ADDR);
00366 genl(LBA, name_buf);
00367 gen1(LDL, T2);
00368 gen3(STI, T2, 0, T1);
00369 gen1(UDC, T2);
00370 gen0(RTN);
00371
00372
00373
00374
00375 compile_stubs(sig, name_buf, ar_name_buf);
00376
00377 Gcompile_funcs();
00378 }
00379
00380
00381
00382 Gfuncconstructor(p, rloc)
00383 NODE * p;
00384 int rloc;
00385
00386
00387
00388
00389
00390 {
00391 int n_args;
00392 boolean contains_globals;
00393 int cl_size;
00394 int fv_len;
00395 int tloc = avail_loc++;
00396
00397 gen2(DCL, tloc, DCL_INT);
00398 if (p -> fc_body -> kind == EXTERNDEF) {
00399 int n_args = length(p -> signature -> fsig_param_list);
00400
00401
00402 ALLOC_FO(rloc);
00403 # ifdef UNDEFINED
00404
00405 p -> fc_code_label = new_global_label("fstub");
00406 # endif
00407
00408 genl(EXT, p -> fc_code_label);
00409 genl(LBA, p -> fc_code_label);
00410 gen1(LDL, tloc);
00411 gen3(STI, rloc, FO_IP, tloc);
00412
00413 gen2(LDN, n_args + 1, tloc);
00414 gen3(STI, rloc, FO_SIZE, tloc);
00415
00416 gen2(LDN, n_args, tloc);
00417 gen3(STI, rloc, FO_EP, tloc);
00418 } else {
00419
00420 contains_globals = ((p -> fc_complexity & CP_GLOBALS) != 0);
00421 if (contains_globals) {
00422 fv_len = length(p -> fc_free_vars);
00423 if (fv_len <= 1) {
00424 cl_size = 3;
00425 } else {
00426 cl_size = 3 + fv_len;
00427 }
00428 } else {
00429 cl_size = 3;
00430 }
00431
00432 gen2(LDN, cl_size, tloc);
00433 gen2(ALH, tloc, rloc);
00434
00435
00436 genl(EXT, p -> fc_code_label);
00437 genl(LBA, p -> fc_code_label);
00438 gen1(LDL, tloc);
00439 gen3(STI, rloc, FO_IP, tloc);
00440
00441 if (p -> fc_complexity & NO_AR_REFS) {
00442
00443 gen2(LDN, p -> ar_size, tloc);
00444 } else {
00445 gen2(LDN, -(p -> ar_size), tloc);
00446 }
00447 gen3(STI, rloc, FO_SIZE, tloc);
00448
00449 if (contains_globals) {
00450
00451 if (fv_len == 1) {
00452
00453 Gident(first(p -> fc_free_vars), tloc);
00454
00455 gen3(STI, rloc, FO_EP, tloc);
00456 } else if (fv_len > 1) {
00457 int cp;
00458
00459
00460 gen3(STI, rloc, FO_EP, rloc);
00461
00462 cp = 3;
00463 maplist(s, p -> fc_free_vars, {
00464 Gident(s, tloc);
00465 gen3(STI, rloc, cp, tloc);
00466 cp++;
00467 });
00468 }
00469 } else {
00470
00471 gen3(STI, rloc, FO_EP, AR);
00472 }
00473 }
00474 gen1(UDC, tloc);
00475
00476 Gfc_add(p, Glevel + 1, FALSE);
00477 }
00478
00479
00480
00481
00482
00483
00484 Gfunc_body(p, l)
00485 NODE * p;
00486 int l;
00487 {
00488 boolean is_extern = (p -> fc_body -> kind == EXTERNDEF);
00489
00490
00491
00492 Gcurrent = p;
00493 Glevel = l;
00494 copied_globals = ((Gcurrent -> fc_complexity & CP_GLOBALS) != 0);
00495 if (copied_globals) {
00496 n_globals = length(Gcurrent -> fc_free_vars);
00497 }
00498
00499 if (sl_available) {
00500 genl(EXT, p -> fc_code_label);
00501 genl(BFN, p -> fc_code_label);
00502 } else {
00503
00504 sprintf(str_code_buf, "F%s", p -> fc_code_label);
00505 genl(EXT, str_code_buf);
00506 genl(BSF, str_code_buf);
00507 }
00508
00509 if (Glevel == 0) {
00510
00511 gen1(HINT, GFU);
00512 gen2(MOV,AR,GF);
00513 }
00514
00515 if (Pflag) {
00516
00517 genl(PRO, (is_extern? p -> fc_body -> ext_name
00518 : p -> fc_code_label));
00519 }
00520
00521 if (Tflag) {
00522
00523 Gentry_trace((is_extern? p -> fc_body -> ext_name
00524 : p -> fc_code_label),
00525 p -> signature -> fsig_param_list, FALSE);
00526 }
00527
00528 if ((Fflag || (p -> fc_complexity & DIR_REC)) && !sl_available) {
00529 int i, n_args;
00530
00531
00532 first_param_loc = avail_loc;
00533 n_args = p -> ar_size - 1;
00534 avail_loc += n_args;
00535 for (i = 0; i < n_args; i++) {
00536 gen2(DCL, first_param_loc + i, DCL_INT);
00537 gen2(GAR, i+1, first_param_loc + i);
00538 }
00539 } else {
00540 first_param_loc = 0;
00541 }
00542 if (p -> fc_complexity & DIR_REC) {
00543 if (sl_available) {
00544 sprintf(str_code_buf, "R%s", p -> fc_code_label);
00545 } else {
00546 sprintf(str_code_buf, "RF%s", p -> fc_code_label);
00547 }
00548 genl(LBL, str_code_buf);
00549 }
00550
00551 if (is_extern) {
00552
00553 NODE * params = p -> signature -> fsig_param_list;
00554 int n_args = length(params) - n_vacuous_params(params);
00555 int i;
00556
00557 ASSERT(sl_available, "Can't compile stub without activation record\n");
00558
00559 {
00560 int j = avail_loc++;
00561
00562 gen2(DCL, j, DCL_INT);
00563 for (i = n_args; i >= 1; i--) {
00564 gen3(LDI, AR, i, j);
00565 gen2(ARG, i, j);
00566 }
00567 gen1(UDC, j);
00568 }
00569
00570 genl(EXT, p -> fc_body -> ext_name);
00571 genl(LBA, p -> fc_body -> ext_name);
00572 gen1(CLC, n_args);
00573
00574 } else {
00575
00576 Gexpression( p -> fc_body, RL, TRUE );
00577 }
00578
00579 if ((Fflag || (p -> fc_complexity & DIR_REC)) && !sl_available) {
00580 int i, n_args;
00581
00582
00583 n_args = p -> ar_size - 1;
00584 for (i = 0; i < n_args; i++) {
00585 gen1(UDC, first_param_loc + i);
00586 }
00587 }
00588
00589
00590 if (Tflag) {
00591
00592 Gexit_trace(is_extern? p -> fc_body -> ext_name
00593 : p -> fc_code_label);
00594 }
00595 gen0(RTN);
00596
00597 if (Glevel == 0) {
00598 gen2(HINT, ET, DCL_INT);
00599 genl(EXT, "_entry_ar_sz");
00600 genl(LBA, "_entry_ar_sz");
00601 gen1(IDT, p -> ar_size);
00602 }
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 Gexpression (p, rloc, last_expr)
00614 register NODE * p;
00615 int rloc;
00616 boolean last_expr;
00617 {
00618 int i;
00619
00620 ASSERT( !last_expr || rloc == RL, "Gexpression: bad last_expr value\n");
00621
00622 if (p -> signature -> kind == SIGNATURESIG) {
00623
00624 gen2(MOV, UN, rloc);
00625 return;
00626 }
00627
00628 switch ( p -> kind ) {
00629
00630 case OPRID :
00631 case LETTERID :
00632 Gident(p, rloc);
00633 break;
00634
00635 case QSTR:
00636 case UQSTR:
00637 {
00638 NODE * sig = p -> sel_type -> signature;
00639 char * code;
00640 int maxlen;
00641
00642 boolean know_inline;
00643
00644 ASSERT(sig -> kind == TYPESIGNATURE,
00645 "codegen: bad string type\n");
00646 if (sig -> ts_string_max == -1) {
00647 maxlen = MAXSTRLEN;
00648 } else {
00649 maxlen = sig -> ts_string_max;
00650 }
00651 know_inline = (sig -> ts_string_code != NIL
00652 && sig -> ts_element_code != NIL
00653 && strlen(p -> str_string) <= maxlen);
00654 if (know_inline
00655 && ! calls_put(p -> sel_type)) {
00656
00657 char *r = p -> str_string;
00658 char *q = str_code_buf;
00659
00660 *q = '\0';
00661 while (*r != '\0') {
00662 sprintf(q, sig -> ts_element_code, *r);
00663
00664 q += strlen(q);
00665 r++;
00666 }
00667 sprintf(str_code_buf2, sig -> ts_string_code,
00668 str_code_buf);
00669 code = (char *)Ginline_cnvt(str_code_buf2);
00670 write_RIC_seq(Goutfile, code, 0, rloc);
00671 free_RIC(code);
00672 } else {
00673 if (Vflag) {
00674 printf("Compiling expansion of %s\n",
00675 p -> str_string);
00676 }
00677
00678 Gexpression(p -> str_expansion, rloc, last_expr);
00679 }
00680 }
00681 break;
00682
00683 case APPLICATION :
00684 Gappl(p, rloc, last_expr);
00685 break;
00686
00687 case BLOCKDENOTATION :
00688 {
00689 if ( p -> bld_flags & REQUIRES_AR ) {
00690
00691
00692
00693
00694 int sz_loc = avail_loc++;
00695 int ar_loc = avail_loc++;
00696
00697 ASSERT(sl_available, "Block a.r. inside simple fn");
00698 Glevel++;
00699 gen2(DCL, sz_loc, DCL_INT);
00700 gen2(DCL, ar_loc, DCL_ADDR);
00701 gen2(LDN, p -> ar_size, sz_loc);
00702 gen2(ALH, sz_loc, ar_loc);
00703 gen3(STI, ar_loc, 0, AR);
00704 gen2(MOV, ar_loc, AR);
00705 gen1(UDC, sz_loc);
00706 gen1(UDC, ar_loc);
00707 }
00708
00709
00710
00711 maplist (v, p -> bld_declaration_list, {
00712 ASSERT (v->kind == DECLARATION,
00713 "codegen.c: decl expected");
00714 if (v -> decl_needed &&
00715 (v -> decl_special & (ID_IN_REG | VAR_IN_REG))) {
00716 genl(LBR, getname(v -> decl_id
00717 -> id_str_table_index));
00718 if (v -> decl_special & PTR_VAR_IN_REG) {
00719 gen2(DCL, v -> displacement, DCL_ADDR);
00720 } else {
00721 gen2(DCL, v -> displacement, DCL_INT);
00722 }
00723 }
00724 if (v -> decl_needed &&
00725 v -> decl_can_be_refd <= v -> pre_num) {
00726
00727 gen2(HINT, OPT, 1);
00728 if (v -> decl_special & (ID_IN_REG | VAR_IN_REG)) {
00729 gen2(MOV, UN, v -> displacement);
00730 } else {
00731 gen3(STI, AR, v -> displacement, UN);
00732 }
00733 }
00734 });
00735 maplist (v, p -> bld_declaration_list, {
00736 extern compile_decl();
00737
00738 compile_decl(v);
00739 });
00740 maplist (v,p->bld_den_seq, {
00741 if (v != last(p -> bld_den_seq)) {
00742 Gexpression(v, SK, FALSE);
00743 } else {
00744 Gexpression(v, rloc, last_expr);
00745 }
00746 });
00747
00748 maplist (v, p -> bld_declaration_list, {
00749 if (v -> decl_needed &&
00750 (v -> decl_special & (ID_IN_REG | VAR_IN_REG))) {
00751 if (v -> decl_special & ARRAY_CONTIG) {
00752
00753
00754
00755
00756 gen2(HINT, LIVE, v -> displacement);
00757 }
00758 gen1(UDC, v -> displacement);
00759 }
00760 });
00761 if ( p -> bld_flags & REQUIRES_AR ) {
00762 Glevel--;
00763 gen3(LDI, AR, 0, AR);
00764 }
00765 break;
00766 }
00767
00768 case LOOPDENOTATION :
00769 if (length(p -> gl_list) == 1) {
00770 compile_while_loop(first(p -> gl_list), rloc);
00771 break;
00772 }
00773
00774 case GUARDEDLIST :
00775 {
00776 char * L0;
00777 register NODE * v;
00778 boolean saw_else = FALSE;
00779
00780 if (p->kind == LOOPDENOTATION) {
00781 L0=Gnewlabel("loop");
00782 genl(LBL, L0);
00783 }
00784 else {
00785 L0=Gnewlabel("guard_exit");
00786 }
00787 maplist (v,p->gl_list, {
00788 char * L1;
00789
00790 ASSERT (v->kind == GUARDEDELEMENT,
00791 "codegen.c: bad guard list");
00792 if (v -> ge_guard -> kind == WORDELSE) {
00793 saw_else = TRUE;
00794 } else {
00795 L1 = Gnewlabel ("guard");
00796 if (Oflag && LAST_ITER
00797 && p -> kind == GUARDEDLIST) {
00798
00799
00800
00801 Gexpression(v -> ge_guard, SK, FALSE);
00802 } else {
00803 Gexpression(v->ge_guard, TL, FALSE);
00804 genl(BRF, L1);
00805 }
00806 }
00807 if (p -> kind == LOOPDENOTATION) {
00808 Gexpression(v -> ge_element, SK, FALSE);
00809 genl(BR, L0);
00810 } else {
00811 Gexpression(v -> ge_element, rloc, last_expr);
00812 if (saw_else) {
00813
00814
00815 break;
00816 } else {
00817
00818 genl(BR, L0);
00819 }
00820 }
00821 genl(LBL, L1);
00822 });
00823 if (p -> kind == LOOPDENOTATION) {
00824
00825 gen2(MOV, UN, rloc);
00826 } else {
00827 if (!saw_else) {
00828
00829 gen2(HINT, OPT, 1);
00830 genl(ERR, "_cond_error");
00831 }
00832
00833 genl(LBL, L0);
00834 }
00835 break;
00836 }
00837
00838 case WORDELSE :
00839 {
00840
00841 gen1(TRU, rloc);
00842 break;
00843 }
00844
00845
00846 case FUNCCONSTR :
00847 {
00848 Gfuncconstructor (p, rloc);
00849 break;
00850 }
00851
00852 case REXTERNDEF :
00853 {
00854 int name_length = strlen(p -> r_ext_name);
00855 char * q;
00856
00857 if (name_length + 3 > MAXSTRCODELEN) {
00858 errmsg0(p, "File name too long");
00859 }
00860 if (Vflag) {
00861 printf("%s forces evaluation of externally defined object %s\n",
00862 Gcurrent -> fc_code_label,
00863 p -> r_ext_name);
00864 }
00865 strcpy(str_code_buf, p -> r_ext_name);
00866 str_code_buf[name_length] = '.';
00867 str_code_buf[name_length+1] = 'o';
00868 str_code_buf[name_length+2] = 0;
00869 add_objfile(str_code_buf);
00870
00871 strcpy(str_code_buf, "m_");
00872 strcat(str_code_buf, p -> r_ext_name);
00873
00874 for (q = str_code_buf; *q != '\0'; q++) {
00875 if (*q == '/') {
00876 *q = '.';
00877 }
00878 }
00879 gen2(ARG, 1, GF);
00880 genl(CLL, str_code_buf);
00881 gen2(MOV, RL, rloc);
00882 break;
00883 }
00884
00885 case USELIST :
00886 {
00887 maplist (v,p->usl_den_seq, {
00888 if (v != last(p -> usl_den_seq)) {
00889 Gexpression(v, SK, FALSE);
00890 } else {
00891 Gexpression(v, rloc, last_expr);
00892 }
00893 });
00894 break;
00895 }
00896
00897
00898 case MODPRIMARY :
00899 {
00900 NODE * tm = p -> mp_type_modifier;
00901 unsigned * delv = (unsigned *)(p -> mp_delete_v);
00902 int orig = p -> mp_orig_length;
00903 int final = 0;
00904 int i,j;
00905 int res_pos;
00906
00907 DECLARE_ITER;
00908 NODE *s;
00909
00910
00911 int *q;
00912 boolean is_wl = (tm == NIL? FALSE
00913 : (tm -> kind == WITHLIST));
00914 int wl_length;
00915
00916 if (is_wl) {
00917 wl_length = length(tm -> wl_component_list);
00918 } else {
00919 wl_length = 0;
00920 }
00921
00922 if (orig > 0) {
00923 q = (int *)delv; i = 0; j = *q;
00924 while (i < orig) {
00925 if (j >= 0) final++;
00926 i++; j <<= 1;
00927 if (i % WORDLENGTH == 0) {
00928 j = *(++q);
00929 }
00930 }
00931 }
00932 final += wl_length;
00933 if (final == 0) {
00934 gen2(LDN, 0, rloc);
00935 } else {
00936 int sz_loc = avail_loc++;
00937
00938
00939
00940 int primary_loc = avail_loc++;
00941 int result_loc = avail_loc++;
00942
00943
00944 if (rloc == SK || rloc == RL){
00945
00946
00947 gen2(DCL, result_loc, DCL_ADDR);
00948 } else {
00949 result_loc = rloc;
00950 }
00951
00952 if (orig > 0) {
00953 gen2(DCL, primary_loc, DCL_ADDR);
00954 Gexpression(p -> mp_primary, primary_loc, FALSE);
00955 }
00956
00957
00958
00959 gen2(DCL, sz_loc, DCL_INT);
00960 gen2(LDN, final, sz_loc);
00961 gen2(ALH, sz_loc, result_loc);
00962 gen1(UDC, sz_loc);
00963
00964
00965 if (is_wl) {
00966 int display_entry;
00967
00968 DISPLAY (display_entry, p -> level);
00969 gen3(STI, display_entry, p -> displacement,
00970 result_loc);
00971 UNDISPLAY(display_entry);
00972 }
00973
00974
00975
00976
00977
00978
00979 if (is_wl && !is_empty(tm->wl_component_list)) {
00980 INIT_ITER(s, tm -> wl_component_list);
00981 } else {
00982 s = NIL;
00983 }
00984 q = (int *)delv; i = res_pos = 0;
00985 j = (orig > 0? *q : 0);
00986 while (s != NIL || i < orig) {
00987
00988
00989
00990 ASSERT(res_pos < 5000 && i < 5000,
00991 "Gexpression: bad type modification\n");
00992 if (s != NIL && s -> decl_sel_index == res_pos) {
00993 res_pos++;
00994 NEXT_ITER(s);
00995 continue;
00996 } else if (j >= 0) {
00997
00998 gen3(LDI, primary_loc, i, T1);
00999 gen3(STI, result_loc, res_pos, T1);
01000 res_pos++;
01001 i++; j <<= 1;
01002 } else {
01003 i++; j <<= 1;
01004 }
01005 if (i % WORDLENGTH == 0) {
01006 j = *(++q);
01007 }
01008 }
01009
01010
01011 if (orig > 0) {
01012 gen1(UDC, primary_loc);
01013 }
01014 if (is_wl) {
01015 NODE * decl_l = (NODE *)
01016 decl_sort(p -> mp_type_modifier
01017 -> wl_component_list);
01018
01019
01020
01021 int comp_loc = avail_loc++;
01022
01023
01024
01025 maplist (v, decl_l, {
01026 ASSERT (v -> kind == DECLARATION,
01027 "codegen.c: decl expected");
01028 if (v -> decl_can_be_refd <= v -> pre_num) {
01029
01030 gen3(STI, result_loc, v -> decl_sel_index, UN);
01031 }
01032 });
01033
01034 gen2(DCL, comp_loc, DCL_ADDR);
01035 maplist(s, decl_l, {
01036 Gexpression(s -> decl_denotation, comp_loc, FALSE);
01037 gen3(STI, result_loc,
01038 s -> decl_sel_index, comp_loc);
01039 });
01040 gen1(UDC, comp_loc);
01041 }
01042
01043 if (rloc == SK) {
01044 gen1(UDC, result_loc);
01045 } else if (rloc == RL) {
01046 gen2(MOV, result_loc, rloc);
01047 gen1(UDC, result_loc);
01048 }
01049 }
01050 break;
01051 }
01052
01053 case RECORDCONSTRUCTION:
01054 case PRODCONSTRUCTION :
01055 case UNIONCONSTRUCTION :
01056 case ENUMERATION:
01057 case EXTENSION :
01058 type_constr(p, rloc);
01059 break;
01060
01061
01062 default :
01063 findvl( p -> vlineno );
01064
01065 dbgmsg( "Gexpression: Unimplemented construct (kind = %s) in file %s at line %d\n",
01066 kindname(p->kind), getname(getfn()), getrl() );
01067 dbgmsg( "Gexpression: p is 0x%x\n",p);
01068 fprintf( Goutfile, "?" );
01069 fflush (Goutfile);
01070 abort();
01071 }
01072 }
01073
01074
01075
01076 compile_while_loop(p, rloc)
01077 NODE *p;
01078 int rloc;
01079 {
01080 extern boolean OOOflag;
01081 char * cond_label = Gnewlabel("guard");
01082 char * start_label = Gnewlabel("loop");
01083 char * end_label;
01084 boolean Ocompile_fcs = compile_fcs;
01085
01086 if (OOOflag) {
01087
01088 compile_fcs = FALSE;
01089
01090 end_label = Gnewlabel("loop_end");
01091 Gexpression(p -> ge_guard, TL, FALSE);
01092 genl(BRF, end_label);
01093 Gexpression(p -> ge_element, SK, FALSE);
01094 compile_fcs = Ocompile_fcs;
01095 }
01096 genl(BR, cond_label);
01097 genl(LBL, start_label);
01098 Gexpression(p -> ge_element, SK, FALSE);
01099 genl(LBL, cond_label);
01100 Gexpression(p -> ge_guard, TL, FALSE);
01101 genl(BRT, start_label);
01102 if (OOOflag) {
01103 genl(LBL, end_label);
01104 }
01105
01106 gen2(MOV, UN, rloc);
01107 }