aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--amd64/emit.c24
-rw-r--r--amd64/isel.c6
-rw-r--r--amd64/sysv.c2
-rw-r--r--ir.c32
-rw-r--r--ir.h6
-rw-r--r--targ.c3
6 files changed, 46 insertions, 27 deletions
diff --git a/amd64/emit.c b/amd64/emit.c
index d2c5aa8..b7cea24 100644
--- a/amd64/emit.c
+++ b/amd64/emit.c
@@ -641,16 +641,19 @@ emitbin(struct function *fn)
aligncode(pcode, 16);
/** prologue **/
- /* push rbp; mov rbp, rsp */
- DS("\x55\x48\x89\xE5");
+ if (fn->stksiz != 0)
+ /* push rbp; mov rbp, rsp */
+ DS("\x55\x48\x89\xE5");
calleesave(pcode, fn);
- /* sub rsp, <stack size> */
- if (fn->stksiz < 128)
- DS("\x48\x83\xEC"), B(fn->stksiz);
- else if (fn->stksiz == 128)
- DS("\x48\x83\xC4\x80"); /* add rsp, -128 */
- else
- DS("\x48\x81\xEC"), I32(fn->stksiz);
+ if (fn->stksiz != 0) {
+ /* sub rsp, <stack size> */
+ if (fn->stksiz < 128)
+ DS("\x48\x83\xEC"), B(fn->stksiz);
+ else if (fn->stksiz == 128)
+ DS("\x48\x83\xC4\x80"); /* add rsp, -128 */
+ else
+ DS("\x48\x81\xEC"), I32(fn->stksiz);
+ }
blk = fn->entry;
do {
@@ -660,7 +663,8 @@ emitbin(struct function *fn)
if (blk->jmp.t == Jret) {
/* epilogue */
calleerestore(pcode, fn);
- DS("\xC9\xC3"); /* leave; ret */
+ if (fn->stksiz) B(0xC9); /* leave */
+ B(0xC3); /* ret */
}
} while ((blk = blk->lnext) != fn->entry);
}
diff --git a/amd64/isel.c b/amd64/isel.c
index 8d19cad..7725013 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -190,7 +190,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
case Osub:
if (ins->r.bits == mkref(RICON, 1).bits) {
/* sub x,1 -> dec x */
- ins->op = Oxdec;
+ ins->op = op = Oxdec;
ins->r = NOREF;
} else if (iscon(ins->l)) {
/* sub imm, x -> sub x, imm; neg x */
@@ -204,13 +204,13 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
case Oadd:
if (ins->l.bits == mkref(RICON, 1).bits) {
/* add 1,x -> inc x */
- ins->op = Oxinc;
+ ins->op = op = Oxinc;
ins->l = ins->r;
ins->r = NOREF;
goto ALU;
} else if (ins->r.bits == mkref(RICON, 1).bits) {
/* add x,1 -> inc x */
- ins->op = Oxinc;
+ ins->op = op = Oxinc;
ins->r = NOREF;
goto ALU;
} else if (kisint(ins->cls) && (addarg4addrp(ins->l) || addarg4addrp(ins->r))) {
diff --git a/amd64/sysv.c b/amd64/sysv.c
index 1c84909..dc43b81 100644
--- a/amd64/sysv.c
+++ b/amd64/sysv.c
@@ -144,6 +144,8 @@ const struct mctarg t_amd64_sysv = {
.rcallee = {{1<<RBX | 1<<R12 | 1<<R13 | 1<<R14 | 1<<R15}},
.rglob = {{1<<RSP | 1<<RBP}},
.rnames = amd64_rnames,
+ .objkind = OBJELF,
+ .isa = ISamd64,
.abiret = abiret,
.abiarg = abiarg,
.isel = amd64_isel,
diff --git a/ir.c b/ir.c
index 7ccb926..d8772ad 100644
--- a/ir.c
+++ b/ir.c
@@ -367,22 +367,28 @@ putreturn(struct function *fn, union ref r0, union ref r1)
#undef putjump
void
-replref(struct function *fn, struct block *blk, int i0, union ref from, union ref to)
+blkreplref(struct block *blk, int i0, union ref from, union ref to)
{
- do {
- if (!i0) for (int i = 0; i < blk->phi.n; ++i) {
- struct phi *phi = &phitab.p[instrtab[blk->phi.p[i]].l.i];
- for (int i = 0; i < phi->n; ++i)
- if (phi->ref[i].bits == to.bits) phi->ref[i] = from;
- }
+ if (i0 == 0) for (int i = 0; i < blk->phi.n; ++i) {
+ struct phi *phi = &phitab.p[instrtab[blk->phi.p[i]].l.i];
+ for (int i = 0; i < phi->n; ++i)
+ if (phi->ref[i].bits == to.bits) phi->ref[i] = from;
+ }
- for (int i = i0; i < blk->ins.n; ++i) {
- struct instr *ins = &instrtab[blk->ins.p[i]];
- for (int i = 0; i < 2; ++i) {
- union ref *r = &(&ins->l)[i];
- if (r->bits == from.bits) *r = to;
- }
+ for (int i = i0; i < blk->ins.n; ++i) {
+ struct instr *ins = &instrtab[blk->ins.p[i]];
+ for (int i = 0; i < 2; ++i) {
+ union ref *r = &(&ins->l)[i];
+ if (r->bits == from.bits) *r = to;
}
+ }
+}
+
+void
+replref(struct function *fn, struct block *blk, int i0, union ref from, union ref to)
+{
+ do {
+ blkreplref(blk, i0, from, to);
i0 = 0;
} while ((blk = blk->lnext) != fn->entry);
}
diff --git a/ir.h b/ir.h
index d3eeeea..f00f6f0 100644
--- a/ir.h
+++ b/ir.h
@@ -138,6 +138,9 @@ struct function {
struct bitset regusage[1];
};
+enum objkind { OBJELF };
+enum mcisa { ISamd64 };
+
struct mctarg {
short gpr0, /* first gpr */
ngpr, /* gpr count */
@@ -147,6 +150,8 @@ struct mctarg {
struct bitset rcallee[1], /* callee-saved */
rglob[1]; /* globally live (never used for regalloc) */
const char (*rnames)[6];
+ enum objkind objkind;
+ enum mcisa isa;
/* abiret: lower return type:
* scalar/small struct -> returns number of regs (1..2),
* r & cls filled with reg and irclass of each scalar return
@@ -219,6 +224,7 @@ void useblk(struct function *, struct block *);
void putbranch(struct function *, struct block *);
void putcondbranch(struct function *, union ref arg, struct block *t, struct block *f);
void putreturn(struct function *, union ref r0, union ref r1);
+void blkreplref(struct block *, int, union ref from, union ref to);
void replref(struct function *, struct block *, int, union ref from, union ref to);
void irdump(struct function *);
diff --git a/targ.c b/targ.c
index da3d86a..7772537 100644
--- a/targ.c
+++ b/targ.c
@@ -16,7 +16,7 @@ static const struct targ {
uchar targ_primsizes[TYPTR+1];
uchar targ_primalign[TYPTR+1];
enum typetag targ_sizetype, targ_ptrdifftype;
-bool targ_charsigned, targ_bigendian;
+bool targ_charsigned, targ_bigendian, targ_64bit;
const struct mctarg *mctarg;
void
@@ -43,5 +43,6 @@ targ_init(const char *starg)
targ_ptrdifftype = t->ptrdifftype;
targ_charsigned = t->charsigned;
targ_bigendian = 0;
+ targ_64bit = t->ptrsize == 8;
mctarg = t->mctarg;
}