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