00001 #include "c.h"
00002 #define I(f) b_##f
00003
00004
00005 static void I(segment)(int n) {
00006 static int cseg;
00007
00008 if (cseg != n)
00009 switch (cseg = n) {
00010 case CODE: print("code\n"); return;
00011 case DATA: print("data\n"); return;
00012 case BSS: print("bss\n"); return;
00013 case LIT: print("lit\n"); return;
00014 default: assert(0);
00015 }
00016 }
00017
00018 static void I(address)(Symbol q, Symbol p, long n) {
00019 q->x.name = stringf("%s%s%D", p->x.name, n > 0 ? "+" : "", n);
00020 }
00021
00022 static void I(defaddress)(Symbol p) {
00023 print("address %s\n", p->x.name);
00024 }
00025
00026 static void I(defconst)(int suffix, int size, Value v) {
00027 switch (suffix) {
00028 case I:
00029 if (size > sizeof (int))
00030 print("byte %d %D\n", size, v.i);
00031 else
00032 print("byte %d %d\n", size, v.i);
00033 return;
00034 case U:
00035 if (size > sizeof (unsigned))
00036 print("byte %d %U\n", size, v.u);
00037 else
00038 print("byte %d %u\n", size, v.u);
00039 return;
00040 case P: print("byte %d %U\n", size, (unsigned long)v.p); return;
00041 case F:
00042 if (size == 4) {
00043 float f = v.d;
00044 print("byte 4 %u\n", *(unsigned *)&f);
00045 } else {
00046 unsigned *p = (unsigned *)&v.d;
00047 print("byte 4 %u\n", p[swap]);
00048 print("byte 4 %u\n", p[1 - swap]);
00049 }
00050 return;
00051 }
00052 assert(0);
00053 }
00054
00055 static void I(defstring)(int len, char *str) {
00056 char *s;
00057
00058 for (s = str; s < str + len; s++)
00059 print("byte 1 %d\n", (*s)&0377);
00060 }
00061
00062 static void I(defsymbol)(Symbol p) {
00063 if (p->scope == CONSTANTS)
00064 switch (optype(ttob(p->type))) {
00065 case I: p->x.name = stringf("%D", p->u.c.v.i); break;
00066 case U: p->x.name = stringf("%U", p->u.c.v.u); break;
00067 case P: p->x.name = stringf("%U", p->u.c.v.p); break;
00068 case F:
00069 {
00070 unsigned temp;
00071
00072 *(float *)&temp = p->u.c.v.d;
00073 p->x.name = stringf("%U", temp );
00074 }
00075 break;
00076 default: assert(0);
00077 }
00078 else if (p->scope >= LOCAL && p->sclass == STATIC)
00079 p->x.name = stringf("$%d", genlabel(1));
00080 else if (p->scope == LABELS || p->generated)
00081 p->x.name = stringf("$%s", p->name);
00082 else
00083 p->x.name = p->name;
00084 }
00085
00086 static void dumptree(Node p) {
00087 switch (specific(p->op)) {
00088 case ASGN+B:
00089 assert(p->kids[0]);
00090 assert(p->kids[1]);
00091 assert(p->syms[0]);
00092 dumptree(p->kids[0]);
00093 dumptree(p->kids[1]);
00094 print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.u);
00095 return;
00096 case RET+V:
00097 assert(!p->kids[0]);
00098 assert(!p->kids[1]);
00099 print("%s\n", opname(p->op));
00100 return;
00101 }
00102 switch (generic(p->op)) {
00103 case CNST: case ADDRG: case ADDRF: case ADDRL: case LABEL:
00104 assert(!p->kids[0]);
00105 assert(!p->kids[1]);
00106 assert(p->syms[0] && p->syms[0]->x.name);
00107 print("%s %s\n", opname(p->op), p->syms[0]->x.name);
00108 return;
00109 case CVF: case CVI: case CVP: case CVU:
00110 assert(p->kids[0]);
00111 assert(!p->kids[1]);
00112 assert(p->syms[0]);
00113 dumptree(p->kids[0]);
00114 print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.i);
00115 return;
00116 case ARG: case BCOM: case NEG: case INDIR: case JUMP: case RET:
00117 assert(p->kids[0]);
00118 assert(!p->kids[1]);
00119 dumptree(p->kids[0]);
00120 print("%s\n", opname(p->op));
00121 return;
00122 case CALL:
00123 assert(p->kids[0]);
00124 assert(!p->kids[1]);
00125 assert(optype(p->op) != B);
00126 dumptree(p->kids[0]);
00127 print("%s\n", opname(p->op));
00128 if ( !p->count ) { printf("pop\n"); };
00129 return;
00130 case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH:
00131 case ADD: case SUB: case DIV: case MUL: case MOD:
00132 assert(p->kids[0]);
00133 assert(p->kids[1]);
00134 dumptree(p->kids[0]);
00135 dumptree(p->kids[1]);
00136 print("%s\n", opname(p->op));
00137 return;
00138 case EQ: case NE: case GT: case GE: case LE: case LT:
00139 assert(p->kids[0]);
00140 assert(p->kids[1]);
00141 assert(p->syms[0]);
00142 assert(p->syms[0]->x.name);
00143 dumptree(p->kids[0]);
00144 dumptree(p->kids[1]);
00145 print("%s %s\n", opname(p->op), p->syms[0]->x.name);
00146 return;
00147 }
00148 assert(0);
00149 }
00150
00151 static void I(emit)(Node p) {
00152 for (; p; p = p->link)
00153 dumptree(p);
00154 }
00155
00156 static void I(export)(Symbol p) {
00157 print("export %s\n", p->x.name);
00158 }
00159
00160 static void I(function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
00161 int i;
00162
00163 (*IR->segment)(CODE);
00164 offset = 0;
00165 for (i = 0; caller[i] && callee[i]; i++) {
00166 offset = roundup(offset, caller[i]->type->align);
00167 caller[i]->x.name = callee[i]->x.name = stringf("%d", offset);
00168 caller[i]->x.offset = callee[i]->x.offset = offset;
00169 offset += caller[i]->type->size;
00170 }
00171 maxargoffset = maxoffset = argoffset = offset = 0;
00172 gencode(caller, callee);
00173 print("proc %s %d %d\n", f->x.name, maxoffset, maxargoffset);
00174 emitcode();
00175 print("endproc %s %d %d\n", f->x.name, maxoffset, maxargoffset);
00176
00177 }
00178
00179 static void gen02(Node p) {
00180 assert(p);
00181 if (generic(p->op) == ARG) {
00182 assert(p->syms[0]);
00183 argoffset += (p->syms[0]->u.c.v.i < 4 ? 4 : p->syms[0]->u.c.v.i);
00184 } else if (generic(p->op) == CALL) {
00185 maxargoffset = (argoffset > maxargoffset ? argoffset : maxargoffset);
00186 argoffset = 0;
00187 }
00188 }
00189
00190 static void gen01(Node p) {
00191 if (p) {
00192 gen01(p->kids[0]);
00193 gen01(p->kids[1]);
00194 gen02(p);
00195 }
00196 }
00197
00198 static Node I(gen)(Node p) {
00199 Node q;
00200
00201 assert(p);
00202 for (q = p; q; q = q->link)
00203 gen01(q);
00204 return p;
00205 }
00206
00207 static void I(global)(Symbol p) {
00208 print("align %d\n", p->type->align > 4 ? 4 : p->type->align);
00209 print("LABELV %s\n", p->x.name);
00210 }
00211
00212 static void I(import)(Symbol p) {
00213 print("import %s\n", p->x.name);
00214 }
00215
00216 static void I(local)(Symbol p) {
00217 offset = roundup(offset, p->type->align);
00218 p->x.name = stringf("%d", offset);
00219 p->x.offset = offset;
00220 offset += p->type->size;
00221 }
00222
00223 static void I(progbeg)(int argc, char *argv[]) {}
00224
00225 static void I(progend)(void) {}
00226
00227 static void I(space)(int n) {
00228 print("skip %d\n", n);
00229 }
00230
00231
00232
00233
00234 static char *sourceFile;
00235 static char *sourcePtr;
00236 static int sourceLine;
00237
00238 static int filelength( FILE *f ) {
00239 int pos;
00240 int end;
00241
00242 pos = ftell (f);
00243 fseek (f, 0, SEEK_END);
00244 end = ftell (f);
00245 fseek (f, pos, SEEK_SET);
00246
00247 return end;
00248 }
00249
00250 static void LoadSourceFile( const char *filename ) {
00251 FILE *f;
00252 int length;
00253
00254 f = fopen( filename, "r" );
00255 if ( !f ) {
00256 print( ";couldn't open %s\n", filename );
00257 sourceFile = NULL;
00258 return;
00259 }
00260 length = filelength( f );
00261 sourceFile = malloc( length + 1 );
00262 if ( sourceFile ) {
00263 fread( sourceFile, length, 1, f );
00264 sourceFile[length] = 0;
00265 }
00266
00267 fclose( f );
00268 sourceLine = 1;
00269 sourcePtr = sourceFile;
00270 }
00271
00272 static void PrintToSourceLine( int line ) {
00273 int c;
00274
00275 if ( !sourceFile ) {
00276 return;
00277 }
00278 while ( sourceLine <= line ) {
00279 int i;
00280
00281 for ( i = 0 ; sourcePtr[i] && sourcePtr[i] != '\n' ; i++ ) {
00282 }
00283 c = sourcePtr[i];
00284 if ( c == '\n' ) {
00285 sourcePtr[i] = 0;
00286 }
00287 print( ";%d:%s\n", sourceLine, sourcePtr );
00288 if ( c == 0 ) {
00289 sourcePtr += i;
00290 } else {
00291 sourcePtr += i+1;
00292 }
00293 sourceLine++;
00294 }
00295 }
00296
00297 static void I(stabline)(Coordinate *cp) {
00298 static char *prevfile;
00299 static int prevline;
00300
00301 if (cp->file && (prevfile == NULL || strcmp(prevfile, cp->file) != 0)) {
00302 print("file \"%s\"\n", prevfile = cp->file);
00303 prevline = 0;
00304 if ( sourceFile ) {
00305 free( sourceFile );
00306 sourceFile = NULL;
00307 }
00308
00309 LoadSourceFile( cp->file );
00310 }
00311 if (cp->y != prevline) {
00312 print("line %d\n", prevline = cp->y);
00313 PrintToSourceLine( cp->y );
00314 }
00315 }
00316
00317
00318
00319 #define b_blockbeg blockbeg
00320 #define b_blockend blockend
00321
00322 Interface bytecodeIR = {
00323 1, 1, 0,
00324 2, 2, 0,
00325 4, 4, 0,
00326 4, 4, 0,
00327 4, 4, 0,
00328 4, 4, 0,
00329 4, 4, 0,
00330 4, 4, 0,
00331 4, 4, 0,
00332 0, 4, 0,
00333 0,
00334 0,
00335 0,
00336 0,
00337 1,
00338 0,
00339 0,
00340 I(address),
00341 I(blockbeg),
00342 I(blockend),
00343 I(defaddress),
00344 I(defconst),
00345 I(defstring),
00346 I(defsymbol),
00347 I(emit),
00348 I(export),
00349 I(function),
00350 I(gen),
00351 I(global),
00352 I(import),
00353 I(local),
00354 I(progbeg),
00355 I(progend),
00356 I(segment),
00357 I(space),
00358 0,
00359 0,
00360 0,
00361 0,
00362 I(stabline),
00363 0,
00364 0,
00365 };