aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2021-02-20 06:53:18 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2021-02-21 12:44:02 +0100
commit2494587e823700458923052b17b0b981be92d776 (patch)
tree56b9680a78dc5b33c6580aeb39126c0a1b69a16f
parentefcf0db9d27ee1f463e1d6544bdaa7d0fd769778 (diff)
downloadsparse-2494587e823700458923052b17b0b981be92d776.tar.gz
asm: output *memory* operands need their address as *input*
The addresses needed by memory output operands are linearized (and placed) after the ASM instruction needing them. So, split add_asm_output() in 2 parts: one generating only the addresses for memory operands and called before issuing the body, and another one doing the usual copy of (non-memory) output operands back into their corresponding variables. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--linearize.c31
-rw-r--r--validation/linear/asm-out0.c1
2 files changed, 23 insertions, 9 deletions
diff --git a/linearize.c b/linearize.c
index 6efa4749..33d641b4 100644
--- a/linearize.c
+++ b/linearize.c
@@ -2144,19 +2144,29 @@ static void add_asm_input(struct entrypoint *ep, struct instruction *insn, struc
add_asm_rule(insn, &insn->asm_rules->inputs, op, pseudo);
}
+static void add_asm_output_address(struct entrypoint *ep, struct instruction *insn, struct asm_operand *op)
+{
+ pseudo_t pseudo;
+
+ if (!op->is_memory)
+ return;
+
+ pseudo = linearize_expression(ep, op->expr);
+ add_asm_rule(insn, &insn->asm_rules->outputs, op, pseudo);
+}
+
static void add_asm_output(struct entrypoint *ep, struct instruction *insn, struct asm_operand *op)
{
struct access_data ad = { NULL, };
pseudo_t pseudo;
- if (op->is_memory) {
- pseudo = linearize_expression(ep, op->expr);
- } else {
- if (!linearize_address_gen(ep, op->expr, &ad))
- return;
- pseudo = alloc_pseudo(insn);
- linearize_store_gen(ep, pseudo, &ad);
- }
+ if (op->is_memory)
+ return;
+
+ if (!linearize_address_gen(ep, op->expr, &ad))
+ return;
+ pseudo = alloc_pseudo(insn);
+ linearize_store_gen(ep, pseudo, &ad);
add_asm_rule(insn, &insn->asm_rules->outputs, op, pseudo);
}
@@ -2184,6 +2194,11 @@ static pseudo_t linearize_asm_statement(struct entrypoint *ep, struct statement
add_asm_input(ep, insn, op);
} END_FOR_EACH_PTR(op);
+ /* ... and the addresses for memory outputs */
+ FOR_EACH_PTR(stmt->asm_outputs, op) {
+ add_asm_output_address(ep, insn, op);
+ } END_FOR_EACH_PTR(op);
+
add_one_insn(ep, insn);
/* Assign the outputs */
diff --git a/validation/linear/asm-out0.c b/validation/linear/asm-out0.c
index 64d154ed..a8e0be69 100644
--- a/validation/linear/asm-out0.c
+++ b/validation/linear/asm-out0.c
@@ -7,7 +7,6 @@ static void asm_out0(void)
/*
* check-name: asm-out0
* check-command: test-linearize -fdump-ir $file
- * check-known-to-fail
*
* check-output-start
asm_out0: