Explicitly select between direct and indirect moves.

This commit is contained in:
Bill Currie 2011-03-09 10:30:57 +09:00
parent 90de6b0499
commit 39278ba8cc
4 changed files with 15 additions and 10 deletions

View file

@ -516,9 +516,11 @@ expr_t *new_param_expr (struct type_s *type, int num);
\param e1 Destination of move. \param e1 Destination of move.
\param e2 Source of move. \param e2 Source of move.
\param type type giving size of move. \param type type giving size of move.
\param indirect Move uses dereferenced pointers.
\return A new expression representing the move. \return A new expression representing the move.
*/ */
expr_t *new_move_expr (expr_t *e1, expr_t *e2, struct type_s *type); expr_t *new_move_expr (expr_t *e1, expr_t *e2, struct type_s *type,
int indirect);
/** Convert a name to an expression of the appropriate type. /** Convert a name to an expression of the appropriate type.

View file

@ -797,7 +797,7 @@ do_op_struct (int op, expr_t *e, expr_t *e1, expr_t *e2)
{ {
type_t *type; type_t *type;
if (op != '=' && op != 'M') if (op != '=' && op != 'm')
return error (e1, "invalid operand for struct"); return error (e1, "invalid operand for struct");
if ((type = get_type (e1)) != get_type (e2)) if ((type = get_type (e1)) != get_type (e2))
return type_mismatch (e1, e2, op); return type_mismatch (e1, e2, op);

View file

@ -838,9 +838,9 @@ new_param_expr (type_t *type, int num)
} }
expr_t * expr_t *
new_move_expr (expr_t *e1, expr_t *e2, type_t *type) new_move_expr (expr_t *e1, expr_t *e2, type_t *type, int indirect)
{ {
expr_t *e = new_binary_expr ('M', e1, e2); expr_t *e = new_binary_expr (indirect ? 'M' : 'm', e1, e2);
e->e.expr.type = type; e->e.expr.type = type;
return e; return e;
} }
@ -2505,7 +2505,7 @@ assign_expr (expr_t *e1, expr_t *e2)
if (is_struct (get_type (e2))) { if (is_struct (get_type (e2))) {
e1 = address_expr (e1, 0, 0); e1 = address_expr (e1, 0, 0);
e2 = address_expr (e2, 0, 0); e2 = address_expr (e2, 0, 0);
e = new_move_expr (e1, e2, t2); e = new_move_expr (e1, e2, t2, 1);
} else { } else {
expr_t *temp = new_temp_def_expr (t1); expr_t *temp = new_temp_def_expr (t1);
@ -2519,7 +2519,7 @@ assign_expr (expr_t *e1, expr_t *e2)
if (is_struct (get_type (e1))) { if (is_struct (get_type (e1))) {
e1 = address_expr (e1, 0, 0); e1 = address_expr (e1, 0, 0);
e2 = address_expr (e2, 0, 0); e2 = address_expr (e2, 0, 0);
return new_move_expr (e1, e2, get_type (e2)); return new_move_expr (e1, e2, get_type (e2), 1);
} }
if (e1->type == ex_expr) { if (e1->type == ex_expr) {
if (get_type (e1->e.expr.e1) == &type_entity) { if (get_type (e1->e.expr.e1) == &type_entity) {
@ -2542,7 +2542,7 @@ assign_expr (expr_t *e1, expr_t *e2)
e1 = address_expr (e1, 0, 0); e1 = address_expr (e1, 0, 0);
e2 = address_expr (e2, 0, 0); e2 = address_expr (e2, 0, 0);
e2->rvalue = 1; e2->rvalue = 1;
return new_move_expr (e1, e2, t2); return new_move_expr (e1, e2, t2, 1);
} }
if (e2->type == ex_uexpr) { if (e2->type == ex_uexpr) {
e = e2->e.expr.e1; e = e2->e.expr.e1;
@ -2561,7 +2561,7 @@ assign_expr (expr_t *e1, expr_t *e2)
} }
} }
if (is_struct (get_type (e1))) { if (is_struct (get_type (e1))) {
return new_move_expr (e1, e2, get_type (e2)); return new_move_expr (e1, e2, get_type (e2), 0);
} }
if (!type) if (!type)
internal_error (e1, 0); internal_error (e1, 0);

View file

@ -250,7 +250,8 @@ convert_op (int op)
case IFB: return "<IFB>"; case IFB: return "<IFB>";
case IFAE: return "<IFAE>"; case IFAE: return "<IFAE>";
case IFA: return "<IFA>"; case IFA: return "<IFA>";
case 'M': return "<MOVE>"; case 'm': return "<MOVE>";
case 'M': return "<MOVEP>";
default: default:
return 0; return 0;
} }
@ -360,7 +361,7 @@ expr_move (sblock_t *sblock, expr_t *e, operand_t **op)
dst = *op; dst = *op;
sblock = statement_subexpr (sblock, src_expr, &src); sblock = statement_subexpr (sblock, src_expr, &src);
sblock = statement_subexpr (sblock, size_expr, &size); sblock = statement_subexpr (sblock, size_expr, &size);
s = new_statement ("<MOVE>", e); s = new_statement (convert_op (e->e.expr.op), e);
s->opa = src; s->opa = src;
s->opb = size; s->opb = size;
s->opc = dst; s->opc = dst;
@ -547,6 +548,7 @@ expr_expr (sblock_t *sblock, expr_t *e, operand_t **op)
case PAS: case PAS:
sblock = expr_assign (sblock, e, op); sblock = expr_assign (sblock, e, op);
break; break;
case 'm':
case 'M': case 'M':
sblock = expr_move (sblock, e, op); sblock = expr_move (sblock, e, op);
break; break;
@ -900,6 +902,7 @@ statement_expr (sblock_t *sblock, expr_t *e)
case PAS: case PAS:
sblock = expr_assign (sblock, e, 0); sblock = expr_assign (sblock, e, 0);
break; break;
case 'm':
case 'M': case 'M':
sblock = expr_move (sblock, e, 0); sblock = expr_move (sblock, e, 0);
break; break;