mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
structure copies now seem to work
This commit is contained in:
parent
be4b8096d4
commit
54564a4726
2 changed files with 61 additions and 10 deletions
|
@ -208,11 +208,18 @@ 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)];
|
||||
arg = emit_sub_expr (earg, &parm);
|
||||
if (arg != &parm) {
|
||||
op = opcode_find ("=", arg, &parm, &def_void);
|
||||
emit_statement (e, op, arg, &parm, 0);
|
||||
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,
|
||||
|
@ -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);
|
||||
|
|
|
@ -2176,14 +2176,25 @@ assign_expr (expr_t *e1, expr_t *e2)
|
|||
}
|
||||
type = t1;
|
||||
if (is_indirect (e1) && is_indirect (e2)) {
|
||||
expr_t *temp = new_temp_def_expr (t1);
|
||||
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;
|
||||
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");
|
||||
|
||||
|
|
Loading…
Reference in a new issue