structure copies now seem to work

This commit is contained in:
Bill Currie 2002-10-16 17:07:01 +00:00
parent be4b8096d4
commit 54564a4726
2 changed files with 61 additions and 10 deletions

View file

@ -208,13 +208,20 @@ emit_function_call (expr_t *e, def_t *dest)
for (earg = e->e.expr.e2; earg; earg = earg->next) {
ind--;
parm = def_parms[ind];
parm.type = types[extract_type (earg)];
parm.type = get_type (earg);
if (parm.type->type == ev_struct) {
expr_t *a = assign_expr (new_def_expr (&parm), earg);
a->line = e->line;
a->file = e->file;
emit_expr (a);
} else {
arg = emit_sub_expr (earg, &parm);
if (arg != &parm) {
op = opcode_find ("=", arg, &parm, &def_void);
emit_statement (e, op, arg, &parm, 0);
}
}
}
op = opcode_find (va ("<CALL%d>", count), &def_function, &def_void,
&def_void);
emit_statement (e, op, func, 0, 0);
@ -312,6 +319,28 @@ emit_bind_expr (expr_t *e1, expr_t *e2)
return e2->e.temp.def;
}
def_t *
emit_move_expr (expr_t *e)
{
expr_t *e1 = e->e.expr.e1;
expr_t *e2 = e->e.expr.e2;
def_t *size, *src, *dst;
type_t *type;
opcode_t *op;
src = emit_sub_expr (e2, 0);
dst = emit_sub_expr (e1, 0);
type = get_type (e1);
if (type->type == ev_struct) {
size = emit_sub_expr (new_short_expr (type_size (dst->type)), 0);
} else {
size = emit_sub_expr (new_integer_expr (type_size (type->aux_type)), 0);
}
op = opcode_find ("<MOVE>", src, size, dst);
return emit_statement (e, op, src, size, dst);
}
def_t *
emit_address_expr (expr_t *e)
{
@ -558,6 +587,9 @@ emit_expr (expr_t *e)
break;
case ex_expr:
switch (e->e.expr.op) {
case 'M':
emit_move_expr (e);
break;
case PAS:
case '=':
emit_assign_expr (e->e.expr.op, e);

View file

@ -2176,14 +2176,25 @@ assign_expr (expr_t *e1, expr_t *e2)
}
type = t1;
if (is_indirect (e1) && is_indirect (e2)) {
if (options.code.progsversion == PROG_ID_VERSION) {
expr_t *temp = new_temp_def_expr (t1);
e = new_block_expr ();
append_expr (e, assign_expr (temp, e2));
append_expr (e, assign_expr (e1, temp));
e->e.block.result = temp;
} else {
e1 = address_expr (e1, 0, 0);
e2 = address_expr (e2, 0, 0);
e = new_binary_expr ('M', e1, e2);
}
return e;
} else if (is_indirect (e1)) {
if (extract_type (e1) == ev_struct) {
e1 = address_expr (e1, 0, 0);
e2 = address_expr (e2, 0, 0);
return new_binary_expr ('M', e1, e2);
}
if (e1->type == ex_expr) {
if (get_type (e1->e.expr.e1) == &type_entity) {
type = e1->e.expr.type;
@ -2200,6 +2211,11 @@ assign_expr (expr_t *e1, expr_t *e2)
}
}
} else if (is_indirect (e2)) {
if (extract_type (e1) == ev_struct) {
e1 = address_expr (e1, 0, 0);
e2 = address_expr (e2, 0, 0);
return new_binary_expr ('M', e1, e2);
}
if (e2->type == ex_uexpr) {
e = e2->e.expr.e1;
if (e->type != ex_pointer
@ -2213,6 +2229,9 @@ assign_expr (expr_t *e1, expr_t *e2)
}
}
}
if (extract_type (e1) == ev_struct) {
return new_binary_expr ('M', e1, e2);
}
if (!type)
error (e1, "internal error");