00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 # include <fcntl.h>
00030 # include <stdio.h>
00031 # include "strings.h"
00032 # include "op_codes.h"
00033 # include "../parm.h"
00034 # include "../pass5d/codegen.h"
00035 # include "tables.h"
00036 # define GCC
00037 # undef GCC
00038
00039
00040 # define STDOUT_FD 1
00041 # define DELAB strcat(RROOT, "/src/delab/delab")
00042 # ifdef GCC
00043 # define CC "/usr/local/gcc"
00044 # else
00045 # define CC "/bin/cc"
00046 # endif
00047
00048 char * C_name();
00049
00050 FILE * in_file;
00051
00052 # define STANDARD_PREFIX \
00053 concat("typedef long word;\n", \
00054 concat("typedef word (*word_func_ptr)();\n", \
00055 concat("extern word * GC_malloc();\n", \
00056 concat("extern void GC_free();\n", \
00057 concat("extern word * GC_malloc_atomic();\n", \
00058 concat("#define alloc(sz,result) *(word **)(&result) = GC_malloc((sz)<<2)\n", \
00059 concat("#define alloc_nc(sz,result) result = GC_malloc((sz)<<2)\n", \
00060 concat("#define alloc_cw(sz,result) result = (word)GC_malloc((sz)<<2)\n", \
00061 concat("#define alloc_a(sz,result) *(word **)(&result) = GC_malloc_atomic((sz)<<2)\n", \
00062 concat("#define alloc_a_nc(sz,result) result = GC_malloc_atomic((sz)<<2)\n", \
00063 concat("#define alloc_a_cw(sz,result) result = (word)GC_malloc_atomic((sz)<<2)\n", \
00064 concat("#define abs(x) ((x) > 0? (x) : -(x))\n", \
00065 "#define shift(x, n) ((n) < 0? (x) >> (-(n)) : (x) << (n))\n" \
00066 ))))))))))))
00067
00068
00069 boolean profile = FALSE;
00070
00071
00072
00073 # define SAFE 0x40000000
00074
00075
00076
00077 # define NONE ((-1) | SAFE)
00078
00079 long lm = NONE;
00080 char * lm_expr;
00081
00082
00083
00084
00085 char * slm_ph;
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 long slm = NONE;
00098
00099
00100
00101
00102
00103
00104 # define MEMORY ((-2) & ~SAFE)
00105
00106
00107
00108
00109
00110
00111
00112
00113 char * store_code;
00114
00115
00116 char * code = "";
00117
00118 char * extern_decls = "";
00119
00120
00121 char * fn_name;
00122
00123 int n_params = 0;
00124
00125 int n_args = 0;
00126
00127 boolean is_simple;
00128
00129 boolean gf_refd = FALSE;
00130
00131 boolean ar_refd = FALSE;
00132
00133
00134 boolean saw_ons = FALSE;
00135
00136 int ons_depth;
00137
00138 char * global_ar_name;
00139
00140 # define ONS_MAX 50
00141
00142 boolean ons_stack[ONS_MAX];
00143
00144
00145
00146 boolean suppress = FALSE;
00147
00148
00149
00150
00151 int extern_type = NONE;
00152
00153 boolean idt_in_progress;
00154
00155
00156
00157
00158
00159
00160 void finish_idt()
00161 {
00162 if (idt_in_progress) {
00163 extern_decls = concat(extern_decls,"};\n");
00164 idt_in_progress = FALSE;
00165 }
00166 }
00167
00168 void add_idt(lbl, item)
00169 long item;
00170 char * lbl;
00171 {
00172 if (lbl != CS_NIL) {
00173 finish_idt();
00174 }
00175 if (!idt_in_progress) {
00176 if (lbl == CS_NIL) {
00177 fprintf(stderr, "Unreachable integer data: %d\n", item);
00178 lbl = "???";
00179 }
00180 idt_in_progress = TRUE;
00181 if (lbl[0] == 'L') {
00182
00183 extern_decls = concat(extern_decls, "static ");
00184 }
00185 extern_decls = concat(concat(extern_decls, "word "),
00186 concat(C_name(lbl), "[] = {"));
00187 }
00188 extern_decls = concat(extern_decls, concat(itos(item), ","));
00189 }
00190
00191
00192
00193
00194
00195
00196 char * C_name(s)
00197 char *s;
00198 {
00199 char * result;
00200 register char *p, *q;
00201 boolean saw_us;
00202 int n_us;
00203 int n_us_so_far;
00204 boolean saw_non_us;
00205
00206 n_us = 0;
00207 for (p = s; *p != '\0'; p++) {
00208 if (*p == '_') n_us++;
00209 }
00210
00211 result = (char *) GC_malloc_atomic(strlen(s) + n_us + 1);
00212
00213 if (*s == '_') {
00214 p = s+1;
00215 n_us_so_far = 1;
00216 } else {
00217 p = s;
00218 n_us_so_far = 0;
00219 }
00220 saw_us = FALSE;
00221 saw_non_us = FALSE;
00222 q = result;
00223 while (*p != '\0') {
00224 switch(*p) {
00225 case '.':
00226 *q++ = '_';
00227 break;
00228 case '_':
00229 *q++ = '_';
00230 n_us_so_far++;
00231 saw_us = TRUE;
00232 if (saw_non_us && n_us_so_far != n_us) {
00233 *q++ = '_';
00234 }
00235 break;
00236 default:
00237 *q++ = *p;
00238 if (saw_us) {
00239 saw_non_us = TRUE;
00240 }
00241 }
00242 p++;
00243 }
00244 *q = '\0';
00245 return(result);
00246 }
00247
00248 char * lbr_label = CS_NIL;
00249 char * lba_label = CS_NIL;
00250
00251 char label_buf[MAXLABELSZ+1];
00252
00253
00254 # define WORD_PTR 1
00255 # define WORD 2
00256 # define CHAR_PTR 3
00257 # define FLOAT 4
00258
00259
00260
00261
00262
00263
00264
00265 char * coerce(expr, coercion)
00266 char * expr;
00267 int coercion;
00268 {
00269 char * result;
00270
00271 switch(coercion) {
00272 case NONE:
00273 return(expr);
00274 case WORD_PTR:
00275 return(concat(concat("((word *)", expr), ")"));
00276 case WORD:
00277 return(concat(concat("((word)", expr), ")"));
00278 case CHAR_PTR:
00279 return(concat(concat("((char *)", expr), ")"));
00280 case FLOAT:
00281 return(concat(concat("(*(float *)&", expr), ")"));
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290 void flush_slm()
00291 {
00292 if (slm != NONE) {
00293 if (slm == MEMORY) {
00294
00295 if (lm != NONE) {
00296 code = concat(code, flush_all_non_const_except(lm & ~SAFE));
00297 } else {
00298 code = concat(code, flush_all_non_const());
00299 }
00300 code = concat(code, store_code);
00301 } else {
00302 if (!(slm & SAFE)) {
00303 code = concat(code, flush_vr(slm));
00304 }
00305 if (slm_ph != CS_NIL) {
00306 set_ph(slm_ph, get_expr(slm & ~SAFE));
00307 slm_ph = CS_NIL;
00308 }
00309 }
00310 }
00311 if (lm == MEMORY) {
00312 code = concat(code, concat(flush_all_non_const(), store_code));
00313 slm = NONE;
00314
00315
00316 rem_tmps();
00317 } else if (lm == NONE) {
00318 slm = NONE;
00319 rem_tmps();
00320 } else {
00321 add_vr_def(lm & ~SAFE, lm_expr);
00322 slm = lm;
00323 }
00324 lm = NONE;
00325 }
00326
00327
00328
00329
00330
00331 # define add_modified_vr(result, expr, safe) \
00332 if ((slm & ~SAFE) != ((result) & ~SAFE)) { \
00333 rem_vr_def(lm & ~SAFE); \
00334 } \
00335 lm = (result); lm_expr = (expr); \
00336 if (safe) { \
00337 lm |= SAFE; \
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 void binary_op(result, is_float, op1, coercion1, op2, coercion2,
00349 prefix, infix, suffix, safe)
00350 long result;
00351 boolean is_float;
00352 long op1;
00353 int coercion1;
00354 long op2;
00355 int coercion2;
00356 char * prefix;
00357 char * infix;
00358 char * suffix;
00359 boolean safe;
00360 {
00361 register char * expr;
00362 char * op1_expr;
00363 char * op2_expr;
00364 char * ph = CS_NIL;
00365 boolean is_ar_ptr = (result == AR || result == GF);
00366
00367 if (result == SK) return;
00368
00369
00370 flush_slm();
00371
00372
00373 if (is_ar_ptr) {
00374 code = concat(code, flush_all_non_const());
00375
00376 }
00377 if (coercion1 == FLOAT) {
00378
00379 code = concat(code, flush_vr(op1));
00380 op1_expr = get_name(op1);
00381 } else if (op1 == (slm & ~SAFE)) {
00382 ph = placeholder();
00383 op1_expr = ph;
00384 } else {
00385 op1_expr = get_expr(op1);
00386 }
00387 if (coercion2 == FLOAT) {
00388 code = concat(code, flush_vr(op2));
00389 op2_expr = get_name(op2);
00390 } else if (op2 == (slm & ~SAFE)) {
00391 if (ph == CS_NIL) {
00392 ph = placeholder();
00393 }
00394 op2_expr = ph;
00395 } else {
00396 op2_expr = get_expr(op2);
00397 }
00398 expr = concat(concat(concat("(", prefix),
00399 coerce(op1_expr, coercion1)),
00400 concat(concat(infix, coerce(op2_expr, coercion2)),
00401 concat(suffix, ")")));
00402 if (is_float) {
00403 flush_slm();
00404 code = concat(code, coerce(get_name(result), FLOAT));
00405 code = concat(code, " = ");
00406 code = concat(code, expr);
00407 code = concat(code, ";\n");
00408 } else {
00409 add_modified_vr(result, expr, safe && !is_ar_ptr);
00410 slm_ph = ph;
00411 }
00412 if (is_ar_ptr) {
00413 flush_slm();
00414 code = concat(code, flush_vr(result));
00415 }
00416 }
00417
00418
00419
00420
00421
00422
00423 void unary_op(result, is_float, op, coercion, prefix, suffix, safe)
00424 long result;
00425 boolean is_float;
00426 long op;
00427 int coercion;
00428 char * prefix;
00429 char * suffix;
00430 boolean safe;
00431 {
00432 register char * expr;
00433 char * op_expr;
00434 char * ph = CS_NIL;
00435 boolean is_ar_ptr = (result == AR || result == GF);
00436
00437 if (result == SK) return;
00438
00439
00440 flush_slm();
00441
00442
00443 if (is_ar_ptr) {
00444 code = concat(code, flush_all_non_const());
00445 }
00446 if (coercion == FLOAT) {
00447
00448 code = concat(code, flush_vr(op));
00449 op_expr = get_name(op);
00450 } else if (op == (slm & ~SAFE)) {
00451 ph = placeholder();
00452 op_expr = ph;
00453 } else {
00454 op_expr = get_expr(op);
00455 }
00456 expr = concat(concat(prefix, coerce(op_expr, coercion)), suffix);
00457 if (!is_empty(prefix) || ! is_empty(suffix)) {
00458 expr = concat("(", concat(expr, ")"));
00459 }
00460 if (is_float) {
00461 flush_slm();
00462 code = concat(code, coerce(get_name(result), FLOAT));
00463 code = concat(code, " = ");
00464 code = concat(code, expr);
00465 code = concat(code, ";\n");
00466 } else {
00467 add_modified_vr(result, expr, safe && !is_ar_ptr);
00468 slm_ph = ph;
00469 }
00470 if (is_ar_ptr) {
00471 flush_slm();
00472 code = concat(code, flush_vr(result));
00473 }
00474 }
00475
00476
00477
00478 void nilary_op(result, is_float, rhs, safe)
00479 long result;
00480 boolean is_float;
00481 char * rhs;
00482 boolean safe;
00483 {
00484 boolean is_ar_ptr = (result == AR || result == GF);
00485
00486 if (result == SK) return;
00487 flush_slm();
00488 if (is_ar_ptr) {
00489 code = concat(code, flush_all_non_const());
00490 }
00491 if (is_float) {
00492 flush_slm();
00493 code = concat(code, coerce(get_name(result), FLOAT));
00494 code = concat(code, " = ");
00495 code = concat(code, rhs);
00496 code = concat(code, ";\n");
00497 } else {
00498 add_modified_vr(result, rhs, safe && !is_ar_ptr);
00499 slm_ph = CS_NIL;
00500 }
00501 if (is_ar_ptr) {
00502 flush_slm();
00503 code = concat(code, flush_vr(result));
00504 }
00505 }
00506
00507
00508
00509 void emit(s)
00510 char *s;
00511 {
00512 char * flattened;
00513 long len;
00514
00515 flattened = flatten(s, &len);
00516 if (write(STDOUT_FD, flattened, len) < len) {
00517 fprintf(stderr, "Write to stdout failed\n");
00518 exit(1);
00519 }
00520 GC_free(flattened);
00521 }
00522
00523 main(argc, argv)
00524 int argc;
00525 char **argv;
00526 {
00527 int opc = RTN;
00528 long arg1, arg2, arg3;
00529 char * label;
00530 char * cmd;
00531 boolean has_flags;
00532 boolean bad_flag = FALSE;
00533 boolean xflag = FALSE;
00534 boolean Oflag = FALSE;
00535 char *Cfile;
00536 char *Gfile;
00537 char *sfile;
00538 int len;
00539
00540 GC_init();
00541
00542 has_flags = (argc == 5);
00543 if (has_flags) {
00544 char *s = &(argv[1][1]);
00545
00546 while (*s) {
00547 switch(*s) {
00548 case 'O':
00549 Oflag = TRUE;
00550 break;
00551 case 'x':
00552 xflag = TRUE;
00553 break;
00554 default:
00555 bad_flag = TRUE;
00556 }
00557 s++;
00558 }
00559 }
00560 if (argc < 4 || argc > 5 || bad_flag) {
00561 fprintf(stderr,
00562 "Usage: %s [-[O][x]] file.G file.s global_ar_name\n",
00563 argv[0]);
00564 exit(1);
00565 }
00566 if (has_flags) {
00567 Gfile = argv[2];
00568 sfile = argv[3];
00569 global_ar_name = C_name(argv[4]);
00570 } else {
00571 Gfile = argv[1];
00572 sfile = argv[2];
00573 global_ar_name = C_name(argv[3]);
00574 }
00575 len = strlen(sfile);
00576 if (len < 3 || sfile[len-2] != '.' || sfile[len-1] != 's') {
00577 fprintf(stderr, "Output file %s name should end in .s\n", sfile);
00578 exit(1);
00579 }
00580 Cfile = (char *)GC_malloc_atomic(len+1);
00581 strcpy(Cfile,sfile);
00582 Cfile[len-1] = 'c';
00583 cmd = concat(concat(DELAB, " "), Gfile);
00584 cmd = flatten(cmd, 0);
00585 in_file = popen(cmd, "r");
00586
00587 (void) close(STDOUT_FD);
00588 if (open(Cfile, O_WRONLY | O_CREAT | O_TRUNC, 0644) != STDOUT_FD) {
00589 fprintf(stderr, "Can't open %s\n", Cfile);
00590 exit(1);
00591 }
00592
00593 init_tmps();
00594
00595 emit(STANDARD_PREFIX);
00596
00597
00598 emit (concat("extern word ", concat(global_ar_name, "[];\n")));
00599
00600 while (!feof(in_file)) {
00601 if (opc != LBA) {
00602 label = CS_NIL;
00603 }
00604 opc = getw(in_file);
00605 if (feof(in_file)) {
00606
00607 break;
00608 }
00609 if (opc < 0 && opc > N_OP_CODES) {
00610 fprintf(stderr, "Bad op code\n");
00611 exit(1);
00612 }
00613 if (opc <= MAX_LABEL_OP) {
00614 char *p = label_buf;
00615 int c;
00616 int i = 0;
00617
00618 while ((c = getc(in_file)) != '\0' && c != EOF) {
00619 *p++ = c;
00620 if (++i >= MAXLABELSZ) {
00621 fprintf(stderr, "Label too long\n");
00622 p = label_buf;
00623 }
00624 }
00625 *p = '\0';
00626 label = (char *) GC_malloc_atomic(i+1);
00627 strcpy(label, label_buf);
00628 } else {
00629 arg1 = getw(in_file);
00630 arg2 = getw(in_file);
00631 arg3 = getw(in_file);
00632 if (!gf_refd) {
00633 if (arg1 == GF && opc != LDN && opc != UDC
00634 && opc != CLC && opc != HINT && opc != ARG
00635 && opc != GAR) {
00636 gf_refd = TRUE;
00637 }
00638 if (arg2 == GF && opc != LDI && opc != STI
00639 && opc != LDC && opc != HINT && opc != CLI
00640 && opc != DCL) {
00641 gf_refd = TRUE;
00642 }
00643 if (arg3 == GF && opc != HINT) {
00644 gf_refd = TRUE;
00645 }
00646 }
00647 }
00648
00649 if (suppress) {
00650 if (opc != LBL && opc != DCL && opc != UDC) {
00651
00652 continue;
00653 }
00654 }
00655
00656 switch(opc) {
00657 case BR:
00658 flush_slm();
00659 code = concat(code, flush_all_exprs());
00660 rem_tmps();
00661 code = concat(concat(code, "goto "), concat(C_name(label), ";\n"));
00662 suppress = TRUE;
00663 break;
00664
00665 case BRT:
00666 flush_slm();
00667 code = concat(code, flush_all_except(TL));
00668 code = concat(concat(concat(code, "if ("),
00669 concat(get_expr(TL),") goto ")),
00670 concat(C_name(label), ";\n"));
00671
00672 rem_vr_def(TL);
00673 rem_tmps();
00674 break;
00675
00676 case BRF:
00677 flush_slm();
00678 code = concat(code, flush_all_except(TL));
00679 code = concat(concat(concat(code, "if (!"),
00680 concat(get_expr(TL),") goto ")),
00681 concat(C_name(label), ";\n"));
00682
00683 rem_vr_def(TL);
00684 rem_tmps();
00685 break;
00686
00687 case CLL:
00688 case ERR:
00689 case CLC:
00690 {
00691 char * expr;
00692 char * args;
00693 boolean lm_is_arg = ((lm & ARG_FLAG) &&
00694 lm != MEMORY && lm != NONE);
00695 boolean slm_is_arg = ((slm & ARG_FLAG) &&
00696 slm != MEMORY && slm != NONE);
00697
00698
00699
00700
00701
00702
00703
00704 if (!lm_is_arg) {
00705 flush_slm();
00706 flush_slm();
00707 args = arg_list(n_args);
00708 } else if (!slm_is_arg) {
00709 flush_slm();
00710 args = arg_list(n_args);
00711 flush_slm();
00712 } else {
00713 if (slm_ph != CS_NIL) {
00714 fprintf(stderr, "Bad slm_ph value\n");
00715 abort();
00716 }
00717
00718
00719
00720
00721
00722 add_vr_def(lm & ~SAFE, lm_expr);
00723 lm = NONE;
00724 args = arg_list(n_args);
00725 flush_slm();
00726 }
00727 if (opc == CLL && n_args != 1) {
00728 fprintf(stderr, "Wrong number of args (%d) to CLL\n",
00729 n_args);
00730 }
00731 if (opc == CLC) {
00732 if (n_args != arg1) {
00733 fprintf(stderr,
00734 "Wrong number of args (%d vs %d) to CLC\n",
00735 n_args, arg1);
00736 }
00737 label = lba_label;
00738 }
00739
00740 expr = concat(C_name(label), "(");
00741
00742 expr = concat(expr, args);
00743 expr = concat(expr, ")");
00744 rem_vr_def(RL);
00745 code = concat(concat(code, "RL = (word)"),
00746 concat(expr, ";\n"));
00747 n_args = 0;
00748 }
00749 break;
00750
00751 case LBL:
00752 suppress = FALSE;
00753 flush_slm();
00754 code = concat(code, flush_all_exprs());
00755 code = concat(concat(code, C_name(label)), ":\n");
00756 break;
00757
00758 case EXT:
00759 finish_idt();
00760 switch(extern_type) {
00761 case DCL_INT:
00762 extern_decls = concat(concat(extern_decls, "extern word "),
00763 concat(C_name(label), "[];\n"));
00764 break;
00765 case DCL_ADDR:
00766 extern_decls = concat(concat(extern_decls, "extern word *"),
00767 concat(C_name(label), "[];\n"));
00768 break;
00769 case DCL_FLOAT:
00770 extern_decls = concat(concat(extern_decls, "extern float "),
00771 concat(C_name(label), "[];\n"));
00772 case DCL_DBL_FLOAT:
00773 extern_decls = concat(concat(extern_decls, "extern double "),
00774 concat(C_name(label), "[];\n"));
00775 break;
00776 case NONE:
00777
00778 extern_decls = concat(concat(extern_decls, "extern word "),
00779 concat(C_name(label), "();\n"));
00780 break;
00781 default:
00782 fprintf(stderr, "Bad type for EXT\n");
00783 break;
00784 }
00785 extern_type = NONE;
00786 break;
00787
00788 case LBA:
00789
00790 lba_label = label;
00791 break;
00792
00793 case BFN:
00794
00795
00796 fn_name = C_name(label);
00797 n_params = 0;
00798 is_simple = FALSE;
00799 gf_refd = FALSE;
00800 ar_refd = FALSE;
00801 break;
00802
00803 case TFB:
00804 case TFE:
00805 fprintf(stderr, "Tracing not yet implemented\n");
00806 break;
00807
00808 case PRO:
00809
00810 profile = TRUE;
00811 break;
00812
00813 case ADT:
00814 fprintf(stderr, "Obsolete ADT instruction encountered\n");
00815 exit(1);
00816
00817 case BSF:
00818 finish_idt();
00819 fn_name = C_name(label);
00820 n_params = 0;
00821 is_simple = TRUE;
00822 gf_refd = FALSE;
00823 ar_refd = FALSE;
00824 break;
00825
00826 case LBR:
00827 lbr_label = label;
00828 break;
00829
00830 case DDT:
00831 finish_idt();
00832 if (lba_label == CS_NIL) {
00833 fprintf(stderr, "Unlabelled double data\n");
00834 } else {
00835 if (lba_label[0] == 'L') {
00836 extern_decls = concat(extern_decls, "static ");
00837 }
00838 extern_decls = concat(concat(extern_decls, "double "),
00839 concat(concat(C_name(lba_label), "[] = {"),
00840 concat(label, "};\n")));
00841 }
00842 break;
00843
00844 case FDT:
00845 finish_idt();
00846 if (lba_label == CS_NIL) {
00847 fprintf(stderr, "Unlabelled float data\n");
00848 } else {
00849 if (lba_label[0] == 'L') {
00850 extern_decls = concat(extern_decls, "static ");
00851 }
00852 extern_decls = concat(concat(extern_decls, "float "),
00853 concat(concat(C_name(lba_label), "[] = {"),
00854 concat(label, "};\n")));
00855 }
00856 break;
00857
00858
00859
00860 case DCL:
00861 add_undef_vr(arg1);
00862 if (lbr_label != CS_NIL) {
00863 code = concat(concat("/* ", lbr_label),
00864 concat(concat(" ~ ", get_name(arg1)),
00865 concat(" */\n", code)));
00866 lbr_label = CS_NIL;
00867 }
00868 break;
00869
00870 case UDC:
00871 if (arg1 == (lm & ~SAFE)) {
00872 lm = NONE;
00873 }
00874 if (arg1 == (slm & ~SAFE)) {
00875 if (lm != NONE && slm_ph != CS_NIL) {
00876
00877
00878 set_ph(slm_ph, get_expr(arg1));
00879 slm_ph = CS_NIL;
00880 }
00881 slm = NONE;
00882 }
00883 rem_vr(arg1);
00884 break;
00885
00886 case ALH:
00887 if (arg2 == SK) break;
00888 flush_slm();
00889 if (arg1 != arg2) rem_vr_def(arg2);
00890 flush_slm();
00891 {
00892 char * sz = get_expr(arg1);
00893 char first_c;
00894 boolean is_number;
00895
00896 GET_FIRST(sz, first_c);
00897 is_number = (first_c >= '0' && first_c <= '9');
00898 if (!is_number) {
00899
00900
00901 code = concat(code, flush_vr(arg1));
00902 sz = get_expr(arg1);
00903 }
00904 if ( saw_ons && is_number ) {
00905 ons_stack[ons_depth++] = TRUE;
00906 code = concat(concat(code, "{ word NS["),
00907 concat(concat(sz,"];\n"),
00908 concat(get_name(arg2), " = (word) NS;\n")));
00909 } else {
00910 if (saw_ons) {
00911 ons_stack[ons_depth++] = FALSE;
00912 }
00913 {
00914 char * ac;
00915 char * sz_expr;
00916
00917 if (!is_number && arg1 == arg2) {
00918 sz_expr = "sz";
00919 } else {
00920 sz_expr = sz;
00921 }
00922 if (arg2 == RL) {
00923
00924
00925
00926 ac = "alloc_cw(";
00927 } else if (arg2 == AR || arg2 == GF) {
00928 ac = "alloc_nc(";
00929 } else {
00930 ac = "alloc(";
00931 }
00932 ac = concat(ac,
00933 concat(concat(sz_expr, ","),
00934 concat(get_name(arg2), ");")));
00935 if (!is_number && arg1 == arg2) {
00936 ac = concat(concat("{ word sz = (word)", sz),
00937 concat(";", concat(ac, "}")));
00938 }
00939 code = concat(code, concat(ac, "\n"));
00940 }
00941 }
00942 if (ons_depth >= ONS_MAX - 2) {
00943 fprintf(stderr, "Too many nested allocations\n");
00944 exit(1);
00945 }
00946 }
00947 if (arg1 == arg2) rem_vr_def(arg2);
00948 saw_ons = FALSE;
00949 break;
00950
00951 case GAR:
00952 if (arg2 != SK) {
00953 nilary_op(arg2, FALSE, par_name(arg1), TRUE);
00954 }
00955 if (arg1 > n_params) n_params = arg1;
00956 break;
00957
00958 case ALS:
00959 fprintf(stderr, "Encountered ALS instruction\n");
00960 exit(1);
00961
00962 case LDI:
00963 unary_op(arg3, FALSE, arg1, WORD_PTR,
00964 "", concat("[", concat(itos(arg2), "]")),
00965 (arg1 == AR || arg1 == GF));
00966 break;
00967
00968 case STI:
00969 if (arg1 != SK) {
00970 char * arg1_expr;
00971 char * arg3_expr;
00972 char * ph = CS_NIL;
00973
00974 flush_slm();
00975 if (arg1 == (slm & ~SAFE)) {
00976 ph = placeholder();
00977 arg1_expr = ph;
00978 } else {
00979 arg1_expr = get_expr(arg1);
00980 }
00981 if (arg3 == (slm & ~SAFE)) {
00982 if (ph == CS_NIL) {
00983 ph = placeholder();
00984 }
00985 arg3_expr = ph;
00986 } else {
00987 arg3_expr = get_expr(arg3);
00988 }
00989 lm = MEMORY;
00990 slm_ph = ph;
00991 store_code = concat(concat("((word *)", arg1_expr),
00992 concat(")[(word)",
00993 concat(itos(arg2), "] = (word)")));
00994 store_code = concat(store_code,
00995 concat(arg3_expr, ";\n"));
00996 }
00997 break;
00998
00999 case CLI:
01000 {
01001 char * expr;
01002 char * fn;
01003 char * args;
01004 boolean lm_is_arg = ((lm & ARG_FLAG) &&
01005 lm != MEMORY && lm != NONE);
01006
01007
01008
01009
01010
01011
01012
01013 flush_slm();
01014 if (!lm_is_arg) {
01015 flush_slm();
01016 args = arg_list(n_args);
01017 } else {
01018 args = arg_list(n_args);
01019 flush_slm();
01020 }
01021 if (n_args != 1) {
01022 fprintf(stderr, "Wrong number of args (%d) to CLI\n",
01023 n_args);
01024 }
01025 fn = concat(concat("((word_func_ptr *)", get_expr(arg1)),
01026 concat(")[(word)",
01027 concat(itos(arg2), "]")));
01028 expr = concat(fn, "(");
01029
01030 expr = concat(expr, args);
01031 expr = concat(expr, ")");
01032 rem_vr_def(RL);
01033 code = concat(concat(code, "RL = (word)"),
01034 concat(expr, ";\n"));
01035 n_args = 0;
01036 }
01037 break;
01038
01039 case LDN:
01040 nilary_op(arg2, FALSE, itos(arg1), TRUE);
01041 break;
01042
01043 case RTN:
01044 {
01045 char * header;
01046 char * par_list;
01047
01048 if (fn_name == CS_NIL) {
01049 fprintf(stderr, "Anonymous function\n");
01050 fn_name = "?anonymous?";
01051 }
01052 if (ons_depth != 0) {
01053 fprintf(stderr,
01054 "Nonmatching stack (de)allocations %d\n",
01055 ons_depth);
01056 exit(1);
01057 }
01058
01059
01060 flush_slm();
01061 rem_tmps();
01062 finish_idt();
01063
01064 code = concat(concat(code, "return((word)"),
01065 concat(get_expr(RL), ");\n}\n\n"));
01066 code = concat(tmp_decls(max_tmp), code);
01067 lm = NONE;
01068 if (gf_refd) {
01069 code = concat(concat(
01070 "register word * GF = ((word *)(",
01071 global_ar_name),
01072 concat("[0]));\n", code));
01073 }
01074 if (ar_refd && is_simple) {
01075 code = concat("register word * AR;\n", code);
01076 }
01077 code = concat("word TL;\n", code);
01078 code = concat("register word RL;\n", code);
01079 header = concat ("\nword ", concat(fn_name, "("));
01080 if (is_simple) {
01081 header = concat(header,
01082 (par_list = par_names(n_params)));
01083 } else {
01084 header = concat(header, "AR");
01085 }
01086 header = concat(header, ")\n");
01087 if (is_simple) {
01088 if (n_params > 0) {
01089 header = concat(concat(header, "word "),
01090 concat(par_list, ";\n{\n"));
01091 } else {
01092 header = concat(header, "{\n");
01093 }
01094 } else {
01095 header = concat(header, "register word * AR;\n{\n");
01096 }
01097 code = concat(extern_decls, concat(header, code));
01098 emit(code);
01099
01100
01101 rem_vr_def(RL);
01102 rem_vr_def(TL);
01103 reset_tmps();
01104 fn_name = CS_NIL;
01105 n_params = 0;
01106 gf_refd = FALSE;
01107 code = "";
01108 extern_decls = "";
01109 }
01110 break;
01111
01112 case LDL:
01113 finish_idt();
01114
01115
01116
01117 if (lba_label == CS_NIL) {
01118 fprintf(stderr, "No LBA preceding LDL\n");
01119 exit(1);
01120 }
01121 nilary_op(arg1, FALSE, coerce(C_name(lba_label), WORD_PTR), TRUE);
01122 break;
01123
01124 case MOV:
01125 unary_op(arg2, FALSE, arg1, NONE, "", "",
01126 (arg1 == AR || arg1 == GF));
01127 break;
01128
01129 case TAR:
01130 fprintf(stderr, "Tracing not yet implemented\n");
01131 break;
01132
01133 case PSH:
01134 fprintf(stderr, "Encountered PSH instruction\n");
01135 exit(1);
01136
01137 case ADP:
01138 {
01139 char * displ;
01140 boolean is_number;
01141 char first_c;
01142 boolean is_ar_ptr = (arg1 == AR || arg1 == GF);
01143
01144 if (is_ar_ptr) {
01145 displ = get_expr(arg2);
01146
01147
01148
01149 GET_FIRST(displ, first_c);
01150 is_number = (first_c == '-'
01151 || first_c >= '0' && first_c <= '9');
01152 }
01153 binary_op(arg3, FALSE, arg1, WORD_PTR, arg2, WORD,
01154 "", "+", "",
01155 is_ar_ptr && is_number);
01156 }
01157 break;
01158
01159
01160
01161 case ALA:
01162 if (arg2 == SK) break;
01163 flush_slm();
01164 if (arg1 != arg2) rem_vr_def(arg2);
01165 flush_slm();
01166 {
01167 char * sz = get_expr(arg1);
01168 char first_c;
01169 boolean is_number;
01170
01171 GET_FIRST(sz, first_c);
01172 is_number = (first_c >= '0' && first_c <= '9');
01173 if (!is_number) {
01174
01175
01176 code = concat(code, flush_vr(arg1));
01177 sz = get_expr(arg1);
01178 }
01179 if ( saw_ons && is_number ) {
01180 ons_stack[ons_depth++] = TRUE;
01181 code = concat(concat(code, "{ word NS["),
01182 concat(concat(sz,"];\n"),
01183 concat(get_name(arg2), " = (word) NS;\n")));
01184 } else {
01185 if (saw_ons) {
01186 ons_stack[ons_depth++] = FALSE;
01187 }
01188 {
01189 char * ac;
01190 char * sz_expr;
01191
01192 if (!is_number && arg1 == arg2) {
01193 sz_expr = "sz";
01194 } else {
01195 sz_expr = sz;
01196 }
01197 if (arg2 == RL) {
01198
01199
01200
01201 ac = "alloc_a_cw(";
01202 } else if (arg2 == AR || arg2 == GF) {
01203 ac = "alloc_a_nc(";
01204 } else {
01205 ac = "alloc_a(";
01206 }
01207 ac = concat(ac,
01208 concat(concat(sz_expr, ","),
01209 concat(get_name(arg2), ");")));
01210 if (!is_number && arg1 == arg2) {
01211 ac = concat(concat("{ word sz = (word)", sz),
01212 concat(";", concat(ac, "}")));
01213 }
01214 code = concat(code, concat(ac, "\n"));
01215 }
01216 }
01217 if (ons_depth >= ONS_MAX - 2) {
01218 fprintf(stderr, "Too many nested allocations\n");
01219 exit(1);
01220 }
01221 }
01222 if (arg1 == arg2) rem_vr_def(arg2);
01223 saw_ons = FALSE;
01224 break;
01225
01226 case HINT:
01227 switch(arg1) {
01228 case OPT:
01229
01230
01231 break;
01232 case NP:
01233 case AL:
01234
01235 break;
01236 case DEA:
01237
01238
01239 flush_slm();
01240 if (arg2 == AR || arg2 == GF) {
01241 code = concat(code, flush_all_non_const());
01242 } else {
01243 flush_slm();
01244 }
01245 if (saw_ons) {
01246 saw_ons = FALSE;
01247 if (ons_stack[--ons_depth]) {
01248 code = concat(code, "}\n");
01249 break;
01250 }
01251 }
01252 code = concat(concat(code, "GC_free("),
01253 concat(get_expr(arg2), ");\n"));
01254 break;
01255 case NSC:
01256 case STSZ:
01257 case PT:
01258
01259 break;
01260 case DEAD:
01261 if (arg2 == (lm & ~SAFE)) {
01262 lm = NONE;
01263 }
01264 if (arg2 == (slm & ~SAFE)) {
01265 if (lm != NONE && slm_ph != CS_NIL) {
01266
01267
01268 set_ph(slm_ph, get_expr(arg2));
01269 slm_ph = CS_NIL;
01270 }
01271 slm = NONE;
01272 }
01273 rem_vr_def(arg2);
01274 break;
01275 case GFU:
01276 if (is_simple) {
01277
01278
01279 ar_refd = TRUE;
01280 }
01281 break;
01282 case LIVE:
01283
01284
01285
01286
01287 # ifdef GCC
01288
01289
01290
01291 code = concat(code, "# ifdef __GNUC__\n");
01292 code = concat(code, "asm volatile(\" \": : \"g\" (");
01293 code = concat(code, get_expr(arg2));
01294 code = concat(code, "));\n");
01295 code = concat(code, "# endif\n");
01296 # else
01297
01298
01299
01300 # endif
01301 break;
01302 case ET:
01303 extern_type = arg2;
01304 break;
01305 case ONS:
01306 saw_ons = TRUE;
01307 break;
01308 }
01309 break;
01310
01311 case ARG:
01312 {
01313 char * rhs;
01314 boolean is_const;
01315 char first_c;
01316
01317 if (arg2 == (lm & ~ SAFE)) {
01318 rhs = lm_expr;
01319 } else {
01320 rhs = get_expr(arg2);
01321 }
01322 GET_FIRST(rhs, first_c);
01323 is_const = (first_c == '-' || first_c == '"'
01324 || first_c >= '0' && first_c <= '9');
01325 add_undef_vr(ARGLOC(arg1));
01326 unary_op(ARGLOC(arg1), FALSE, arg2, WORD, "", "",
01327 (is_const || arg2 == AR || arg2 == GF
01328 || is_param(first_c)));
01329 if (n_args < arg1) n_args = arg1;
01330 }
01331 break;
01332
01333 case ADI:
01334 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "+", "", FALSE);
01335 break;
01336
01337 case SBI:
01338 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "-", "", FALSE);
01339 break;
01340
01341 case MLI:
01342 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "*", "", FALSE);
01343 break;
01344
01345 case DVI:
01346 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "/", "", FALSE);
01347 break;
01348
01349 case NGI:
01350 unary_op(arg2, FALSE, arg1, WORD, "-", "", FALSE);
01351 break;
01352
01353 case IDT:
01354 add_idt(lba_label, arg1);
01355 break;
01356
01357 case EQI:
01358 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "==", "", FALSE);
01359 break;
01360
01361 case LTI:
01362 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "<", "", FALSE);
01363 break;
01364
01365 case GTI:
01366 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", ">", "", FALSE);
01367 break;
01368
01369 case NEI:
01370 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "!=", "", FALSE);
01371 break;
01372
01373 case LEI:
01374 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "<=", "", FALSE);
01375 break;
01376
01377 case GEI:
01378 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", ">=", "", FALSE);
01379 break;
01380
01381 case SHI:
01382 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "shift(", ",", ")", FALSE);
01383 break;
01384
01385 case ABI:
01386 unary_op(arg2, FALSE, arg1, WORD, "abs(", ")", FALSE);
01387 break;
01388
01389 case TRU:
01390 nilary_op(arg1, FALSE, "1", TRUE);
01391 break;
01392
01393 case FLS:
01394 nilary_op(arg1, FALSE, "0", TRUE);
01395 break;
01396
01397 case LDS:
01398 {
01399 char * string;
01400 if (lba_label == CS_NIL) {
01401 fprintf(stderr, "LDS: missing label\n");
01402 lba_label = "???";
01403 }
01404 string = concat("\"", concat(rmcntrl(lba_label), "\""));
01405 nilary_op(arg1, FALSE, string, TRUE);
01406 }
01407 break;
01408
01409 case LDC:
01410 binary_op(arg3, FALSE, arg1, CHAR_PTR, arg2, WORD,
01411 "", "[", "]", FALSE);
01412 break;
01413
01414 case AND:
01415 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "&", "", FALSE);
01416 break;
01417
01418 case OR:
01419 binary_op(arg3, FALSE, arg1, WORD, arg2, WORD, "", "|", "", FALSE);
01420 break;
01421
01422 case NOT:
01423 unary_op(arg2, FALSE, arg1, WORD, "!", "", FALSE);
01424 break;
01425
01426 case ADF:
01427
01428 case SBF:
01429
01430 case MLF:
01431
01432 case DVF:
01433
01434 case NGF:
01435
01436 case EXF:
01437
01438 default:
01439 fprintf(stderr, "Unrecognized op code: %d\n", opc);
01440 exit(1);
01441 }
01442 if (opc != LBA) {
01443 lba_label = CS_NIL;
01444 }
01445 }
01446
01447 finish_idt();
01448 if (!is_empty(extern_decls)) {
01449 emit(extern_decls);
01450 }
01451
01452 {
01453 (void) close(STDOUT_FD);
01454 if (open("/dev/tty", O_WRONLY | O_CREAT | O_TRUNC, 0644) != STDOUT_FD) {
01455 fprintf(stderr, "/dev/tty reopen failed - continuing\n");
01456 }
01457 pclose(in_file);
01458
01459
01460
01461
01462 if (profile) {
01463 execl(CC, "cc", "-S", Oflag? "-O" : "-g" , "-p", "-o", sfile, Cfile, 0);
01464 } else {
01465 execl(CC, "cc", "-S", Oflag? "-O" : "-g" , "-o", sfile, Cfile, 0);
01466 }
01467 fprintf(stderr, "Couldn't exec %s\n", CC);
01468 exit(1);
01469 }
01470 }