mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 06:51:47 +00:00
make chained structure assignments (mostly) work. found a bug in the
handling of pointer immediates which needs fixing before this will work in general
This commit is contained in:
parent
6ece3bc481
commit
7bb6dd7197
3 changed files with 37 additions and 12 deletions
|
@ -153,6 +153,7 @@ expr_t *new_short_expr (short short_val);
|
||||||
expr_t *new_bind_expr (expr_t *e1, expr_t *e2);
|
expr_t *new_bind_expr (expr_t *e1, expr_t *e2);
|
||||||
expr_t *new_self_expr (void);
|
expr_t *new_self_expr (void);
|
||||||
expr_t *new_this_expr (void);
|
expr_t *new_this_expr (void);
|
||||||
|
expr_t *new_move_expr (expr_t *e1, expr_t *e2, struct type_s *type);
|
||||||
|
|
||||||
void inc_users (expr_t *e);
|
void inc_users (expr_t *e);
|
||||||
void convert_name (expr_t *e);
|
void convert_name (expr_t *e);
|
||||||
|
|
|
@ -324,19 +324,32 @@ emit_move_expr (expr_t *e)
|
||||||
{
|
{
|
||||||
expr_t *e1 = e->e.expr.e1;
|
expr_t *e1 = e->e.expr.e1;
|
||||||
expr_t *e2 = e->e.expr.e2;
|
expr_t *e2 = e->e.expr.e2;
|
||||||
|
expr_t *size_expr;
|
||||||
def_t *size, *src, *dst;
|
def_t *size, *src, *dst;
|
||||||
type_t *type;
|
type_t *src_type, *dst_type;
|
||||||
opcode_t *op;
|
opcode_t *op;
|
||||||
|
|
||||||
|
dst_type = get_type (e1);
|
||||||
|
src_type = get_type (e2);
|
||||||
src = emit_sub_expr (e2, 0);
|
src = emit_sub_expr (e2, 0);
|
||||||
dst = emit_sub_expr (e1, 0);
|
dst = emit_sub_expr (e1, 0);
|
||||||
type = get_type (e1);
|
|
||||||
|
if (dst_type->type == ev_struct && src_type->type == ev_struct) {
|
||||||
if (type->type == ev_struct) {
|
printf("%s:%d\n", src->name, src->ofs);
|
||||||
size = emit_sub_expr (new_short_expr (type_size (dst->type)), 0);
|
size_expr = new_short_expr (type_size (dst->type));
|
||||||
|
} else if (dst_type->type == ev_struct) {
|
||||||
|
dst = emit_sub_expr (address_expr (new_def_expr (dst), 0, 0), 0);
|
||||||
|
size_expr = new_integer_expr (type_size (dst_type));
|
||||||
|
} else if (src_type->type == ev_struct) {
|
||||||
|
printf("%s:%d ", src->name, src->ofs);
|
||||||
|
src = emit_sub_expr (address_expr (new_def_expr (src), 0, 0), 0);
|
||||||
|
printf("%s:%d\n", src->name, src->ofs);
|
||||||
|
size_expr = new_integer_expr (type_size (dst_type->aux_type));
|
||||||
} else {
|
} else {
|
||||||
size = emit_sub_expr (new_integer_expr (type_size (type->aux_type)), 0);
|
size_expr = new_integer_expr (type_size (dst_type->aux_type));
|
||||||
}
|
}
|
||||||
|
size = emit_sub_expr (size_expr, 0);
|
||||||
|
|
||||||
op = opcode_find ("<MOVE>", src, size, dst);
|
op = opcode_find ("<MOVE>", src, size, dst);
|
||||||
return emit_statement (e, op, src, size, dst);
|
return emit_statement (e, op, src, size, dst);
|
||||||
}
|
}
|
||||||
|
@ -428,6 +441,10 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
||||||
error (e, "internal error");
|
error (e, "internal error");
|
||||||
abort ();
|
abort ();
|
||||||
case ex_expr:
|
case ex_expr:
|
||||||
|
if (e->e.expr.op == 'M') {
|
||||||
|
d = emit_move_expr (e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (e->e.expr.op == 'b') {
|
if (e->e.expr.op == 'b') {
|
||||||
d = emit_bind_expr (e->e.expr.e1, e->e.expr.e2);
|
d = emit_bind_expr (e->e.expr.e1, e->e.expr.e2);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -343,6 +343,7 @@ get_op_string (int op)
|
||||||
case 's': return "<state>";
|
case 's': return "<state>";
|
||||||
case 'c': return "<call>";
|
case 'c': return "<call>";
|
||||||
case 'C': return "<cast>";
|
case 'C': return "<cast>";
|
||||||
|
case 'M': return "<move>";
|
||||||
default:
|
default:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
@ -640,6 +641,14 @@ new_this_expr (void)
|
||||||
return new_def_expr (def);
|
return new_def_expr (def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_t *
|
||||||
|
new_move_expr (expr_t *e1, expr_t *e2, type_t *type)
|
||||||
|
{
|
||||||
|
expr_t *e = new_binary_expr ('M', e1, e2);
|
||||||
|
e->e.expr.type = type;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
expr_t *
|
expr_t *
|
||||||
append_expr (expr_t *block, expr_t *e)
|
append_expr (expr_t *block, expr_t *e)
|
||||||
{
|
{
|
||||||
|
@ -2179,7 +2188,7 @@ assign_expr (expr_t *e1, expr_t *e2)
|
||||||
if (extract_type (e2) == ev_struct) {
|
if (extract_type (e2) == ev_struct) {
|
||||||
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_binary_expr ('M', e1, e2);
|
e = new_move_expr (e1, e2, get_type (e2));
|
||||||
} else {
|
} else {
|
||||||
expr_t *temp = new_temp_def_expr (t1);
|
expr_t *temp = new_temp_def_expr (t1);
|
||||||
|
|
||||||
|
@ -2192,8 +2201,7 @@ assign_expr (expr_t *e1, expr_t *e2)
|
||||||
} else if (is_indirect (e1)) {
|
} else if (is_indirect (e1)) {
|
||||||
if (extract_type (e1) == ev_struct) {
|
if (extract_type (e1) == ev_struct) {
|
||||||
e1 = address_expr (e1, 0, 0);
|
e1 = address_expr (e1, 0, 0);
|
||||||
e2 = address_expr (e2, 0, 0);
|
return new_move_expr (e1, e2, get_type (e2));
|
||||||
return new_binary_expr ('M', e1, e2);
|
|
||||||
}
|
}
|
||||||
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) {
|
||||||
|
@ -2212,9 +2220,8 @@ assign_expr (expr_t *e1, expr_t *e2)
|
||||||
}
|
}
|
||||||
} else if (is_indirect (e2)) {
|
} else if (is_indirect (e2)) {
|
||||||
if (extract_type (e1) == ev_struct) {
|
if (extract_type (e1) == ev_struct) {
|
||||||
e1 = address_expr (e1, 0, 0);
|
|
||||||
e2 = address_expr (e2, 0, 0);
|
e2 = address_expr (e2, 0, 0);
|
||||||
return new_binary_expr ('M', e1, e2);
|
return new_move_expr (e1, e2, get_type (e2));
|
||||||
}
|
}
|
||||||
if (e2->type == ex_uexpr) {
|
if (e2->type == ex_uexpr) {
|
||||||
e = e2->e.expr.e1;
|
e = e2->e.expr.e1;
|
||||||
|
@ -2230,7 +2237,7 @@ assign_expr (expr_t *e1, expr_t *e2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (extract_type (e1) == ev_struct) {
|
if (extract_type (e1) == ev_struct) {
|
||||||
return new_binary_expr ('M', e1, e2);
|
return new_move_expr (e1, e2, get_type (e2));
|
||||||
}
|
}
|
||||||
if (!type)
|
if (!type)
|
||||||
error (e1, "internal error");
|
error (e1, "internal error");
|
||||||
|
|
Loading…
Reference in a new issue