aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/example.c
diff options
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-08 21:30:19 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:44 -0700
commit45d84a60ee3f3f30ed1a41e39237d6fe53efdda7 (patch)
treec5e711a960b3236a9e878e17ce9f8b8b8ebbce41 /example.c
parent5f3baf5f3df4c7710631732cf34aad2869f5fd19 (diff)
downloadsparse-dev-45d84a60ee3f3f30ed1a41e39237d6fe53efdda7.tar.gz
Add a few more hard registers, and let things live a bit longer.
Our binops are destructive, but maybe we should try to copy the destroyed register if it's still live.
Diffstat (limited to 'example.c')
-rw-r--r--example.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/example.c b/example.c
index c16c12a7..05e2b495 100644
--- a/example.c
+++ b/example.c
@@ -29,6 +29,9 @@ static struct hardreg hardregs[] = {
{ .name = "eax" },
{ .name = "edx" },
{ .name = "ecx" },
+ { .name = "ebx" },
+ { .name = "esi" },
+ { .name = "edi" },
};
#define REGNO (sizeof(hardregs)/sizeof(struct hardreg))
@@ -336,15 +339,36 @@ static const char* opcodes[] = {
[OP_CONTEXT] = "context",
};
+
+static struct hardreg *copy_reg(struct bb_state *state, struct hardreg *src)
+{
+ int i;
+
+ if (!src->busy)
+ return src;
+
+ for (i = 0; i < REGNO; i++) {
+ struct hardreg *reg = hardregs + i;
+ if (!reg->busy) {
+ printf("\tmovl %s,%s\n", src->name, reg->name);
+ return reg;
+ }
+ }
+
+ flush_reg(state, src);
+ return src;
+}
+
static void generate_binop(struct bb_state *state, struct instruction *insn)
{
const char *op = opcodes[insn->opcode];
- struct hardreg *reg = getreg(state, insn->src1);
- flush_reg(state, reg);
- printf("\t%s.%d %s,%s\n", op, insn->size, reg_or_imm(state, insn->src2), reg->name);
- reg->contains = insn->target;
- reg->busy = 1;
- reg->dirty = 1;
+ struct hardreg *src = getreg(state, insn->src1);
+ struct hardreg *dst = copy_reg(state, src);
+
+ printf("\t%s.%d %s,%s\n", op, insn->size, reg_or_imm(state, insn->src2), dst->name);
+ dst->contains = insn->target;
+ dst->busy = 1;
+ dst->dirty = 1;
}
static void mark_pseudo_dead(pseudo_t pseudo)