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@xxxxxxxxx> --- linearize.c | 31 +++++++++++++++++++++++-------- validation/linear/asm-out0.c | 1 - 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/linearize.c b/linearize.c index 6efa47492869..33d641b40de6 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 64d154ed5ad7..a8e0be693d87 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: -- 2.30.0