Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

bytecode.c

Go to the documentation of this file.
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             {   // JDC: added this to get inline floats
00070                 unsigned temp;
00071 
00072                 *(float *)&temp = p->u.c.v.d;
00073                 p->x.name = stringf("%U", temp );
00074             }
00075             break;// JDC: added this
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"); };  // JDC
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 // JDC: hacked up to get interleaved source lines in asm code
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; // end of file
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         // load the new source file
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,    /* char */
00324     2, 2, 0,    /* short */
00325     4, 4, 0,    /* int */
00326     4, 4, 0,    /* long */
00327     4, 4, 0,    /* long long */
00328     4, 4, 0,    /* float */             // JDC: use inline floats
00329     4, 4, 0,    /* double */            // JDC: don't ever emit 8 byte double code
00330     4, 4, 0,    /* long double */       // JDC: don't ever emit 8 byte double code
00331     4, 4, 0,    /* T* */
00332     0, 4, 0,    /* struct */
00333     0,      /* little_endian */
00334     0,      /* mulops_calls */
00335     0,      /* wants_callb */
00336     0,      /* wants_argb */
00337     1,      /* left_to_right */
00338     0,      /* wants_dag */
00339     0,      /* unsigned_char */
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,      /* I(stabblock) */
00359     0,      /* I(stabend) */
00360     0,      /* I(stabfend) */
00361     0,      /* I(stabinit) */
00362     I(stabline),
00363     0,      /* I(stabsym) */
00364     0,      /* I(stabtype) */
00365 };

Generated on Thu Aug 25 12:38:12 2005 for Quake III Arena by  doxygen 1.3.9.1