diff mbox series

[10/18] asm: use a specific struct for asm operands

Message ID 20190927234322.5157-13-luc.vanoostenryck@gmail.com (mailing list archive)
State Mainlined, archived
Headers show
Series add missing expansion of ASM operands | expand

Commit Message

Luc Van Oostenryck Sept. 27, 2019, 11:43 p.m. UTC
Before commit 756731e9 ("use a specific struct for asm operands")
ASM operands where stored as a list of n times 3 expressions.
After this commit, the triplets where stored inside a single
expression of type EXPR_ASM_OPERAND.

However, while this improved the parsing and use of ASM operands
it needlessly reuse 'struct expression' for something that is not
an expression at all.

Fix this by really using a specific struct for ASM operands.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 allocate.c   |  1 +
 allocate.h   |  1 +
 dissect.c    |  2 +-
 evaluate.c   |  5 +----
 expand.c     |  3 ---
 expression.h | 13 ++++++-------
 inline.c     | 28 +++++++++++++---------------
 lib.h        |  2 ++
 linearize.c  | 19 ++++++++++---------
 parse.c      |  6 +++---
 parse.h      |  4 ++--
 show-parse.c |  3 ---
 12 files changed, 40 insertions(+), 47 deletions(-)
diff mbox series

Patch

diff --git a/allocate.c b/allocate.c
index 152fa8964..bef85192e 100644
--- a/allocate.c
+++ b/allocate.c
@@ -141,6 +141,7 @@  ALLOCATOR(ident, "identifiers");
 ALLOCATOR(token, "tokens");
 ALLOCATOR(context, "contexts");
 ALLOCATOR(symbol, "symbols");
+ALLOCATOR(asm_operand, "asmops");
 ALLOCATOR(expression, "expressions");
 ALLOCATOR(statement, "statements");
 ALLOCATOR(string, "strings");
diff --git a/allocate.h b/allocate.h
index 5137ae934..a6d305371 100644
--- a/allocate.h
+++ b/allocate.h
@@ -82,6 +82,7 @@  DECLARE_ALLOCATOR(ident);
 DECLARE_ALLOCATOR(token);
 DECLARE_ALLOCATOR(context);
 DECLARE_ALLOCATOR(symbol);
+DECLARE_ALLOCATOR(asm_operand);
 DECLARE_ALLOCATOR(expression);
 DECLARE_ALLOCATOR(statement);
 DECLARE_ALLOCATOR(string);
diff --git a/dissect.c b/dissect.c
index b50c268b9..14d57bf5b 100644
--- a/dissect.c
+++ b/dissect.c
@@ -450,7 +450,7 @@  again:
 	return ret;
 }
 
-static void do_asm_xputs(usage_t mode, struct expression_list *xputs)
+static void do_asm_xputs(usage_t mode, struct asm_operand_list *xputs)
 {
 	DO_LIST(xputs, op, do_expression(U_W_AOF | mode, op->expr));
 }
diff --git a/evaluate.c b/evaluate.c
index 634da4b93..7cc695c7e 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -3354,9 +3354,6 @@  struct symbol *evaluate_expression(struct expression *expr)
 	case EXPR_SLICE:
 		expression_error(expr, "internal front-end error: SLICE re-evaluated");
 		return NULL;
-	case EXPR_ASM_OPERAND:
-		expression_error(expr, "internal front-end error: ASM_OPERAND evaluated");
-		return NULL;
 	}
 	return NULL;
 }
@@ -3519,7 +3516,7 @@  static void verify_input_constraint(struct expression *expr, const char *constra
 static void evaluate_asm_statement(struct statement *stmt)
 {
 	struct expression *expr;
-	struct expression *op;
+	struct asm_operand *op;
 	struct symbol *sym;
 
 	expr = stmt->asm_string;
diff --git a/expand.c b/expand.c
index aba20b8cf..487a44943 100644
--- a/expand.c
+++ b/expand.c
@@ -1091,9 +1091,6 @@  static int expand_expression(struct expression *expr)
 	case EXPR_OFFSETOF:
 		expression_error(expr, "internal front-end error: sizeof in expansion?");
 		return UNSAFE;
-	case EXPR_ASM_OPERAND:
-		expression_error(expr, "internal front-end error: ASM_OPERAND in expansion?");
-		return UNSAFE;
 	}
 	return SIDE_EFFECTS;
 }
diff --git a/expression.h b/expression.h
index 13f35e64b..a06bfe130 100644
--- a/expression.h
+++ b/expression.h
@@ -64,7 +64,6 @@  enum expression_type {
 	EXPR_FVALUE,
 	EXPR_SLICE,
 	EXPR_OFFSETOF,
-	EXPR_ASM_OPERAND,
 };
 
 
@@ -136,6 +135,12 @@  enum {
 	Taint_comma = 1,
 }; /* for expr->taint */
 
+struct asm_operand {
+	struct ident *name;
+	struct expression *constraint;
+	struct expression *expr;
+};
+
 struct expression {
 	enum expression_type type:8;
 	unsigned flags:8;
@@ -235,12 +240,6 @@  struct expression {
 				struct expression *index;
 			};
 		};
-		// EXPR_ASM_OPERAND
-		struct {
-			struct ident *name;
-			struct expression *constraint;
-			struct expression *expr;
-		};
 	};
 };
 
diff --git a/inline.c b/inline.c
index fcc43db5c..6f73a3055 100644
--- a/inline.c
+++ b/inline.c
@@ -274,26 +274,24 @@  static struct expression * copy_expression(struct expression *expr)
 		}
 		break;
 	}
-	case EXPR_ASM_OPERAND: {
-		expr = dup_expression(expr);
-		expr->constraint = copy_expression(expr->constraint);
-		expr->expr = copy_expression(expr->expr);
-		break;
-	}
 	default:
 		warning(expr->pos, "trying to copy expression type %d", expr->type);
 	}
 	return expr;
 }
 
-static struct expression_list *copy_asm_constraints(struct expression_list *in)
+static struct asm_operand_list *copy_asm_operands(struct asm_operand_list *in)
 {
-	struct expression_list *out = NULL;
-	struct expression *expr;
-
-	FOR_EACH_PTR(in, expr) {
-		add_expression(&out, copy_expression(expr));
-	} END_FOR_EACH_PTR(expr);
+	struct asm_operand_list *out = NULL;
+	struct asm_operand *old;
+
+	FOR_EACH_PTR(in, old) {
+		struct asm_operand *new = __alloc_asm_operand(0);
+		new->name = old->name;
+		new->constraint = copy_expression(old->constraint);
+		new->expr = copy_expression(old->expr);
+		add_ptr_list(&out, new);
+	} END_FOR_EACH_PTR(old);
 	return out;
 }
 
@@ -445,8 +443,8 @@  static struct statement *copy_one_statement(struct statement *stmt)
 	}
 	case STMT_ASM: {
 		stmt = dup_statement(stmt);
-		stmt->asm_inputs = copy_asm_constraints(stmt->asm_inputs);
-		stmt->asm_outputs = copy_asm_constraints(stmt->asm_outputs);
+		stmt->asm_inputs = copy_asm_operands(stmt->asm_inputs);
+		stmt->asm_outputs = copy_asm_operands(stmt->asm_outputs);
 		/* no need to dup "clobbers", since they are all constant strings */
 		break;
 	}
diff --git a/lib.h b/lib.h
index 322408be3..697c977a1 100644
--- a/lib.h
+++ b/lib.h
@@ -67,6 +67,7 @@  struct ident;
 struct token;
 struct symbol;
 struct statement;
+struct asm_operand;
 struct expression;
 struct basic_block;
 struct entrypoint;
@@ -76,6 +77,7 @@  struct pseudo;
 
 DECLARE_PTR_LIST(symbol_list, struct symbol);
 DECLARE_PTR_LIST(statement_list, struct statement);
+DECLARE_PTR_LIST(asm_operand_list, struct asm_operand);
 DECLARE_PTR_LIST(expression_list, struct expression);
 DECLARE_PTR_LIST(basic_block_list, struct basic_block);
 DECLARE_PTR_LIST(instruction_list, struct instruction);
diff --git a/linearize.c b/linearize.c
index 415bf7e50..69f2dfe6b 100644
--- a/linearize.c
+++ b/linearize.c
@@ -2106,9 +2106,10 @@  static void add_asm_output(struct entrypoint *ep, struct instruction *insn, stru
 
 static pseudo_t linearize_asm_statement(struct entrypoint *ep, struct statement *stmt)
 {
-	struct expression *expr;
 	struct instruction *insn;
+	struct expression *expr;
 	struct asm_rules *rules;
+	struct asm_operand *op;
 	const char *constraint;
 
 	insn = alloc_instruction(OP_ASM, 0);
@@ -2123,18 +2124,18 @@  static pseudo_t linearize_asm_statement(struct entrypoint *ep, struct statement
 	insn->asm_rules = rules;
 
 	/* Gather the inputs.. */
-	FOR_EACH_PTR(stmt->asm_inputs, expr) {
-		constraint = expr->constraint ? expr->constraint->string->data : "";
-		add_asm_input(ep, insn, expr->expr, constraint, expr->name);
-	} END_FOR_EACH_PTR(expr);
+	FOR_EACH_PTR(stmt->asm_inputs, op) {
+		constraint = op->constraint ? op->constraint->string->data : "";
+		add_asm_input(ep, insn, op->expr, constraint, op->name);
+	} END_FOR_EACH_PTR(op);
 
 	add_one_insn(ep, insn);
 
 	/* Assign the outputs */
-	FOR_EACH_PTR(stmt->asm_outputs, expr) {
-		constraint = expr->constraint ? expr->constraint->string->data : "";
-		add_asm_output(ep, insn, expr->expr, constraint, expr->name);
-	} END_FOR_EACH_PTR(expr);
+	FOR_EACH_PTR(stmt->asm_outputs, op) {
+		constraint = op->constraint ? op->constraint->string->data : "";
+		add_asm_output(ep, insn, op->expr, constraint, op->name);
+	} END_FOR_EACH_PTR(op);
 
 	return VOID;
 }
diff --git a/parse.c b/parse.c
index 23c0ee012..d132a15a0 100644
--- a/parse.c
+++ b/parse.c
@@ -2037,13 +2037,13 @@  static struct token *expression_statement(struct token *token, struct expression
 }
 
 static struct token *parse_asm_operands(struct token *token, struct statement *stmt,
-	struct expression_list **inout)
+	struct asm_operand_list **inout)
 {
 	/* Allow empty operands */
 	if (match_op(token->next, ':') || match_op(token->next, ')'))
 		return token->next;
 	do {
-		struct expression *op = alloc_expression(token->pos, EXPR_ASM_OPERAND);
+		struct asm_operand *op = __alloc_asm_operand(0);
 		if (match_op(token->next, '[') &&
 		    token_type(token->next->next) == TOKEN_IDENT &&
 		    match_op(token->next->next->next, ']')) {
@@ -2053,7 +2053,7 @@  static struct token *parse_asm_operands(struct token *token, struct statement *s
 		token = token->next;
 		token = string_expression(token, &op->constraint, "asm constraint");
 		token = parens_expression(token, &op->expr, "in asm parameter");
-		add_expression(inout, op);
+		add_ptr_list(inout, op);
 	} while (match_op(token, ','));
 	return token;
 }
diff --git a/parse.h b/parse.h
index 505c91c2c..0742a2a87 100644
--- a/parse.h
+++ b/parse.h
@@ -106,8 +106,8 @@  struct statement {
 		};
 		struct /* asm */ {
 			struct expression *asm_string;
-			struct expression_list *asm_outputs;
-			struct expression_list *asm_inputs;
+			struct asm_operand_list *asm_outputs;
+			struct asm_operand_list *asm_inputs;
 			struct expression_list *asm_clobbers;
 			struct symbol_list *asm_labels;
 		};
diff --git a/show-parse.c b/show-parse.c
index 3aa06e47c..371041675 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -1185,9 +1185,6 @@  int show_expression(struct expression *expr)
 	case EXPR_TYPE:
 		warning(expr->pos, "unable to show type expression");
 		return 0;
-	case EXPR_ASM_OPERAND:
-		warning(expr->pos, "unable to show asm operand expression");
-		return 0;
 	}
 	return 0;
 }