00001 # define DEBUG DEBUG
00002 #include <stdio.h>
00003 #include <ctype.h>
00004 #include "../parm.h"
00005 #include "op_codes.h"
00006 #include "codegen.h"
00007
00008 #define OCLENGTH 9
00009
00010 #define MAXLOC 100000
00011
00012
00013
00014
00015
00016 typedef struct hrecord {
00017 char hr_name[OCLENGTH+1];
00018 int hr_val;
00019 struct hrecord * hr_next;
00020 } hrecord;
00021
00022 # define NIL 0
00023
00024 # define TABSIZE 50
00025 # define hash(s) ((((s)[0]<<2) + (((s)[1]) == '\0'? 0 : (s)[1] + (s)[2]))%TABSIZE)
00026
00027 static hrecord * htable[TABSIZE];
00028
00029
00030
00031 void add_RIC_table(nm, val)
00032 char * nm;
00033 int val;
00034 {
00035 register int index = hash(nm);
00036 register hrecord * nhr = (hrecord *)gc_malloc(sizeof (hrecord));
00037
00038 nhr -> hr_next = htable[index];
00039 strcpy(nhr -> hr_name,nm);
00040 nhr -> hr_val = val;
00041 htable[index] = nhr;
00042 }
00043
00044 extern char * op_code_table[];
00045 #define NONE ((char *)0)
00046
00047
00048 void init_RIC_table()
00049 {
00050 int i;
00051
00052 for ( i = 0; i < N_OP_CODES; i++ ) {
00053 if (op_code_table[i] != NONE) {
00054 add_RIC_table(op_code_table[i], i);
00055 }
00056 }
00057
00058 add_RIC_table("RS", RS);
00059 add_RIC_table("AR", AR);
00060 add_RIC_table("SP", SP);
00061 add_RIC_table("GF", GF);
00062 add_RIC_table("UN", UN);
00063 add_RIC_table("SK", SK);
00064 add_RIC_table("RL", RL);
00065 add_RIC_table("TL", TL);
00066 add_RIC_table("C0", C0);
00067 add_RIC_table("C1", C1);
00068 add_RIC_table("C2", C2);
00069 add_RIC_table("C3", C3);
00070 add_RIC_table("C4", C4);
00071 add_RIC_table("T1", T1);
00072 add_RIC_table("T2", T2);
00073
00074 add_RIC_table("ADDR", DCL_ADDR);
00075 add_RIC_table("INT", DCL_INT);
00076 add_RIC_table("FLOAT", DCL_FLOAT);
00077 add_RIC_table("DBL_FLOAT", DCL_DBL_FLOAT);
00078
00079 add_RIC_table("OPT", OPT);
00080 add_RIC_table("NP", NP);
00081 add_RIC_table("PT", PT);
00082 add_RIC_table("AL", AL);
00083 add_RIC_table("DEA", DEA);
00084 add_RIC_table("NSC", NSC);
00085 add_RIC_table("STSZ", STSZ);
00086 add_RIC_table("DEAD", DEAD);
00087 add_RIC_table("GFU",GFU);
00088 add_RIC_table("LIVE",LIVE);
00089 add_RIC_table("ET", ET);
00090 add_RIC_table("ONS", ONS);
00091 }
00092
00093
00094
00095 int find_RIC_table(name)
00096 char * name;
00097 {
00098 register hrecord * ce = htable[hash(name)];
00099
00100 while (ce != NIL) {
00101 if (strcmp(ce -> hr_name, name) == 0) {
00102 return (ce -> hr_val);
00103 }
00104 ce = ce -> hr_next;
00105 }
00106
00107 return(MISSING);
00108 }
00109
00110
00111
00112
00113 static char field_buf[OCLENGTH+1];
00114
00115 static char * extract_field(p)
00116 char * p;
00117 {
00118 register int i;
00119 register char c;
00120
00121 for (i = 0; i < OCLENGTH; i ++) {
00122 c = *p++;
00123 switch(c) {
00124 case '\0':
00125 case ' ':
00126 case '\t':
00127 case '\n':
00128 case ',':
00129 case ';':
00130 field_buf[i] = '\0';
00131 return(p-1);
00132 default:
00133 field_buf[i] = c;
00134 }
00135 }
00136 field_buf[OCLENGTH] = '\0';
00137 return(p);
00138 }
00139
00140
00141 void free_RIC(p)
00142 struct RIC_instr * p;
00143 {
00144 struct RIC_instr *current, *next;
00145
00146 current = p;
00147 while (current != (struct RIC_instr *) 0) {
00148 next = current -> next_instr;
00149 free(current);
00150 current = next;
00151 }
00152 }
00153
00154
00155 put_RIC(seq, f)
00156 struct RIC_instr * seq;
00157 FILE * f;
00158 {
00159 struct RIC_instr *current;
00160
00161 for (current = seq; current != (struct RIC_instr *) 0;
00162 current = current -> next_instr) {
00163 putc(current -> op_code, f);
00164 putc(current -> label_arg, f); putc(current -> n_args, f);
00165 if (current -> label_arg) {
00166 char * s = current -> label;
00167 for (; *s != '\0'; s++) {
00168 putc(*s, f);
00169 }
00170 putc(0, f);
00171 } else {
00172 putw(current -> arg[0], f);
00173 putw(current -> arg[1], f);
00174 putw(current -> arg[2], f);
00175 }
00176 }
00177
00178 putc(0,f);
00179 }
00180
00181 extern long avail_loc;
00182
00183
00184
00185 struct RIC_instr * get_RIC(f)
00186 FILE * f;
00187 {
00188 struct RIC_instr *current;
00189 struct RIC_instr *last;
00190 struct RIC_instr *result = (struct RIC_instr *)0;
00191 int opcode;
00192 int label_arg;
00193 int n_args;
00194 long arg0;
00195 char label_buf[MAXLABELSZ+1];
00196
00197 while ((opcode = getc(f)) != 0) {
00198 label_arg = getc(f);
00199 n_args = getc(f);
00200 if (feof(f)) {
00201 dbgmsg("Unexpected end of file\n");
00202 abort();
00203 }
00204 if (label_arg) {
00205 char * s = label_buf;
00206 char * t;
00207
00208 while((*s++ = getc(f)) != '\0');
00209 current = (struct RIC_instr *) gc_malloc(sizeof(struct RIC_instr)
00210 + s - label_buf);
00211
00212 s = current -> label;
00213 t = label_buf;
00214 while (*s++ = *t++);
00215 } else {
00216 current = (struct RIC_instr *) gc_malloc(sizeof(struct RIC_instr));
00217 current -> arg[0] = arg0 = getw(f);
00218 current -> arg[1] = getw(f);
00219 current -> arg[2] = getw(f);
00220 current -> label[0] = '\0';
00221 }
00222
00223 if (opcode == DCL && arg0 >= avail_loc) {
00224 if ((arg0 & ARG_BIT) || arg0 == RS) {
00225 dbgmsg("get_RIC: Attempt to declare argument or result\n");
00226 abort(arg0);
00227 }
00228 # ifdef DEBUG
00229 if (((unsigned)arg0) > 10000000) {
00230 dbgmsg("get_RIC: Bad declaration\n");
00231 abort(arg0);
00232 }
00233 # endif
00234 avail_loc = arg0+1;
00235 }
00236 current -> op_code = opcode; current -> n_args = n_args;
00237 current -> label_arg = label_arg;
00238 current -> next_instr = (struct RIC_instr *)0;
00239
00240 if (result == (struct RIC_instr *)0) {
00241 result = last = current;
00242 } else {
00243 last -> next_instr = current;
00244 last = current;
00245 }
00246 }
00247 return(result);
00248 }
00249
00250
00251
00252
00253
00254
00255 struct RIC_instr * parse_RIC(s)
00256 char **s;
00257 {
00258 # define skip_blanks while (*p == ' ' || *p == '\t' || *p == ',') { p++; }
00259 # define AT_END (*p == '\0' || *p == '\n' || *p == ';')
00260 char *p = *s;
00261 int op_code;
00262 int i;
00263 struct RIC_instr * result;
00264
00265 skip_blanks;
00266 # ifdef DEBUG
00267 if (AT_END) {
00268 dbgmsg ("Empty RIC line\n");
00269 abort();
00270 }
00271 # endif
00272 p = extract_field(p);
00273 op_code = find_RIC_table(field_buf);
00274 # ifdef DEBUG
00275 if (op_code == MISSING) {
00276 dbgmsg ("Bad RIC opcode: %s\n", field_buf);
00277 abort();
00278 }
00279 # endif
00280 skip_blanks;
00281 if (*p == '\"') {
00282 char * q;
00283 int i = 0;
00284
00285
00286 # ifdef DEBUG
00287 if (i > MAX_LABEL_OP) {
00288 dbgmsg("Label with big op code, oc = %d\n", i);
00289 }
00290 # endif
00291 p++;
00292 result = (struct RIC_instr *) gc_malloc(sizeof(struct RIC_instr)
00293 + ((char *)(index(p,'"'))) - p);
00294 result -> op_code = op_code;
00295 result -> n_args = 1;
00296 result -> next_instr = (struct RIC_instr *)0;
00297 q = result -> label;
00298 while ((*q = *p++) != '\"') {
00299 if (*q == '\\') {
00300
00301 int j,k;
00302
00303 k = 0;
00304 for (j = 0; j < 3; j++) {
00305 k = 8*k + (*p++) - '0';
00306 }
00307 *q = k;
00308 }
00309 q++;
00310 }
00311 *q = '\0';
00312 skip_blanks;
00313 # ifdef DEBUG
00314 if (!(AT_END)) {
00315 dbgmsg("Junk: %s following RIC label: %s\n", p, result -> label);
00316 }
00317 # endif
00318 result -> label_arg = TRUE;
00319 } else {
00320
00321 result = (struct RIC_instr *) gc_malloc(sizeof(struct RIC_instr));
00322 result -> label_arg = FALSE;
00323 result -> op_code = op_code;
00324 result -> n_args = 0;
00325 result -> next_instr = (struct RIC_instr *)0;
00326 while (!(AT_END)) {
00327 if (isdigit(*p)) {
00328 int v = 0;
00329 while (isdigit(*p)) {
00330 v = v * 10 + (*p++ - '0');
00331 }
00332 result -> arg[result -> n_args++] = v;
00333 } else if (*p == '$') {
00334 int v = 0;
00335
00336 p++;
00337 while (isdigit(*p)) {
00338 v = v * 10 + (*p++ - '0');
00339 }
00340 # ifdef DEBUG
00341 if (v <= 0) {
00342 dbgmsg("There is no parameter 0\n");
00343 }
00344 # endif
00345 result -> arg[result -> n_args++] = v + ARG_BIT;
00346 } else {
00347 p = extract_field(p);
00348 i = find_RIC_table(field_buf);
00349 # ifdef DEBUG
00350 if (i == MISSING) {
00351 dbgmsg ("Bad RIC loc: %s\n", field_buf);
00352 abort();
00353 }
00354 # endif
00355 result -> arg[result -> n_args++] = i;
00356 }
00357 skip_blanks;
00358 }
00359 }
00360 *s = p;
00361 return(result);
00362 }
00363
00364
00365
00366
00367
00368 struct RIC_instr * Ginline_cnvt(s)
00369 char *s;
00370 {
00371 char *p = s;
00372 struct RIC_instr *first = NIL;
00373 struct RIC_instr *last = NIL;
00374 struct RIC_instr *q = NIL;
00375 extern char end;
00376
00377 while (*p != '\0') {
00378 q = parse_RIC(&p);
00379 if (first == NIL) {
00380 first = last = q;
00381 } else {
00382 last -> next_instr = q;
00383 last = q;
00384 }
00385 while (*p == '\n' || *p == ';') { p++; }
00386 }
00387 last -> next_instr = NIL;
00388 if (s > &end) {
00389 free(s);
00390 }
00391 return(first);
00392 }
00393
00394
00395
00396
00397
00398
00399 void write_RIC(f, RIC_i, n, rs)
00400 FILE * f;
00401 struct RIC_instr * RIC_i;
00402 int n;
00403 int rs;
00404 {
00405 char * result;
00406
00407 putw(RIC_i -> op_code, f);
00408 if (RIC_i -> label_arg) {
00409 fputs(RIC_i -> label,f);
00410 putc('\0',f);
00411 } else {
00412 int i;
00413 int is_ldn = ((RIC_i -> op_code == LDN) || (RIC_i -> op_code == IDT));
00414 for (i = 0; i < 3; i++) {
00415 if (i < RIC_i -> n_args) {
00416 int arg = RIC_i -> arg[i];
00417
00418 if ((arg & ARG_BIT) && (!is_ldn || i != 0)) {
00419 arg &= ~ARG_BIT;
00420 arg = (n == 0? 1 - arg : arg + n - 1);
00421 } else if (arg == RS &&
00422 (!is_ldn || i != 0)) {
00423
00424 arg = rs;
00425 }
00426 ASSERT(arg < MAXLOC || is_ldn,
00427 "Bad opnd in inline code\n");
00428 putw(arg, f);
00429 } else {
00430 putw(SK, f);
00431 }
00432 }
00433 }
00434 }
00435
00436
00437
00438 void write_RIC_seq(f, RIC_seq, n, rs)
00439 FILE * f;
00440 struct RIC_instr * RIC_seq;
00441 int n;
00442 int rs;
00443 {
00444 struct RIC_instr * p = RIC_seq;
00445
00446 while (p != NIL) {
00447 write_RIC(f, p, n, rs);
00448 p = p -> next_instr;
00449 }
00450 }
00451
00452
00453 genl_RIC(f, op, label)
00454 FILE * f;
00455 int op;
00456 char * label;
00457 {
00458 putw(op, f);
00459 fputs(label, f);
00460 putc('\0', f);
00461 }
00462
00463
00464
00465 gen_RIC(f, op, arg1, arg2, arg3)
00466 FILE * f;
00467 int op;
00468 int arg1, arg2, arg3;
00469 {
00470 ASSERT((arg1 <= MAXLOC || op == LDN || op == IDT)
00471 && arg2 <= MAXLOC && arg3 <= MAXLOC,
00472 "Bad operand to gen_RIC\n");
00473 putw(op, f);
00474 putw(arg1, f);
00475 putw(arg2, f);
00476 putw(arg3, f);
00477 }
00478
00479
00480 struct RIC_instr * copy_RIC(p)
00481 struct RIC_instr * p;
00482 {
00483 if (p == RIC_nil) {
00484 return (RIC_nil);
00485 } else {
00486 struct RIC_instr * result;
00487
00488 if (!p -> label_arg) {
00489 result = (struct RIC_instr *) gc_malloc(sizeof (struct RIC_instr));
00490 *result = *p;
00491 } else {
00492 int sz = (sizeof (struct RIC_instr)) + strlen(p -> label);
00493 result = (struct RIC_instr *)gc_malloc(sz);
00494 result -> op_code = p -> op_code;
00495 result -> n_args = 0;
00496 result -> label_arg = TRUE;
00497 strcpy(result -> label, p -> label);
00498 }
00499 result -> next_instr = copy_RIC(p -> next_instr);
00500 return(result);
00501 }
00502 }
00503
00504
00505 struct RIC_instr * cat_RIC(p,q)
00506 struct RIC_instr * p;
00507 struct RIC_instr * q;
00508 {
00509 register struct RIC_instr * r;
00510
00511 if (p == RIC_nil) {
00512 return(q);
00513 } else {
00514 for (r = p; r -> next_instr != RIC_nil; r = r -> next_instr);
00515 r -> next_instr = q;
00516 }
00517 return(p);
00518 }
00519
00520
00521
00522
00523 struct RIC_instr * RIC_inst_args(p, n)
00524 struct RIC_instr * p;
00525 long n;
00526 {
00527 struct RIC_instr * r;
00528 int i;
00529 boolean is_ldn;
00530
00531
00532 int arg_no;
00533
00534 for (r = p; r != RIC_nil; r = r -> next_instr) {
00535 is_ldn = (r -> op_code == LDN || r -> op_code == IDT);
00536 for (i = 0; i < r -> n_args && !(r -> label_arg); i++) {
00537 if (!is_ldn || i >= 1) {
00538 if ((r -> arg[i]) & ARG_BIT) {
00539 arg_no = (r -> arg[i]) & ~ ARG_BIT;
00540 r -> arg[i] = arg_no + n - 1;
00541 }
00542 }
00543 }
00544 }
00545 return(p);
00546 }
00547
00548
00549
00550
00551 struct RIC_instr * RIC_inst_rs(p, n)
00552 struct RIC_instr * p;
00553 long n;
00554 {
00555 struct RIC_instr * r;
00556 int i;
00557 boolean is_ldn;
00558
00559
00560 for (r = p; r != RIC_nil; r = r -> next_instr) {
00561 is_ldn = (r -> op_code == LDN || r -> op_code == IDT);
00562 for (i = 0; i < r -> n_args && !(r -> label_arg); i++) {
00563 if (!is_ldn || i >= 1) {
00564 if ((r -> arg[i]) == RS) {
00565 r -> arg[i] = n;
00566 }
00567 }
00568 }
00569 }
00570 return(p);
00571 }
00572
00573
00574
00575 long RIC_len(p)
00576 struct RIC_instr * p;
00577 {
00578 struct RIC_instr * r;
00579 int i = 0;
00580
00581 for (r = p; r != RIC_nil; r = r -> next_instr) {
00582 i++;
00583 if (r -> op_code == HINT) {
00584 i--;
00585 if (r -> arg[1] == OPT) {
00586 i -= r -> arg[2];
00587 }
00588 }
00589 }
00590 return(i);
00591 }