aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linearize.c
diff options
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-02-23 13:35:00 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:01:28 -0700
commitdcda4aecd5eddf0001417fc20dd530bb3154f654 (patch)
tree287501fabb069b6caa3f6b8ea4ce840c0a6bd42f /linearize.c
parent8e3e7f9a8c1a6ea2532b383aacc76b49000a53d6 (diff)
downloadsparse-dev-dcda4aecd5eddf0001417fc20dd530bb3154f654.tar.gz
Linearize post-ops and casts.
And add a "OP_BADOP" linearization for expressions that we don't do yet, so that it's easier to see what is missing..
Diffstat (limited to 'linearize.c')
-rw-r--r--linearize.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/linearize.c b/linearize.c
index b839f1fc..afaa616f 100644
--- a/linearize.c
+++ b/linearize.c
@@ -44,6 +44,9 @@ static void show_instruction(struct instruction *insn)
int op = insn->opcode;
switch (op) {
+ case OP_BADOP:
+ printf("\tAIEEE! (%d %d)\n", insn->target.nr, insn->src.nr);
+ break;
case OP_CONDTRUE: case OP_CONDFALSE:
printf("\t%s %%r%d,%p\n",
op == OP_CONDTRUE ? "jne" : "jz",
@@ -93,6 +96,12 @@ static void show_instruction(struct instruction *insn)
case OP_INDCALL:
printf("\t%%r%d <- CALL [%%r%d]\n", insn->target.nr, insn->src.nr);
break;
+ case OP_CAST:
+ printf("\t%%r%d <- CAST(%d->%d) %%r%d\n",
+ insn->target.nr,
+ insn->orig_type->bit_size, insn->type->bit_size,
+ insn->src.nr);
+ break;
case OP_UNOP ... OP_LASTUNOP:
printf("\t%%r%d <- %c %%r%d\n",
insn->target.nr,
@@ -327,6 +336,11 @@ static pseudo_t linearize_preop(struct entrypoint *ep, struct expression *expr)
return linearize_regular_preop(ep, expr);
}
+static pseudo_t linearize_postop(struct entrypoint *ep, struct expression *expr)
+{
+ return linearize_inc_dec(ep, expr, 1);
+}
+
static pseudo_t linearize_assignment(struct entrypoint *ep, struct expression *expr)
{
struct expression *target = expr->left;
@@ -459,6 +473,21 @@ static pseudo_t linearize_logical(struct entrypoint *ep, struct expression *expr
return result;
}
+pseudo_t linearize_cast(struct entrypoint *ep, struct expression *expr)
+{
+ pseudo_t src, result;
+ struct instruction *insn;
+
+ src = linearize_expression(ep, expr->cast_expression);
+ insn = alloc_instruction(OP_CAST, expr->ctype);
+ result = alloc_pseudo();
+ insn->target = result;
+ insn->src = src;
+ insn->orig_type = expr->cast_expression->ctype;
+ add_one_insn(ep, expr->pos, insn);
+ return result;
+}
+
pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
{
if (!expr)
@@ -497,9 +526,20 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
case EXPR_PREOP:
return linearize_preop(ep, expr);
- default:
+ case EXPR_POSTOP:
+ return linearize_postop(ep, expr);
+
+ case EXPR_CAST:
+ return linearize_cast(ep, expr);
+
+ default: {
+ struct instruction *bad = alloc_instruction(OP_BADOP, expr->ctype);
+ bad->target.nr = expr->type;
+ bad->src.nr = expr->op;
+ add_one_insn(ep, expr->pos, bad);
return VOID;
}
+ }
return VOID;
}