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
00030
00031 # include <stdio.h>
00032 # include <strings.h>
00033 # include "codegen.h"
00034 # include "op_codes.h"
00035
00036 # define TRUE 1
00037 # define FALSE 0
00038 # define MAX_TEMP_LAB 20
00039
00040 int last_type;
00041 # define REF 0
00042 # define DEF 1
00043
00044 int last_num;
00045
00046 int last_dir;
00047 # define FWD 0
00048 # define BCK 1
00049
00050
00051
00052
00053
00054 struct instr {
00055 int opc, arg[3];
00056 char *label;
00057 struct instr *next;
00058 };
00059
00060 struct instr *instr_list = (struct instr *) 0;
00061
00062 struct instr *tail_il = (struct instr *) 0;
00063
00064
00065
00066
00067
00068 struct fwd_ref {
00069 struct instr *inst;
00070 struct fwd_ref *next;
00071 };
00072
00073 struct fwd_ref *fwd_refs[MAX_TEMP_LAB+1] =
00074 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00075
00076
00077 extern char *op_code_table[];
00078
00079 char label_buf[MAXLABELSZ+1];
00080 char save_label[MAXLABELSZ+1];
00081
00082 char * crud[20];
00083
00084
00085 char * cur_name[MAX_TEMP_LAB+1] =
00086 { "..............", "..............", "..............",
00087 "..............", "..............", "..............",
00088 "..............", "..............", "..............",
00089 "..............", "..............", "..............",
00090 "..............", "..............", "..............",
00091 "..............", "..............", "..............",
00092 "..............", ".............." };
00093
00094 int num_fwd_refs = 0;
00095 int lbl_num = 0;
00096 int read_ahead = FALSE;
00097 int saved_opc;
00098
00099 FILE *in_file, *out_file;
00100
00101
00102
00103 #ifdef DEBUG
00104 # define dbg_msg(s) printf(s); fflush(stdout)
00105 # define dbg_msg2(s,x) printf(s,x); fflush(stdout)
00106 # define dbg_msg3(s,x,y) printf(s,x,y); fflush(stdout)
00107 # define dbg_msg4(s,x,y,z) printf(s,x,y,z); fflush(stdout)
00108 #else
00109 # define dbg_msg(x)
00110 # define dbg_msg2(s,x)
00111 # define dbg_msg3(s,x,y)
00112 # define dbg_msg4(s,x,y,z)
00113 #endif
00114
00115
00116
00117
00118 main(argc, argv)
00119 int argc;
00120 char ** argv;
00121 {
00122 int opc,
00123 arg[3];
00124 char * op_mnem;
00125 struct instr *newone;
00126 struct fwd_ref *cur_ref;
00127
00128 int last_was_def= FALSE,
00129 last_was_lba= FALSE;
00130 int input_index = 1,
00131 i;
00132 char *temp;
00133
00134
00135 if (argc == 1) {
00136 in_file = stdin;
00137 out_file = stdout;
00138 } else if (argc <= 3) {
00139 if (argv[1][0] == '-') {
00140 int res = 0;
00141
00142 for (i = 1; i < strlen(argv[1])-1; i++) {
00143 if (argv[1][i] < '0' || argv[1][i] > '9') {
00144 fprintf(stderr,"invalid label num argument\n");
00145 usage(argv[0]);
00146 } else {
00147 res = (10 * res) + (argv[1][i] - '0');
00148 }
00149 }
00150 lbl_num = res;
00151 }
00152 in_file = fopen(argv[1], "r");
00153 out_file =
00154 (argc == 2) ? stdout : fopen(argv[2], "w");
00155
00156 if (in_file == NULL || out_file == NULL) {
00157 fprintf(stderr, "Can't open %s\n", argv[1]);
00158 usage(argv[0]);
00159 }
00160 } else {
00161 fprintf(stderr, "Usage: %s [%s]\n", argv[0], argv[1]);
00162 }
00163
00164
00165 while (!feof(in_file)) {
00166 int i;
00167
00168 if (read_ahead) {
00169 opc = saved_opc;
00170 read_ahead = FALSE;
00171 } else {
00172 opc = getw(in_file);
00173 }
00174 if (feof(in_file)) {
00175
00176 exit(0);
00177 }
00178
00179
00180 if (opc >= 0 && opc <= N_OP_CODES) op_mnem = op_code_table[opc];
00181
00182
00183 *label_buf = '\0';
00184 for (i = 0; i < 3; i++) arg[i] = 0;
00185
00186
00187 if (last_was_lba) {
00188 char *lba_lbl;
00189
00190 if (last_was_def) {
00191 lba_lbl = cur_name[last_num];
00192 } else {
00193 lba_lbl = save_label;
00194 }
00195 if (num_fwd_refs == 0) {
00196 put_lbl_op(LBA,lba_lbl);
00197 dbg_msg2("LBA %s\n",lba_lbl);
00198 } else {
00199 newone = (struct instr *) malloc(sizeof(struct instr));
00200 save_it(newone,LBA,arg,lba_lbl);
00201 }
00202 }
00203
00204
00205 last_was_lba = FALSE;
00206 if (opc <= MAX_LABEL_OP) {
00207 char *p = label_buf;
00208 int c;
00209 int i = 0;
00210
00211 while ((c = getc(in_file)) != '\0' && c != EOF) {
00212 *p++ = c;
00213 if (++i >= MAXLABELSZ) {
00214 fprintf(stderr, "Label too long\n");
00215 p = label_buf;
00216 }
00217 }
00218 *p = '\0';
00219
00220 if (opc == LBA) {
00221 last_was_lba = TRUE;
00222 dbg_msg("opc == LBA\n");
00223 dbg_msg2("label_buf = %s\n",label_buf);
00224 strcpy(save_label,label_buf);
00225 }
00226
00227 if (normal_label(opc,label_buf)) {
00228 if (opc != LBA) {
00229 if (num_fwd_refs == 0) {
00230 put_lbl_op(opc,label_buf);
00231 dbg_msg3("%s %s\t(normal)\n",op_mnem,label_buf);
00232 } else {
00233 newone = (struct instr *) malloc(sizeof(struct instr));
00234 save_it(newone,opc,arg,label_buf);
00235 }
00236 } else {
00237 last_was_def = FALSE;
00238 }
00239 } else {
00240 if (last_type == DEF) {
00241 last_was_def = (opc == LBA);
00242
00243 dbg_msg3("assigned L_X%dX_ to %d\n",lbl_num,last_num);
00244 sprintf(crud,"L_X%dX_",lbl_num++);
00245 strcpy(cur_name[last_num],crud);
00246 cur_ref = fwd_refs[last_num];
00247
00248
00249 if (opc != LBA) {
00250 if (num_fwd_refs == 0) {
00251 put_lbl_op(opc,cur_name[last_num]);
00252 } else {
00253 newone =
00254 (struct instr *) malloc(sizeof(struct instr));
00255 save_it(newone,opc,arg,cur_name[last_num]);
00256 }
00257 }
00258 dbg_msg3("resolving fwd refs %d to %s\n",
00259 last_num,cur_name[last_num]);
00260
00261
00262 while (cur_ref != (struct fwd_ref *) NULL) {
00263 strcpy( (cur_ref->inst)->label, cur_name[last_num]);
00264 temp = (char *) cur_ref;
00265 cur_ref = cur_ref->next;
00266 free(temp);
00267 num_fwd_refs--;
00268 }
00269 fwd_refs[last_num] = (struct fwd_ref *) NULL;
00270
00271 if (num_fwd_refs == 0) {
00272 struct instr *cur = instr_list;
00273 while (cur != (struct instr *) NULL) {
00274 if (cur->opc < MAX_LABEL_OP) {
00275 put_lbl_op(cur->opc,cur->label);
00276 dbg_msg3("%s %s\t(saved)\n",
00277 op_code_table[cur->opc],cur->label);
00278 } else if (cur->opc < N_OP_CODES) {
00279 put_reg_op(cur->opc,cur->arg);
00280 dbg_msg2("%s ",op_code_table[cur->opc]);
00281 dbg_msg4("%d %d %d\t(saved)\n",
00282 cur->arg[0],cur->arg[1],cur->arg[2]);
00283 } else {
00284 fprintf(stderr,
00285 "Bad op code in instr_list = %d\n",
00286 cur->opc);
00287 }
00288 instr_list = tail_il = (struct instr *) NULL;
00289 temp = (char *) cur;
00290 cur = cur->next;
00291 free(temp);
00292 }
00293 } else {
00294 dbg_msg2("now num_fwd_refs = %d\n",num_fwd_refs);
00295 }
00296 } else if (opc != LBA) {
00297 if (last_dir == FWD) {
00298 newone =
00299 (struct instr *) malloc(sizeof(struct instr));
00300 i = (int) malloc(sizeof(struct fwd_ref));
00301 cur_ref = (struct fwd_ref *) i;
00302
00303 cur_ref->inst = newone;
00304 cur_ref->next = fwd_refs[last_num];
00305 fwd_refs[last_num] = cur_ref;
00306 save_it(newone,opc,arg,label_buf);
00307 num_fwd_refs++;
00308 } else {
00309 dbg_msg3("resolved back ref to %d = %s\n",last_num,
00310 cur_name[last_num]);
00311 strcpy(label_buf, cur_name[last_num]);
00312 if (num_fwd_refs == 0) {
00313 put_lbl_op(opc,label_buf);
00314 dbg_msg3("%s %s\t(back ref)\n",op_mnem,label_buf);
00315 } else {
00316 newone =
00317 (struct instr *) malloc(sizeof(struct instr));
00318 save_it(newone,opc,arg,label_buf);
00319 }
00320 }
00321 }
00322 }
00323
00324
00325 } else {
00326 for ( i = 0; i < 3; i++ ) {
00327 arg[i] = getw(in_file);
00328 }
00329 if (num_fwd_refs == 0) {
00330 put_reg_op(opc,arg);
00331 dbg_msg2("%s ",op_mnem);
00332 dbg_msg4("%d %d %d\t(plain)\n",arg[0],arg[1],arg[2]);
00333 } else {
00334 newone = (struct instr *) malloc(sizeof(struct instr));
00335 save_it(newone,opc,arg,label_buf);
00336 }
00337 }
00338
00339 }
00340 }
00341
00342
00343
00344
00345 save_it(newone,opc,arg,label_buf)
00346 struct instr *newone;
00347 int opc,arg[3];
00348 char *label_buf;
00349 {
00350 struct instr *temp;
00351
00352
00353 if (newone == (struct instr *) NULL) {
00354 fprintf(stderr,"Internal: (nil) newone passed to save_it\n");
00355 fflush(stderr);
00356 exit(1);
00357 } else {
00358 newone->next = (struct instr *) NULL;
00359 newone->opc = opc;
00360 newone->arg[0] = arg[0];
00361 newone->arg[1] = arg[1];
00362 newone->arg[2] = arg[2];
00363 newone->label = (char *) malloc(MAXLABELSZ+1);
00364 strcpy(newone->label,label_buf);
00365
00366 if (tail_il != (struct instr *) NULL) tail_il->next = newone;
00367 tail_il = newone;
00368 if (instr_list == (struct instr *) NULL) instr_list = tail_il;
00369 }
00370
00371 dbg_msg("il = ");
00372 for(temp = instr_list; temp != NULL; temp = temp->next) {
00373 dbg_msg2("(%s",op_code_table[temp->opc]);
00374 dbg_msg4(" %d %d %d ",temp->arg[0],temp->arg[1],temp->arg[2]);
00375 dbg_msg2("%s), ",temp->label);
00376 }
00377 dbg_msg("\n");
00378 }
00379
00380
00381
00382
00383
00384 int next_opc() {
00385 if (read_ahead) {
00386 fprintf(stderr,"tried to read ahead when read_ahead already set!\n");
00387 exit(1);
00388 }
00389 read_ahead = TRUE;
00390 saved_opc = getw(in_file);
00391 return(saved_opc);
00392 }
00393
00394
00395
00396
00397
00398 int normal_label(opc,p)
00399 int opc;
00400 char *p;
00401 {
00402 char *s;
00403
00404
00405 if (opc == LBA && next_opc() == LDS) return(TRUE);
00406
00407 last_num = 0;
00408 for (s = p; *s != '\0'; s++) {
00409 if (*s >= '0' && *s <= '9') {
00410 last_num = 10 * last_num + *s - '0';
00411 } else if (s != p && (*s == 'f' || *s == 'b') && (*(s+1) == '\0')) {
00412 last_type = REF;
00413 last_dir = (*s == 'f') ? FWD : BCK;
00414 dbg_msg3("found a %s ref to %d\n",
00415 (last_dir==FWD)?"fwd":"back",last_num);
00416 return(FALSE);
00417 } else {
00418 return(TRUE);
00419 }
00420 }
00421 if (opc == LBA || opc == LBL) {
00422 last_type = DEF;
00423 dbg_msg2("found a def of %d\n",last_num);
00424 dbg_msg3("%s %s\n",op_code_table[opc],p);
00425 return(FALSE);
00426 } else {
00427 return(TRUE);
00428 }
00429 }
00430
00431
00432
00433
00434 put_reg_op(opc,arg)
00435 int opc, arg[];
00436 {
00437 putw(opc,out_file);
00438 putw(arg[0],out_file);
00439 putw(arg[1],out_file);
00440 putw(arg[2],out_file);
00441 }
00442
00443
00444
00445
00446
00447
00448 put_lbl_op(opc,label)
00449 int opc;
00450 char *label;
00451 {
00452 char *fixit();
00453
00454 putw(opc,out_file);
00455 fputs(fixit(label),out_file);
00456 putc('\0',out_file);
00457 }
00458
00459
00460
00461 char *fixit(str)
00462 char *str;
00463 {
00464 char *p;
00465 char *q = (char *) malloc(strlen(str)+1);
00466 int state = 0, offset=0;
00467
00468 for (p = str; *p != '\0'; p++, offset++) {
00469 if (state == 0) {
00470 if (*p == '_') state = 1;
00471 *(q+offset) = *p;
00472 } else {
00473 if (*p == '.') {
00474 *(q+offset) = '_';
00475 } else
00476 *(q+offset) = *p;
00477 if (*p != '_') state = 0;
00478 }
00479 }
00480 *(q+offset) = '\0';
00481
00482 return(q);
00483 }
00484
00485
00486 usage(name)
00487 char *name;
00488 {
00489 fprintf(stderr,"usage: %s [-nnn] infile [outfile]\n",name);
00490 exit(1);
00491 }