[qfcc] Rework address expr calculation

This removes a bogus lea from the instruction stream (and there can be
many such).
This commit is contained in:
Bill Currie 2020-03-17 12:13:09 +09:00
parent 0d751dcdc5
commit 0d784d9ef4
2 changed files with 26 additions and 7 deletions

View file

@ -296,8 +296,9 @@ zero_memory (expr_t *local_expr, def_t *def, type_t *zero_type,
expr_t *dst;
for (; init_offset < init_size + 1 - zero_size; init_offset += zero_size) {
dst = new_pointer_expr (init_offset, zero_type, def);
append_expr (local_expr, assign_expr (unary_expr ('.', dst), zero));
dst = new_def_expr (def);
dst = new_offset_alias_expr (zero_type, dst, init_offset);
append_expr (local_expr, assign_expr (dst, zero));
}
return init_offset;
}
@ -355,8 +356,8 @@ init_elements (struct def_s *def, expr_t *eles)
build_element_chain (&element_chain, def->type, eles, 0);
if (def->local && local_expr) {
expr_t *ptr = new_pointer_expr (0, def->type, def);
assign_elements (local_expr, pointer_expr (ptr), &element_chain);
expr_t *dst = new_def_expr (def);
assign_elements (local_expr, dst, &element_chain);
} else {
def_t dummy = *def;
for (element = element_chain.head; element; element = element->next) {

View file

@ -2256,6 +2256,22 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
t = get_type (e1);
switch (e1->type) {
case ex_def:
{
def_t *def = e1->e.def;
type_t *type = def->type;
if (is_array (type)) {
e = e1;
e->type = ex_value;
e->e.value = new_pointer_val (0, t, def, 0);
} else {
e = new_pointer_expr (0, t, def);
e->line = e1->line;
e->file = e1->file;
}
}
break;
case ex_symbol:
if (e1->e.symbol->sy_type == sy_var) {
def_t *def = e1->e.symbol->s.def;
@ -2328,9 +2344,11 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
if (e2) {
if (e2->type == ex_error)
return e2;
if (e->type == ex_value && e->e.value->lltype == ev_pointer
&& is_short_val (e2)) {
e->e.value = new_pointer_val (e->e.value->v.pointer.val + expr_short (e2), t, e->e.value->v.pointer.def, 0);
if (is_pointer_val (e) && is_integral_val (e2)) {
int base = e->e.value->v.pointer.val;
int offset = expr_integral (e2);
def_t *def = e->e.value->v.pointer.def;
e->e.value = new_pointer_val (base + offset, t, def, 0);
} else {
if (!is_short_val (e2) || expr_short (e2)) {
if (e->type == ex_expr && e->e.expr.op == '&') {