📄 xr16.md
字号:
p->syms[2] = intconst(mkactual(align,
p->syms[0]->u.c.v.i));
}
static void local(Symbol p) {
if (askregvar(p, rmap(ttob(p->type))) == 0)
mkauto(p);
}
static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
int i, saved, sizefsave, sizeisave, varargs;
Symbol r, argregs[NUM_ARG_REGS];
usedmask[0] = usedmask[1] = 0;
freemask[0] = freemask[1] = ~(unsigned)0;
offset = maxoffset = maxargoffset = 0;
for (i = 0; callee[i]; i++)
;
varargs = variadic(f->type)
|| i > 0 && strcmp(callee[i-1]->name, "va_alist") == 0;
for (i = 0; callee[i]; i++) {
Symbol p = callee[i];
Symbol q = caller[i];
assert(q);
offset = roundup(offset, q->type->align);
p->x.offset = q->x.offset = offset;
p->x.name = q->x.name = stringd(offset);
r = argreg(i, offset, optype(ttob(q->type)), q->type->size, optype(ttob(caller[0]->type)));
if (i < NUM_ARG_REGS)
argregs[i] = r;
offset = roundup(offset + q->type->size, 2);
if (varargs)
p->sclass = AUTO;
else if (r && ncalls == 0 &&
!isstruct(q->type) && !p->addressed &&
!(isfloat(q->type) && r->x.regnode->set == IREG)
) {
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 = 0;
gencode(caller, callee);
if (ncalls)
usedmask[IREG] |= ((unsigned)1)<<REG_RETADDR;
usedmask[IREG] &= INT_CALLEE_SAVE;
usedmask[FREG] &= 0xfff00000;
maxargoffset = roundup(maxargoffset, usedmask[FREG] ? 8 : 2);
if (ncalls && maxargoffset < NUM_ARG_REGS*2)
maxargoffset = NUM_ARG_REGS*2;
sizefsave = 4*bitcount(usedmask[FREG]);
sizeisave = 2*bitcount(usedmask[IREG]);
framesize = roundup(maxargoffset + sizefsave
+ sizeisave + maxoffset, 2);
segment(CODE);
printf("align 16\n");
printf("%s:\n", f->x.name);
i = maxargoffset + sizefsave - framesize;
if (framesize > 0)
print("addi sp,sp,%d\n", -framesize);
saved = maxargoffset;
for (i = 20; i <= 30; i += 2)
if (usedmask[FREG]&(3<<i)) {
print("s.d rf%d,%d(sp)\n", i, saved);
saved += 8;
}
for (i = 0; i < NUM_IREGS; i++)
if (usedmask[IREG]&(1<<i)) {
print("sw r%d,%d(sp)\n", i, saved);
saved += 2;
}
for (i = 0; i < NUM_ARG_REGS && 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
&& (isint(out->type) || out->type == in->type)) {
int outn = out->x.regnode->number;
if (rs == FREG && tyin == F+sizeop(8))
print("mov.d rf%d,rf%d\n", outn, rn);
else if (rs == FREG && tyin == F+sizeop(4))
print("mov.s rf%d,rf%d\n", outn, rn);
else if (rs == IREG && tyin == F+sizeop(8))
print("mtc1.d r%d,rf%d\n", rn, outn);
else if (rs == IREG && tyin == F+sizeop(4))
print("mtc1 r%d,rf%d\n", rn, outn);
else
print("mov r%d,r%d\n", outn, rn);
} else {
int off = in->x.offset + framesize;
if (rs == FREG && tyin == F+sizeop(8))
print("s.d rf%d,%d(sp)\n", rn, off);
else if (rs == FREG && tyin == F+sizeop(4))
print("s.s rf%d,%d(sp)\n", rn, off);
else {
int i, n = (in->type->size + 1)/2;
for (i = rn; i < rn+n && i <= REG_LAST_ARG; i++)
print("sw r%d,%d(sp)\n", i, off + (i-rn)*2);
}
}
}
}
if (varargs && callee[i-1]) {
i = callee[i-1]->x.offset + callee[i-1]->type->size;
for (i = roundup(i, 2)/2; i < NUM_ARG_REGS; i++)
print("sw r%d,%d(sp)\n", REG_FIRST_ARG + i, framesize + 2*i);
}
emitcode();
saved = maxargoffset;
for (i = 20; i <= 30; i += 2)
if (usedmask[FREG]&(3<<i)) {
print("l.d rf%d,%d(sp)\n", i, saved);
saved += 8;
}
for (i = 0; i < NUM_IREGS; i++)
if (usedmask[IREG]&(1<<i)) {
print("lw r%d,%d(sp)\n", i, saved);
saved += 2;
}
if (framesize > 0)
print("addi sp,sp,%d\n", framesize);
print("ret\n\n");
}
static void defconst(int suffix, int size, Value v) {
if (suffix == F)
fp();
else if (suffix == P)
print("word %u\n", v.p);
else if (size == 1)
print("byte %u\n", suffix == I ? v.i : v.u);
else if (size == 2)
print("word %u\n", suffix == I ? v.i : v.u);
else if (size == 4)
print("dword %u\n", suffix == I ? v.i : v.u);
}
static void defaddress(Symbol p) {
print("word %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("global %s\n", p->x.name);
}
static void import(Symbol p) {
if (!isfunc(p->type))
print("global %s\n", p->x.name); /* good enough? */
}
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 if (p->scope == GLOBAL || p->sclass == EXTERN)
p->x.name = stringf("_%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->type->align > 1)
print("align %d\n", p->type->align);
print("%s:\n", p->x.name);
if (p->u.seg == BSS)
printf("bss %d\n", p->type->size);
}
static void segment(int n) {
cseg = n;
}
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("addi r%d,r%d,%d\n", sreg, sreg, size&~7);
print("addi r%d,r%d,%d\n", tmps[2], dreg, size&~7);
blkcopy(tmps[2], doff, sreg, soff, size&7, tmps);
print("L%d:\n", lab);
print("addi r%d,r%d,%d\n", sreg, sreg, -8);
print("addi r%d,r%d,%d\n", tmps[2], tmps[2], -8);
blkcopy(tmps[2], doff, sreg, soff, 8, tmps);
print("cmp r%d,r%d\nbltu L%d\n", dreg, tmps[2], lab);
}
static void blkfetch(int size, int off, int reg, int tmp) {
assert(size == 1 || size == 2);
if (size == 1)
print("lb r%d,%d(r%d)\n", tmp, off, reg);
else {
assert(salign >= size);
print("lw r%d,%d(r%d)\n", tmp, off, reg);
}
}
static void blkstore(int size, int off, int reg, int tmp) {
assert(size == 1 || size == 2);
if (size == 1)
print("sb r%d,%d(r%d)\n", tmp, off, reg);
else {
assert(dalign >= size);
print("sw r%d,%d(r%d)\n", tmp, off, reg);
}
}
static void stabinit(char *, int, char *[]);
static void stabline(Coordinate *);
static void stabsym(Symbol);
static char *currentfile;
static int bitcount(unsigned mask) {
unsigned i, n = 0;
for (i = 1; i; i <<= 1)
if (mask&i)
n++;
return n;
}
/* stabinit - initialize stab output */
static void stabinit(char *file, int argc, char *argv[]) {
if (file) {
print("file \"%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 \"%s\"\n", cp->file);
currentfile = cp->file;
}
print("loc %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);
}
static int fp() {
static int err = 0;
if (!err) {
err = 1;
error("floating point not implemented\n");
}
return 2;
}
Interface xr16IR = {
1, 1, 0, /* char */
2, 2, 0, /* short */
2, 2, 0, /* int */
4, 4, 0, /* long */
4, 4, 0, /* long long */
4, 4, 1, /* float */
4, 4, 1, /* double */
4, 4, 1, /* long double */
2, 2, 0, /* T * */
0, 2, 0, /* struct */
0, /* little_endian */
1, /* mulops_calls */
0, /* wants_callb */
0, /* wants_argb */
1, /* left_to_right */
0, /* wants_dag */
1, /* 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,
{
2, /* max_unaligned_load */
rmap,
blkfetch, blkstore, blkloop,
_label,
_rule,
_nts,
_kids,
_string,
_templates,
_isinstruction,
_ntname,
emit2,
doarg,
target,
clobber,
}
};
static char rcsid[] =
"$Header: /dist/lcc-xr16/src-mods/src/xr16.md 3 3/04/00 10:05a Jan $\n"
"Portions copyright (C) 1999,2000, Gray Research LLC. All rights reserved.\n"
"This program is subject to the XSOC License Agreement.\n"
"See the LICENSE file.";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -