From 39278ba8cc926bba01d272addbc34c16ac354d82 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 9 Mar 2011 10:30:57 +0900 Subject: [PATCH] Explicitly select between direct and indirect moves. --- tools/qfcc/include/expr.h | 4 +++- tools/qfcc/source/constfold.c | 2 +- tools/qfcc/source/expr.c | 12 ++++++------ tools/qfcc/source/statements.c | 7 +++++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 7ca0ca251..e736229e6 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -516,9 +516,11 @@ expr_t *new_param_expr (struct type_s *type, int num); \param e1 Destination of move. \param e2 Source of move. \param type type giving size of move. + \param indirect Move uses dereferenced pointers. \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. diff --git a/tools/qfcc/source/constfold.c b/tools/qfcc/source/constfold.c index 485acc819..cff5df9dc 100644 --- a/tools/qfcc/source/constfold.c +++ b/tools/qfcc/source/constfold.c @@ -797,7 +797,7 @@ do_op_struct (int op, expr_t *e, expr_t *e1, expr_t *e2) { type_t *type; - if (op != '=' && op != 'M') + if (op != '=' && op != 'm') return error (e1, "invalid operand for struct"); if ((type = get_type (e1)) != get_type (e2)) return type_mismatch (e1, e2, op); diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 69c422550..36a0281d0 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -838,9 +838,9 @@ new_param_expr (type_t *type, int num) } 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; return e; } @@ -2505,7 +2505,7 @@ assign_expr (expr_t *e1, expr_t *e2) if (is_struct (get_type (e2))) { e1 = address_expr (e1, 0, 0); e2 = address_expr (e2, 0, 0); - e = new_move_expr (e1, e2, t2); + e = new_move_expr (e1, e2, t2, 1); } else { 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))) { e1 = address_expr (e1, 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 (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); e2 = address_expr (e2, 0, 0); e2->rvalue = 1; - return new_move_expr (e1, e2, t2); + return new_move_expr (e1, e2, t2, 1); } if (e2->type == ex_uexpr) { e = e2->e.expr.e1; @@ -2561,7 +2561,7 @@ assign_expr (expr_t *e1, expr_t *e2) } } 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) internal_error (e1, 0); diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index 76ee38335..006593279 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -250,7 +250,8 @@ convert_op (int op) case IFB: return ""; case IFAE: return ""; case IFA: return ""; - case 'M': return ""; + case 'm': return ""; + case 'M': return ""; default: return 0; } @@ -360,7 +361,7 @@ expr_move (sblock_t *sblock, expr_t *e, operand_t **op) dst = *op; sblock = statement_subexpr (sblock, src_expr, &src); sblock = statement_subexpr (sblock, size_expr, &size); - s = new_statement ("", e); + s = new_statement (convert_op (e->e.expr.op), e); s->opa = src; s->opb = size; s->opc = dst; @@ -547,6 +548,7 @@ expr_expr (sblock_t *sblock, expr_t *e, operand_t **op) case PAS: sblock = expr_assign (sblock, e, op); break; + case 'm': case 'M': sblock = expr_move (sblock, e, op); break; @@ -900,6 +902,7 @@ statement_expr (sblock_t *sblock, expr_t *e) case PAS: sblock = expr_assign (sblock, e, 0); break; + case 'm': case 'M': sblock = expr_move (sblock, e, 0); break;