aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-10 14:14:48 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:55 -0700
commit5925cd42c163ead7e5fad701e5a34bb14382291d (patch)
tree5629bb8b961adfc44234af24c0bf8f12bdfc309e /example.c
parentAdd fake OP_CALL code generation. (diff)
downloadsparse-5925cd42c163ead7e5fad701e5a34bb14382291d.tar.gz
sparse-5925cd42c163ead7e5fad701e5a34bb14382291d.tar.bz2
sparse-5925cd42c163ead7e5fad701e5a34bb14382291d.zip
Generate cheesy "cast" instructions.
No sign extension, no nuffink. My opcode generation gets worse and worse.
Diffstat (limited to 'example.c')
-rw-r--r--example.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/example.c b/example.c
index 79e4da9..da7a3a4 100644
--- a/example.c
+++ b/example.c
@@ -594,6 +594,25 @@ static void generate_phisource(struct instruction *insn, struct bb_state *state)
} END_FOR_EACH_PTR(user);
}
+static void generate_cast(struct bb_state *state, struct instruction *insn)
+{
+ struct hardreg *src = getreg(state, insn->src, insn->target);
+ struct hardreg *dst = copy_reg(state, src, insn->target);
+ unsigned int old = insn->orig_type ? insn->orig_type->bit_size : 0;
+ unsigned int new = insn->size;
+ unsigned long long mask;
+
+ /* No, we shouldn't just mask it, but this is just for an example */
+ if (old > new) {
+ mask = ~(~0ULL << new);
+ } else {
+ mask = ~(~0ULL << old);
+ }
+
+ output_insn(state, "andl.%d $%#llx,%s", insn->size, mask, dst->name);
+ add_pseudo_reg(state, insn->target, dst);
+}
+
static void generate_output_storage(struct bb_state *state);
static void generate_branch(struct bb_state *state, struct instruction *br)
@@ -692,6 +711,10 @@ static void generate_one_insn(struct instruction *insn, struct bb_state *state)
generate_binop(state, insn);
break;
+ case OP_CAST: case OP_PTRCAST:
+ generate_cast(state, insn);
+ break;
+
case OP_BR:
generate_branch(state, insn);
break;