📄 alpha.md
字号:
break; } }}static void doarg(Node p) { p->syms[2] = intconst(mkactual(8, roundup(p->syms[0]->u.c.v.i,8)));}static void local(Symbol p) { if (askregvar(p, rmap(ttob(p->type))) == 0) mkauto(p);}static int bitcount(unsigned mask) { unsigned i, n = 0; for (i = 1; i; i <<= 1) if (mask&i) n++; return n;}static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { int i, sizeargs, saved, sizefsave, sizeisave, varargs; Symbol r, argregs[6]; usedmask[0] = usedmask[1] = 0; freemask[0] = freemask[1] = ~(unsigned)0; maxargoffset = offset = maxoffset = 0; for (i = 0; callee[i]; i++) ; varargs = variadic(f->type) || i > 0 && strcmp(callee[i-1]->name, "va_alist") == 0; if (varargs) sizeargs = 2*48; else sizeargs = 48; for (i = 0; callee[i]; i++) { Symbol p = callee[i]; Symbol q = caller[i]; assert(q); if (isfloat(p->type) && varargs) { p->x.offset = q->x.offset = offset - 2*48; p->x.name = q->x.name = stringd(offset - 2*48); } else { p->x.offset = q->x.offset = offset - 48; p->x.name = q->x.name = stringd(offset - 48); } offset = roundup(offset, q->type->align); r = argreg(offset, optype(ttob(q->type))); if (i < 6) argregs[i] = r; offset = roundup(offset + q->type->size, 8); if (varargs) p->sclass = AUTO; else if (r && ncalls == 0 && !isstruct(q->type) && !p->addressed) { p->sclass = q->sclass = REGISTER; askregvar(p, r); assert(p->x.regnode && p->x.regnode->vbl == p); q->x = p->x; q->type = p->type; } else if (askregvar(p, rmap(ttob(p->type))) && r != NULL /* && (isint(p->type) || p->type == q->type) */) { assert(q->sclass != REGISTER); p->sclass = q->sclass = REGISTER; q->type = p->type; } } assert(!caller[i]); offset = sizeargs + 8; gencode(caller, callee); usedmask[IREG] &= ~(INTTMP|(0x3f<<16)|INTRET); usedmask[FREG] &= ~(FLTTMP|(0x3f<<16)|FLTRET); if (ncalls || usedmask[IREG] || usedmask[FREG]) usedmask[IREG] |= 1<<26; sizefsave = 8*bitcount(usedmask[FREG]); sizeisave = 8*bitcount(usedmask[IREG]); if (maxargoffset > 48) maxargoffset -= 48; else maxargoffset = 0; if (maxoffset < sizeargs) maxoffset = sizeargs; framesize = roundup(maxargoffset + sizefsave + sizeisave + maxoffset, 16); segment(CODE); print(".ent %s\n", f->x.name); print("%s:\n", f->x.name); print("ldgp $gp,0($27)\n"); i = maxargoffset + sizefsave - framesize; if (framesize > 0) print("lda $sp,%d($sp)\n", -framesize); if (usedmask[FREG]) print(".fmask 0x%x,%d\n", usedmask[FREG], i - 8); if (usedmask[IREG]) print(".mask 0x%x,%d\n", usedmask[IREG], i + sizeisave - 8); print(".frame $sp,%d,$26,%d\n", framesize, sizeargs); saved = maxargoffset; for (i = 2; i <= 9; i++) if (usedmask[FREG]&(1<<i)) { print("stt $f%d,%d($sp)\n", i, saved); saved += 8; } for (i = 9; i <= 26; i++) if (usedmask[IREG]&(1<<i)) { print("stq $%d,%d($sp)\n", i, saved); saved += 8; } for (i = 0; i < 6 && callee[i]; i++) { r = argregs[i]; if (r && r->x.regnode != callee[i]->x.regnode) { Symbol out = callee[i]; Symbol in = caller[i]; int rn = r->x.regnode->number; int rs = r->x.regnode->set; int tyin = ttob(in->type); assert(out && in && r && r->x.regnode); assert(out->sclass != REGISTER || out->x.regnode); if (out->sclass == REGISTER) { if (rs == FREG) print("fmov $f%d,$f%d\n", rn, out->x.regnode->number); else print("mov $%d,$%d\n", rn, out->x.regnode->number); } else { int off = in->x.offset + framesize; if (rs == FREG && tyin == F+sizeop(8)) print("stt $f%d,%d($sp)\n", rn, off); else if (rs == FREG && tyin == F+sizeop(4)) print("sts $f%d,%d($sp)\n", rn, off); else { int i, n = (in->type->size + 7)/8; for (i = rn; i < rn+n && i <= 21; i++) print("stq $%d,%d($sp)\n", i, off + (i-rn)*8); } } } } if (varargs && callee[i-1]) { i = callee[i-1]->x.offset + roundup(callee[i-1]->type->size, 8); for (i = (48+i)/8; i < 6; i++) { print("stq $%d,%d($sp)\n", i + 16, framesize - 48 + 8*i); print("stt $f%d,%d($sp)\n", i + 16, framesize - 2*48 + 8*i); } } print(".prologue 1\n"); emitcode(); saved = maxargoffset; for (i = 2; i <= 9; i++) if (usedmask[FREG]&(1<<i)) { print("ldt $f%d,%d($sp)\n", i, saved); saved += 8; } for (i = 9; i <= 26; i++) if (usedmask[IREG]&(1<<i)) { print("ldq $%d,%d($sp)\n", i, saved); saved += 8; } if (framesize > 0) print("lda $sp,%d($sp)\n", framesize); print("ret\n"); print(".end %s\n", f->x.name);}static void defconst(int suffix, int size, Value v) { if (suffix == F && size == 4) { float f = v.d; print(".long 0x%x\n", *(unsigned *)&f); } else if (suffix == F && size == 8) { double d = v.d; unsigned *p = (unsigned *)&d; print(".long 0x%x\n.long 0x%x\n", p[swap], p[!swap]); } else if (suffix == P) print(".quad 0x%X\n", v.p); else if (size == 1) print(".byte 0x%x\n", suffix == I ? v.i : v.u); else if (size == 2) print(".word 0x%x\n", suffix == I ? v.i&0xFFFF : v.u&0xFFFF); else if (size == 4) print(".long 0x%x\n", suffix == I ? v.i : v.u); else if (size == 8) print(".quad 0x%X\n", suffix == I ? v.i : v.u);}static void defaddress(Symbol p) { print(".quad %s\n", p->x.name);}static void defstring(int n, char *str) { char *s; for (s = str; s < str + n; s++) print(".byte %d\n", (*s)&0377);}static void export(Symbol p) { print(".globl %s\n", p->x.name);}static void import(Symbol p) { if (!isfunc(p->type)) print(".extern %s %d\n", p->name, p->type->size);}static void defsymbol(Symbol p) { if (p->scope >= LOCAL && p->sclass == STATIC) p->x.name = stringf("L.%d", genlabel(1)); else if (p->generated) p->x.name = stringf("L.%s", p->name); else assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)), p->x.name = p->name;}static void address(Symbol q, Symbol p, long n) { if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) q->x.name = stringf("%s%s%D", p->x.name, n >= 0 ? "+" : "", n); else { assert(n <= INT_MAX && n >= INT_MIN); q->x.offset = p->x.offset + n; q->x.name = stringd(q->x.offset); }}static void global(Symbol p) { if (p->u.seg == DATA || p->u.seg == LIT) { assert(p->type->align <= 8); print(".align %c\n", ".01.2...3"[p->type->align]); print("%s:\n", p->x.name); } else if (p->sclass == STATIC || Aflag >= 2) print(".lcomm %s,%d\n", p->x.name, p->type->size); else print( ".comm %s,%d\n", p->x.name, p->type->size);}static void segment(int n) { cseg = n; switch (n) { case DATA: print(".sdata\n"); break; case CODE: print(".text\n"); break; case LIT: print(".rdata\n"); break; }}static void space(int n) { if (cseg != BSS) print(".space %d\n", n);}static void blkloop(int dreg, int doff, int sreg, int soff, int size, int tmps[]) { int lab = genlabel(1); print("addq $%d,%d,$%d\n", sreg, size&~7, sreg); print("addq $%d,%d,$%d\n", dreg, size&~7, tmps[2]); blkcopy(tmps[2], doff, sreg, soff, size&7, tmps); print("L.%d:\n", lab); print("addq $%d,%d,$%d\n", sreg, -8, sreg); print("addq $%d,%d,$%d\n", tmps[2], -8, tmps[2]); blkcopy(tmps[2], doff, sreg, soff, 8, tmps); print("cmpult $%d,$%d,$23\nbne $23,L.%d\n", dreg, tmps[2], lab);}static void blkfetch(int size, int off, int reg, int tmp) { assert(size == 1 || size == 2 || size == 4 || size == 8); if (size == 1) print("ldb $%d,%d($%d)\n", tmp, off, reg); else if (size == 2) print("ldw $%d,%d($%d)\n", tmp, off, reg); else if (salign >= size && size == 4) print("ldl $%d,%d($%d)\n", tmp, off, reg); else if (salign >= size && size == 8) print("ldq $%d,%d($%d)\n", tmp, off, reg); else if (size == 4) print("uldl $%d,%d($%d)\n", tmp, off, reg); else print("uldq $%d,%d($%d)\n", tmp, off, reg);}static void blkstore(int size, int off, int reg, int tmp) { assert(size == 1 || size == 2 || size == 4 || size == 8); if (size == 1) print("stb $%d,%d($%d)\n", tmp, off, reg); else if (size == 2) print("stw $%d,%d($%d)\n", tmp, off, reg); else if (dalign >= size && size == 4) print("stl $%d,%d($%d)\n", tmp, off, reg); else if (dalign >= size && size == 8) print("stq $%d,%d($%d)\n", tmp, off, reg); else if (size == 4) print("ustl $%d,%d($%d)\n", tmp, off, reg); else print("ustq $%d,%d($%d)\n", tmp, off, reg);}/* stabinit - initialize stab output */static void stabinit(char *file, int argc, char *argv[]) { if (file) { print(".file 2,\"%s\"\n", file); currentfile = file; }}/* stabline - emit stab entry for source coordinate *cp */static void stabline(Coordinate *cp) { if (cp->file && cp->file != currentfile) { print(".file 2,\"%s\"\n", cp->file); currentfile = cp->file; } print(".loc 2,%d\n", cp->y);}/* stabsym - output a stab entry for symbol p */static void stabsym(Symbol p) { if (p == cfunc && IR->stabline) (*IR->stabline)(&p->src);}Interface alphaIR = { 1, 1, 0, /* char */ 2, 2, 0, /* short */ 4, 4, 0, /* int */ 8, 8, 0, /* long */ 8, 8, 0, /* long long */ 4, 4, 1, /* float */ 8, 8, 1, /* double */ 8, 8, 1, /* long double */ 8, 8, 0, /* T * */ 0, 1, 0, /* struct */ 1, /* little_endian */ 0, /* mulops_calls */ 0, /* wants_callb */ 1, /* wants_argb */ 1, /* left_to_right */ 0, /* wants_dag */ 0, /* unsigned_char */ address, blockbeg, blockend, defaddress, defconst, defstring, defsymbol, emit, export, function, gen, global, import, local, progbeg, progend, segment, space, 0, 0, 0, stabinit, stabline, stabsym, 0, { 1, /* max_unaligned_load */ rmap, blkfetch, blkstore, blkloop, _label, _rule, _nts, _kids, _string, _templates, _isinstruction, _ntname, emit2, doarg, target, clobber, }};static char rcsid[] = "$Id: alpha.md,v 1.1 2002/08/28 23:12:41 drh Exp $";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -