mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[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:
parent
0d751dcdc5
commit
0d784d9ef4
2 changed files with 26 additions and 7 deletions
|
@ -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) {
|
||||
|
|
|
@ -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 == '&') {
|
||||
|
|
Loading…
Reference in a new issue