aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-11 21:17:37 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:06:02 -0700
commit10a301a2d01b93423e1699e2131707464d2e5448 (patch)
tree778f9dbca45d6257df4be71b92c730b14d0e9218 /example.c
parentTeach code generator about commutative operations. (diff)
downloadsparse-10a301a2d01b93423e1699e2131707464d2e5448.tar.gz
sparse-10a301a2d01b93423e1699e2131707464d2e5448.tar.bz2
sparse-10a301a2d01b93423e1699e2131707464d2e5448.zip
Do slightly better on casts.
In particular, casts to a smaller type doesn't need to do anything.
Diffstat (limited to 'example.c')
-rw-r--r--example.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/example.c b/example.c
index fc3467c..616539f 100644
--- a/example.c
+++ b/example.c
@@ -738,18 +738,25 @@ static void generate_phisource(struct instruction *insn, struct bb_state *state)
static void generate_cast(struct bb_state *state, struct instruction *insn)
{
struct hardreg *src = getreg(state, insn->src, insn->target);
- struct hardreg *dst = target_copy_reg(state, src, insn->target);
+ struct hardreg *dst;
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);
+ /*
+ * Cast to smaller type? Ignore the high bits, we
+ * just keep both pseudos in the same register.
+ */
+ if (old >= new) {
+ add_pseudo_reg(state, insn->target, src);
+ return;
}
+ dst = target_copy_reg(state, src, insn->target);
+
+ mask = ~(~0ULL << old);
+ mask &= ~(~0ULL << new);
+
output_insn(state, "andl.%d $%#llx,%s", insn->size, mask, dst->name);
add_pseudo_reg(state, insn->target, dst);
}