aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/example.c
diff options
authorLinus Torvalds <torvalds@evo.osdl.org>2004-12-11 21:26:50 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:06:02 -0700
commit7ec6f5462f09df41d61a986b80cf7a6cfb174464 (patch)
tree133f5a2d2edc41641497c5c911f949afe2791fcb /example.c
parent10a301a2d01b93423e1699e2131707464d2e5448 (diff)
downloadsparse-dev-7ec6f5462f09df41d61a986b80cf7a6cfb174464.tar.gz
Do some kind of signed cast too.
Diffstat (limited to 'example.c')
-rw-r--r--example.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/example.c b/example.c
index 616539fd..c13335fd 100644
--- a/example.c
+++ b/example.c
@@ -741,7 +741,6 @@ static void generate_cast(struct bb_state *state, struct instruction *insn)
struct hardreg *dst;
unsigned int old = insn->orig_type ? insn->orig_type->bit_size : 0;
unsigned int new = insn->size;
- unsigned long long mask;
/*
* Cast to smaller type? Ignore the high bits, we
@@ -754,10 +753,14 @@ static void generate_cast(struct bb_state *state, struct instruction *insn)
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);
+ if (insn->orig_type && (insn->orig_type->ctype.modifiers & MOD_SIGNED)) {
+ output_insn(state, "sext.%d.%d %s", old, new, dst->name);
+ } else {
+ unsigned long long mask;
+ 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);
}