|
|
1.1 ! root 1: /* C compiler: VAX code generator */ ! 2: ! 3: #include "c.h" ! 4: ! 5: dclproto(static void address,(Symbol, Symbol, int)); ! 6: dclproto(static void defaddress,(Symbol)); ! 7: dclproto(static void defconst,(int, Value)); ! 8: dclproto(static void defstring,(int, char *)); ! 9: dclproto(static void defsymbol,(Symbol)); ! 10: dclproto(static void doarg,(Node)); ! 11: dclproto(static void emitspecial,(Node)); ! 12: dclproto(static void function,(Symbol, Symbol [], Symbol [], int)); ! 13: dclproto(static void global,(Symbol)); ! 14: dclproto(static void import,(Symbol)); ! 15: dclproto(static void local,(Symbol)); ! 16: dclproto(static void progbeg,(int, char **)); ! 17: dclproto(static void segment,(int)); ! 18: dclproto(static void space,(int)); ! 19: ! 20: #ifdef vax ! 21: #ifdef V9 ! 22: dclproto(static void stabblock,(int, int, Symbol*)); ! 23: dclproto(static void stabend,(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *)); ! 24: dclproto(static void stabfend,(Symbol, int)); ! 25: dclproto(static void stabinit,(char *, int, char *[])); ! 26: dclproto(static void stabline,(Coordinate *)); ! 27: dclproto(static void stabsym,(Symbol)); ! 28: dclproto(static void stabtype,(Symbol)); ! 29: #else ! 30: #include <stab.h> ! 31: #include "stabbsd.c" ! 32: #define stabend 0 ! 33: #endif ! 34: #endif ! 35: ! 36: dclproto(static void initgen,(void)); ! 37: dclproto(static void final,(Node)); ! 38: ! 39: #ifdef GEN4 ! 40: dclproto(static unsigned emit2,(Node,Node[],short[])); ! 41: dclproto(static void target,(Node)); ! 42: #endif ! 43: ! 44: Interface vaxInterface = { ! 45: "vax", ! 46: 1, 1, 0, /* char */ ! 47: 2, 2, 0, /* short */ ! 48: 4, 4, 0, /* int */ ! 49: 4, 4, 1, /* float */ ! 50: 8, 4, 1, /* double */ ! 51: 4, 4, 0, /* T * */ ! 52: 0, 1, 0, /* struct */ ! 53: 0, /* left_to_right */ ! 54: 1, /* little_endian */ ! 55: 0, /* jump_on_return */ ! 56: 0, /* mulops_are_calls */ ! 57: 1, /* compl_band */ ! 58: 0, /* no_argb */ ! 59: NODAG, /* no_dag */ ! 60: address, ! 61: blockbeg, ! 62: blockend, ! 63: defaddress, ! 64: defconst, ! 65: defstring, ! 66: defsymbol, ! 67: 0, ! 68: export, ! 69: function, ! 70: gen, ! 71: global, ! 72: import, ! 73: local, ! 74: progbeg, ! 75: progend, ! 76: segment, ! 77: space, ! 78: #ifdef vax ! 79: stabblock, stabend, stabfend, stabinit, stabline, stabsym, stabtype, ! 80: #else ! 81: 0, 0, 0, 0, 0, 0, 0, ! 82: #endif ! 83: {".globl %s\n", 0, 0, {".text", ".data", ".data", ".text 1", ".data 2"}, ! 84: doarg, docall, 0, 0, 0, ! 85: final, 0, emitspecial, ! 86: #ifdef GEN4 ! 87: vax_kids, vax_ntname, vax_nts, vax_rule, vax_state, vax_string, vax_cost, ! 88: rules, emit2, target ! 89: #endif ! 90: } ! 91: }; ! 92: ! 93: static Symbol d0, f0, r0, r1; ! 94: ! 95: /* address - initialize q for addressing expression p+n */ ! 96: static void address(q, p, n) Symbol q, p; { ! 97: q->x.offset = p->x.offset + n; ! 98: if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) ! 99: q->x.name = stringf("%s%s%d", p->x.name, n >= 0 ? "+" : "", n); ! 100: else ! 101: q->x.name = stringd(q->x.offset); ! 102: } ! 103: ! 104: static void defaddress(p) Symbol p; { ! 105: print(".long %s\n", p->x.name); ! 106: } ! 107: ! 108: /* defconst - define a constant */ ! 109: static void defconst(ty, v) Value v; { ! 110: switch (ty) { ! 111: case C: print(".byte %d\n", v.uc); break; ! 112: case S: print(".word %d\n", v.ss); break; ! 113: case I: print(".long %d\n", v.i ); break; ! 114: case U: print(".long 0x%x\n", v.u ); break; ! 115: case P: print(".long 0x%x\n", v.p ); break; ! 116: case F: ! 117: if (v.f == 0.0) ! 118: print(".long 0x0\n"); ! 119: else { ! 120: struct real r; ! 121: r = decode(F, v.f); ! 122: r.exp = (r.exp + 129)&0xff; ! 123: r.msb &= ~0x1ff; ! 124: print(".long 0x%x\n", (r.msb<<7) | (r.sign<<15) | (r.exp<<7) | (r.msb>>25)); ! 125: } ! 126: break; ! 127: case D: ! 128: if (v.d == 0.0) ! 129: print(".long 0x0,0x0\n"); ! 130: else { ! 131: unsigned u; ! 132: struct real r; ! 133: r = decode(D, v.d); ! 134: r.exp = (r.exp + 129)&0xff; ! 135: u = r.msb&~0x1ff; ! 136: print(".long 0x%x,", (u<<7) | (r.sign<<15) | (r.exp<<7) | (u>>25)); ! 137: u = (r.msb<<23) | (r.lsb>>9); ! 138: print("0x%x\n", (u<<16) | (u>>16)); ! 139: } ! 140: break; ! 141: default: ! 142: assert(0); ! 143: } ! 144: } ! 145: ! 146: static void defstring(n, s) char *s; { ! 147: genascii(".ascii", ".byte", n, s); ! 148: } ! 149: ! 150: /* defsymbol - compute and store p's back-end name */ ! 151: static void defsymbol(p) Symbol p; { ! 152: if (p->scope == CONSTANTS) ! 153: p->x.name = p->name; ! 154: else if (p->scope >= LOCAL && p->sclass == STATIC) ! 155: p->x.name = stringf("L%d", genlabel(1)); ! 156: else if (p->generated) ! 157: p->x.name = stringf("L%s", p->name); ! 158: else ! 159: p->x.name = stringf("_%s", p->name); ! 160: } ! 161: ! 162: /* doarg - assign offset for next ARG node */ ! 163: static void doarg(p) Node p; { ! 164: assert(p); ! 165: assert(p->syms[0]); ! 166: assert(p->syms[1]); ! 167: p->syms[2] = intconst(mkactual(p->syms[1]->u.c.v.i, p->syms[0]->u.c.v.i, 4)); ! 168: } ! 169: ! 170: static void emitspecial(p) Node p; {} ! 171: ! 172: /* function - generate code for a function */ ! 173: static void function(p, caller, callee, n) Symbol p, callee[], caller[]; { ! 174: int i; ! 175: ! 176: initfunc(n, 4, 0); ! 177: for (i = 0; callee[i]; i++) { ! 178: assert(caller[i]); ! 179: callee[i]->x.offset = caller[i]->x.offset = offset; ! 180: callee[i]->x.name = caller[i]->x.name = stringd(offset); ! 181: offset = roundup(offset + caller[i]->type->size, 4); ! 182: getregvar(callee[i], rmap[ttob(callee[i]->type)]); ! 183: } ! 184: assert(caller[i] == 0); ! 185: offset = 0; ! 186: gencode(caller, callee); ! 187: mvregvars(); ! 188: savemask[0] = usedmask[0]&eemask[0]; ! 189: savebase[0] = 20; ! 190: print(".align 1\n%s:.word 0x%x\n", p->x.name, savemask[0]); ! 191: if (maxoffset > 0) ! 192: print("subl2 $%d,sp\n", maxoffset); ! 193: if (isstruct(freturn(p->type))) ! 194: print("movl r1,-4(fp)\n"); ! 195: if (pflag) { ! 196: int lab = genlabel(1); ! 197: print("movab L%d,r0\njsb mcount\n", lab); ! 198: print(".data\n.align 2\nL%d: .long 0\n.text\n", lab); ! 199: } ! 200: emitcode(); ! 201: if (glevel > 1) ! 202: print("ret\n"); ! 203: } ! 204: ! 205: /* global - global id */ ! 206: static void global(p) Symbol p; { ! 207: assert(p->u.seg); ! 208: if (p->u.seg == BSS && (p->sclass == STATIC || Aflag >= 2)) ! 209: print(".lcomm %s,", p->x.name); ! 210: else if (p->u.seg == BSS) ! 211: print(".comm %s,", p->x.name); ! 212: else { ! 213: if (p->type->align > 1) ! 214: print(".align %c; ", "..1.2...3"[p->type->align]); ! 215: print("%s:", p->x.name); ! 216: } ! 217: } ! 218: ! 219: static void import(p) Symbol p; {} ! 220: ! 221: /* local - local */ ! 222: static void local(p) Symbol p; { ! 223: if (getregvar(p, rmap[ttob(p->type)]) == 0) ! 224: p->x.name = stringd(mkauto(p, 4)); ! 225: } ! 226: ! 227: /* progbeg - beginning of program */ ! 228: static void progbeg(argc, argv) char *argv[]; { ! 229: nregsets = 1; ! 230: eemask[0] = 0xfc0; ! 231: tmask[0] = 0x03f; ! 232: vmask[0] = 0xfc0; ! 233: parseflags(argc, argv); ! 234: initgen(); ! 235: d0 = mkregs("%d", 0, 0, 2, 3, 0, D, 0); ! 236: r0 = mkregs("%d", 0, 0, 1, 1, 0, I, 0); ! 237: f0 = mkregs("%d", 0, 0, 1, 1, 0, F, 0); ! 238: r1 = mkregs("%d", 1, 1, 1, 1, 0, I, 0); ! 239: rmap[D] = mkregs("%d", 0, 10, 2, 3, 0, D, 0); ! 240: rmap[F] = mkregs("%d", 0, 11, 1, 1, 0, F, 0); ! 241: rmap[I] = mkregs("%d", 0, 11, 1, 1, 0, I, 0); ! 242: rmap[C] = rmap[S] = rmap[P] = rmap[U] = rmap[I]; ! 243: } ! 244: ! 245: static void segment(n) { ! 246: setseg(n); ! 247: } ! 248: ! 249: static void space(n) { ! 250: spacen(n, ".space"); ! 251: } ! 252: ! 253: #ifndef V9 ! 254: #include <errno.h> ! 255: #ifndef errno ! 256: extern int errno; ! 257: #endif ! 258: ! 259: /* strtol - interpret str as a base b number; if ptr!=0, *ptr gets updated str */ ! 260: long strtol(str, ptr, b) char *str, **ptr; { ! 261: long n = 0; ! 262: char *s, sign = '+'; ! 263: int d, overflow = 0; ! 264: ! 265: if (ptr) ! 266: *ptr = str; ! 267: if (b < 0 || b == 1 || b > 36) ! 268: return 0; ! 269: while (*str==' '||*str=='\f'||*str=='\n'||*str=='\r'||*str=='\t'||*str=='\v') ! 270: str++; ! 271: if (*str == '-' || *str == '+') ! 272: sign = *str++; ! 273: if (b == 0) ! 274: if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { ! 275: b = 16; ! 276: str += 2; ! 277: } else if (str[0] == '0') ! 278: b = 8; ! 279: else ! 280: b = 10; ! 281: for (s = str; *str; str++) { ! 282: if (*str >= '0' && *str <= '9') ! 283: d = *str - '0'; ! 284: else if (*str >= 'a' && *str <= 'z' || *str >= 'A' && *str <= 'Z') ! 285: d = (*str&~040) - 'A' + 10; ! 286: else ! 287: break; ! 288: if (d >= b) ! 289: break; ! 290: if (n < (LONG_MIN + d)/b) ! 291: overflow = 1; ! 292: n = b*n - d; ! 293: } ! 294: if (s == str) ! 295: return 0; ! 296: if (ptr) ! 297: *ptr = str; ! 298: if (overflow || (sign == '+' && n == LONG_MIN)) { ! 299: errno = ERANGE; ! 300: return sign == '+' ? LONG_MAX : LONG_MIN; ! 301: } ! 302: return sign == '+' ? -n : n; ! 303: } ! 304: #endif ! 305: ! 306: #ifdef vax ! 307: #ifdef V9 ! 308: #include <stab.h> ! 309: static char *currentfile; /* current file name */ ! 310: ! 311: dclproto(static void emittype,(int desc, int s, Type ty, char *str)); ! 312: dclproto(extern long time,(long *)); ! 313: ! 314: /* emittype - emit p's type */ ! 315: static void emittype(desc, s, ty, str) Type ty; char *str; { ! 316: ty = unqual(ty); ! 317: switch (ty->op) { ! 318: case CHAR: desc |= (ty == unsignedchar ? 12 : 2); break; ! 319: case SHORT: desc |= (ty == unsignedshort ? 13 : 3); break; ! 320: case INT: desc |= 4; break; ! 321: case UNSIGNED: desc |= 14; break; ! 322: case FLOAT: desc |= 6; break; ! 323: case DOUBLE: desc |= 7; break; ! 324: case STRUCT: case UNION: case ENUM: ! 325: if (ty->op == STRUCT) ! 326: desc |= 8; ! 327: else if (ty->op == UNION) ! 328: desc |= 9; ! 329: else ! 330: desc |= 10; ! 331: print("0x%x,%s\n", desc, str); ! 332: if (glevel > 1) ! 333: if (*ty->u.sym->name >= '0' && *ty->u.sym->name <= '9') ! 334: print(".stabs \"%s$%d.%s\",0x%x,0,0,0\n", ty->u.sym->src.file, ! 335: ty->u.sym->src.y, ty->u.sym->name, N_TYID); ! 336: else ! 337: print(".stabs \"%s\",0x%x,0,0,0\n", ty->u.sym->name, N_TYID); ! 338: return; ! 339: case ARRAY: ! 340: emittype(desc | (3<<s), s + 2, ty->type, str); ! 341: if (glevel > 1) ! 342: print(".stabn 0x%x,0,0,%d\n", N_DIM, ty->size/ty->type->size); ! 343: return; ! 344: case POINTER: ! 345: emittype(desc | (1<<s), s + 2, ty->type, str); ! 346: return; ! 347: case FUNCTION: ! 348: emittype(desc | (2<<s), s + 2, ty->type, str); ! 349: return; ! 350: case VOID: desc |= 16; break; ! 351: default: break; ! 352: } ! 353: print("0x%x,%s\n", desc, str); ! 354: } ! 355: ! 356: /* stabblock - output a stab entry for '{' or '}' at level lev */ ! 357: static void stabblock(brace, lev, p) Symbol *p; { ! 358: if (brace == '}') ! 359: while (*p) ! 360: stabsym(*p++); ! 361: print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev); ! 362: } ! 363: ! 364: /* stabend - finalize stab output */ ! 365: static void stabend(cp, p, cpp, sp, syms) Coordinate *cp; Symbol p, *sp, *syms; Coordinate **cpp; { ! 366: if (glevel && cp->file && *cp->file) { ! 367: segment(CODE); ! 368: print("Lend:.stabs \"%s\",0x%x,0,%d,Lend\n", cp->file, N_ESO, cp->y); ! 369: } ! 370: } ! 371: ! 372: /* stabfend - end of function p */ ! 373: static void stabfend(p, line) Symbol p; { ! 374: int lab; ! 375: ! 376: if (glevel <= 1) ! 377: return; ! 378: lab = genlabel(1); ! 379: print(".stabn 0x%x,0,%d,L%d\n", N_RFUN, line, p->u.f.label); ! 380: print("L%d:.stabs \"%s\",0x%x,0,%d,L%d\n", lab, ! 381: p->name, N_EFUN, line, lab); ! 382: } ! 383: ! 384: /* stabinit - initialize stab output */ ! 385: static void stabinit(file, argc, argv) char *file, *argv[]; { ! 386: if (file && *file) { ! 387: segment(CODE); ! 388: print("Ltext:.stabs \"%s\",0x%x,0,0,Ltext\n", file, N_SO); ! 389: print(".stabs \"rcc\",0x%x,0,17665,%d\n", N_VER, time(0)); ! 390: currentfile = file; ! 391: } ! 392: } ! 393: ! 394: /* stabline - emit stab entry for source coordinate *cp */ ! 395: static void stabline(cp) Coordinate *cp; { ! 396: if (glevel <= 1) ! 397: return; ! 398: if (cp->file && cp->file != currentfile) { ! 399: int lab = genlabel(1); ! 400: print("L%d: .stabs \"%s\",0x%x,0,%d,L%d\n", lab, ! 401: cp->file, N_SOL, line, lab); ! 402: currentfile = cp->file; ! 403: } ! 404: print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y); ! 405: } ! 406: ! 407: /* stabsym - output a stab entry for symbol p */ ! 408: static void stabsym(p) Symbol p; { ! 409: char buf[100], *adr = p->x.name; ! 410: ! 411: if (p->generated || p->computed) ! 412: return; ! 413: print(".stabs \"%s\",", p->name); ! 414: if (isfunc(p->type)) { ! 415: print("0x%x,0,0x%x,_%s\n", N_FUN, p->u.f.pt[0].y, p->name); ! 416: print(".stabs \"%s\",0x%x,0,", p->name, ! 417: p->sclass == STATIC ? N_STFUN : N_GSYM); ! 418: adr = "0"; ! 419: } else if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) { ! 420: print("0x%x,0,", N_GSYM); ! 421: adr = "0"; ! 422: } else if (p->sclass == STATIC) ! 423: print("0x%x,0,", p->u.seg == BSS ? N_LCSYM : N_STSYM); ! 424: else if (p->scope == PARAM) ! 425: print("0x%x,0,", p->sclass == REGISTER ? N_RSYM : N_PSYM); ! 426: else if (p->scope >= LOCAL) { ! 427: print("0x%x,0,", p->sclass == REGISTER ? N_RSYM : N_LSYM); ! 428: if (p->sclass != REGISTER) ! 429: adr = p->x.name + 1; /* skip - sign */ ! 430: } else ! 431: assert(0); ! 432: emittype(0, 5, p->type, adr); ! 433: } ! 434: ! 435: /* stabtype - output a stab entry for type name, ty */ ! 436: static void stabtype(p) Symbol p; { ! 437: char *name = p->name; ! 438: ! 439: if (p->sclass || p->type == 0 || glevel <= 1) ! 440: return; ! 441: if (*p->name >= '0' && *p->name <= '9') ! 442: name = stringf("%s$%d.%s", p->src.file, p->src.y, p->name); ! 443: switch (p->type->op) { ! 444: case STRUCT: case UNION: { ! 445: Field q; ! 446: print(".stabs \"%s\",0x%x,0,%d,0\n", name, N_BSTR, ! 447: p->type->op == STRUCT ? 8 : 9); ! 448: for (q = fieldlist(p->type); q; q = q->link) { ! 449: print(".stabs \"%s\",", q->name ? q->name : ""); ! 450: if (q->lsb) ! 451: print("0x%x,0,0x%x,%d\n", N_SFLD, ! 452: fieldsize(q)<<5|(q->type == inttype ? 4 : 14), ! 453: 8*q->offset + fieldright(q)); ! 454: else { ! 455: print("0x%x,0,", N_SSYM); ! 456: emittype(0, 5, q->type, stringd(q->offset)); ! 457: } ! 458: } ! 459: print(".stabs \"%s\",0x%x,0,%d,%d\n", name, N_ESTR, ! 460: p->type->op == STRUCT ? 8 : 9, p->type->size); ! 461: break; ! 462: } ! 463: case ENUM: { ! 464: Symbol *q; ! 465: print(".stabs \"%s\",0x%x,0,10,0\n", name, N_BSTR); ! 466: for (q = p->u.idlist; *q; q++) ! 467: print(".stabs \"%s\",0x%x,0,11,%d\n", (*q)->name, ! 468: N_SSYM, (*q)->u.value); ! 469: print(".stabs \"%s\",0x%x,0,10,%d\n", name, N_ESTR, ! 470: p->type->size); ! 471: break; ! 472: } ! 473: } ! 474: } ! 475: #endif ! 476: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.