[PATCH 3/3] asm: output *memory* operands need their address as *input*

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux