📄 mips.md
字号:
usedmask[IREG] &= 0xc0ff0000;
usedmask[FREG] &= 0xfff00000;
if (pic && ncalls)
usedmask[IREG] |= 1<<25;
maxargoffset = roundup(maxargoffset, usedmask[FREG] ? 8 : 4);
if (ncalls && maxargoffset < 16)
maxargoffset = 16;
sizefsave = 4*bitcount(usedmask[FREG]);
sizeisave = 4*bitcount(usedmask[IREG]);
framesize = roundup(maxargoffset + sizefsave
+ sizeisave + maxoffset, 16);
segment(CODE);
print(".align 2\n");
print(".ent %s\n", f->x.name);
print("%s:\n", f->x.name);
i = maxargoffset + sizefsave - framesize;
print(".frame $sp,%d,$31\n", framesize);
if (pic)
print(".set noreorder\n.cpload $25\n.set reorder\n");
if (framesize > 0)
print("addu $sp,$sp,%d\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 - 4);
saved = maxargoffset;
for (i = 20; i <= 30; i += 2)
if (usedmask[FREG]&(3<<i)) {
print("s.d $f%d,%d($sp)\n", i, saved);
saved += 8;
}
for (i = 16; i <= 31; i++)
if (usedmask[IREG]&(1<<i)) {
if (i == 25)
print(".cprestore %d\n", saved);
else
print("sw $%d,%d($sp)\n", i, saved);
saved += 4;
}
for (i = 0; i < 4 && 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 $f%d,$f%d\n", outn, rn);
else if (rs == FREG && tyin == F+sizeop(4))
print("mov.s $f%d,$f%d\n", outn, rn);
else if (rs == IREG && tyin == F+sizeop(8))
print("mtc1.d $%d,$f%d\n", rn, outn);
else if (rs == IREG && tyin == F+sizeop(4))
print("mtc1 $%d,$f%d\n", rn, outn);
else
print("move $%d,$%d\n", outn, rn);
} else {
int off = in->x.offset + framesize;
if (rs == FREG && tyin == F+sizeop(8))
print("s.d $f%d,%d($sp)\n", rn, off);
else if (rs == FREG && tyin == F+sizeop(4))
print("s.s $f%d,%d($sp)\n", rn, off);
else {
int i, n = (in->type->size + 3)/4;
for (i = rn; i < rn+n && i <= 7; i++)
print("sw $%d,%d($sp)\n", i, off + (i-rn)*4);
}
}
}
}
if (varargs && callee[i-1]) {
i = callee[i-1]->x.offset + callee[i-1]->type->size;
for (i = roundup(i, 4)/4; i <= 3; i++)
print("sw $%d,%d($sp)\n", i + 4, framesize + 4*i);
}
emitcode();
saved = maxargoffset;
for (i = 20; i <= 30; i += 2)
if (usedmask[FREG]&(3<<i)) {
print("l.d $f%d,%d($sp)\n", i, saved);
saved += 8;
}
for (i = 16; i <= 31; i++)
if (usedmask[IREG]&(1<<i)) {
print("lw $%d,%d($sp)\n", i, saved);
saved += 4;
}
if (framesize > 0)
print("addu $sp,$sp,%d\n", framesize);
print("j $31\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(".word 0x%x\n", *(unsigned *)&f);
}
else if (suffix == F && size == 8) {
double d = v.d;
unsigned *p = (unsigned *)&d;
print(".word 0x%x\n.word 0x%x\n", p[swap], p[!swap]);
}
else if (suffix == P)
print(".word 0x%x\n", (unsigned)v.p);
else if (size == 1)
print(".byte 0x%x\n", (unsigned)((unsigned char)(suffix == I ? v.i : v.u)));
else if (size == 2)
print(".half 0x%x\n", (unsigned)((unsigned short)(suffix == I ? v.i : v.u)));
else if (size == 4)
print(".word 0x%x\n", (unsigned)(suffix == I ? v.i : v.u));
}
static void defaddress(Symbol p) {
if (pic && p->scope == LABELS)
print(".gpword %s\n", p->x.name);
else
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(".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 == BSS) {
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);
} else {
if (p->u.seg == DATA
&& (p->type->size == 0 || p->type->size > gnum))
print(".data\n");
else if (p->u.seg == DATA)
print(".sdata\n");
print(".align %c\n", ".01.2...3"[p->type->align]);
print("%s:\n", p->x.name);
}
}
static void segment(int n) {
cseg = n;
switch (n) {
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("addu $%d,$%d,%d\n", sreg, sreg, size&~7);
print("addu $%d,$%d,%d\n", tmps[2], dreg, size&~7);
blkcopy(tmps[2], doff, sreg, soff, size&7, tmps);
print("L.%d:\n", lab);
print("addu $%d,$%d,%d\n", sreg, sreg, -8);
print("addu $%d,$%d,%d\n", tmps[2], tmps[2], -8);
blkcopy(tmps[2], doff, sreg, soff, 8, tmps);
print("bltu $%d,$%d,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);
if (size == 1)
print("lbu $%d,%d($%d)\n", tmp, off, reg);
else if (salign >= size && size == 2)
print("lhu $%d,%d($%d)\n", tmp, off, reg);
else if (salign >= size)
print("lw $%d,%d($%d)\n", tmp, off, reg);
else if (size == 2)
print("ulhu $%d,%d($%d)\n", tmp, off, reg);
else
print("ulw $%d,%d($%d)\n", tmp, off, reg);
}
static void blkstore(int size, int off, int reg, int tmp) {
if (size == 1)
print("sb $%d,%d($%d)\n", tmp, off, reg);
else if (dalign >= size && size == 2)
print("sh $%d,%d($%d)\n", tmp, off, reg);
else if (dalign >= size)
print("sw $%d,%d($%d)\n", tmp, off, reg);
else if (size == 2)
print("ush $%d,%d($%d)\n", tmp, off, reg);
else
print("usw $%d,%d($%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 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 mipsebIR = {
1, 1, 0, /* char */
2, 2, 0, /* short */
4, 4, 0, /* int */
4, 4, 0, /* long */
4, 4, 0, /* long long */
4, 4, 1, /* float */
8, 8, 1, /* double */
8, 8, 1, /* long double */
4, 4, 0, /* T * */
0, 1, 0, /* struct */
0, /* 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,
{
4, /* max_unaligned_load */
rmap,
blkfetch, blkstore, blkloop,
_label,
_rule,
_nts,
_kids,
_string,
_templates,
_isinstruction,
_ntname,
emit2,
doarg,
target,
clobber,
}
}, mipselIR = {
1, 1, 0, /* char */
2, 2, 0, /* short */
4, 4, 0, /* int */
4, 4, 0, /* long */
4, 4, 0, /* long long */
4, 4, 1, /* float */
8, 8, 1, /* double */
8, 8, 1, /* long double */
4, 4, 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,
{
4, /* max_unaligned_load */
rmap,
blkfetch, blkstore, blkloop,
_label,
_rule,
_nts,
_kids,
_string,
_templates,
_isinstruction,
_ntname,
emit2,
doarg,
target,
clobber,
}
};
static char rcsid[] = "$Id: mips.md,v 1.1 2002/08/28 23:12:44 drh Exp $";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -