Allocate space for temp defs using size rather than type.

Statement operands throw away the high level type information, so store
type size in the operand and use this size for allocating space for temps
rather than using the low-level type.
This commit is contained in:
Bill Currie 2011-03-23 21:32:14 +09:00
parent 98f5f84ca3
commit 8d3508cf20
5 changed files with 48 additions and 31 deletions

View file

@ -76,6 +76,7 @@ extern storage_class_t current_storage;
def_t *new_def (const char *name, struct type_s *type,
struct defspace_s *space, storage_class_t storage);
def_t *alias_def (def_t *def, struct type_s *type);
def_t *temp_def (etype_t type, int size);
void free_def (def_t *def);
void def_to_ddef (def_t *def, ddef_t *ddef, int aux);

View file

@ -44,6 +44,7 @@ typedef struct operand_s {
struct operand_s *next;
op_type_e op_type;
etype_t type; ///< possibly override symbol's type
int size; ///< for structures
union {
struct symbol_s *symbol;
struct ex_value_s *value;

View file

@ -53,6 +53,7 @@ static __attribute__ ((used)) const char rcsid[] =
#include "diagnostic.h"
#include "emit.h"
#include "expr.h"
#include "function.h"
#include "options.h"
#include "reloc.h"
#include "strpool.h"
@ -142,12 +143,33 @@ alias_def (def_t *def, type_t *type)
def_t *alias;
ALLOC (16384, def_t, defs, alias);
alias->return_addr = __builtin_return_address (0);
alias->offset = def->offset;
alias->type = type;
alias->alias = def;
return alias;
}
def_t *
temp_def (etype_t type, int size)
{
def_t *temp;
defspace_t *space = current_func->symtab->space;
ALLOC (16384, def_t, defs, temp);
temp->return_addr = __builtin_return_address (0);
temp->name = save_string (va (".tmp%d", current_func->temp_num++));
temp->type = ev_types[type];
temp->file = pr.source_file;
temp->line = pr.source_line;
set_storage_bits (temp, st_local);
temp->offset = defspace_alloc_loc (space, size);
temp->space = space;
*space->def_tail = temp;
space->def_tail = &temp->next;
return temp;
}
void
free_def (def_t *def)
{

View file

@ -109,13 +109,8 @@ get_operand_def (expr_t *expr, operand_t *op)
zero_def.type = &type_short;
return &zero_def; //FIXME
case op_temp:
if (!op->o.def) {
const char *temp_name;
temp_name = va (".tmp%d", current_func->temp_num++);
op->o.def = new_def (temp_name, ev_types[op->type],
current_func->symtab->space, st_local);
}
if (!op->o.def)
op->o.def = temp_def (op->type, op->size);
return op->o.def;
case op_pointer:
def = op->o.pointer->def;

View file

@ -217,6 +217,16 @@ free_sblock (sblock_t *sblock)
free_sblocks = sblock;
}
static operand_t *
temp_operand (type_t *type)
{
operand_t *op = new_operand (op_temp);
op->type = low_level_type (type);
op->size = type_size (type);
return op;
}
static operand_t *
short_operand (short short_val)
{
@ -486,8 +496,7 @@ lea_statement (operand_t *pointer, operand_t *offset, expr_t *e)
statement_t *s = new_statement ("&", e);
s->opa = pointer;
s->opb = offset;
s->opc = new_operand (op_temp);
s->opc->type = ev_pointer;
s->opc = temp_operand (&type_pointer);
return s;
}
@ -496,8 +505,7 @@ address_statement (operand_t *value, expr_t *e)
{
statement_t *s = new_statement ("&", e);
s->opa = value;
s->opc = new_operand (op_temp);
s->opc->type = ev_pointer;
s->opc = temp_operand (&type_pointer);
return s;
}
@ -519,10 +527,8 @@ expr_deref (sblock_t *sblock, expr_t *deref, operand_t **op)
operand_t *offs = 0;
sblock = statement_subexpr (sblock, e->e.expr.e1, &ptr);
sblock = statement_subexpr (sblock, e->e.expr.e2, &offs);
if (!*op) {
*op = new_operand (op_temp);
(*op)->type = low_level_type (type);
}
if (!*op)
*op = temp_operand (type);
if (low_level_type (type) == ev_void) {
operand_t *src_addr;
operand_t *dst_addr;
@ -591,10 +597,8 @@ expr_expr (sblock_t *sblock, expr_t *e, operand_t **op)
s = new_statement (opcode, e);
sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
sblock = statement_subexpr (sblock, e->e.expr.e2, &s->opb);
if (!*op) {
*op = new_operand (op_temp);
(*op)->type = low_level_type (e->e.expr.type);
}
if (!*op)
*op = temp_operand (e->e.expr.type);
s->opc = *op;
sblock_add_statement (sblock, s);
break;
@ -621,10 +625,8 @@ expr_cast (sblock_t *sblock, expr_t *e, operand_t **op)
sblock = statement_subexpr (sblock, e->e.expr.e1, &src);
if ((src->type == ev_integer && type->type == ev_float)
|| (src->type == ev_float && type->type == ev_integer)) {
if (!*op) {
(*op) = new_operand (op_temp);
(*op)->type = low_level_type (e->e.expr.type);
}
if (!*op)
*op = temp_operand (e->e.expr.type);
s = new_statement ("=", e);
s->opa = src;
s->opc = *op;
@ -681,10 +683,8 @@ expr_uexpr (sblock_t *sblock, expr_t *e, operand_t **op)
internal_error (e, "ice ice baby");
s = new_statement (opcode, e);
sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
if (!*op) {
*op = new_operand (op_temp);
(*op)->type = low_level_type (e->e.expr.type);
}
if (!*op)
*op = temp_operand (e->e.expr.type);
s->opc = *op;
sblock_add_statement (sblock, s);
}
@ -703,10 +703,8 @@ expr_symbol (sblock_t *sblock, expr_t *e, operand_t **op)
static sblock_t *
expr_temp (sblock_t *sblock, expr_t *e, operand_t **op)
{
if (!e->e.temp.op) {
e->e.temp.op = new_operand (op_temp);
e->e.temp.op->type = low_level_type (e->e.temp.type);
}
if (!e->e.temp.op)
e->e.temp.op = temp_operand (e->e.temp.type);
*op = e->e.temp.op;
return sblock;
}