diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2021-02-20 06:53:18 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2021-02-21 12:44:02 +0100 |
commit | 2494587e823700458923052b17b0b981be92d776 (patch) | |
tree | 56b9680a78dc5b33c6580aeb39126c0a1b69a16f | |
parent | efcf0db9d27ee1f463e1d6544bdaa7d0fd769778 (diff) | |
download | sparse-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.c | 31 | ||||
-rw-r--r-- | validation/linear/asm-out0.c | 1 |
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: |