general revamp so params and the return value use proper defs rather than

hardcoded locations. this will allow use of quaternions in the future.
This commit is contained in:
Bill Currie 2003-04-22 15:29:32 +00:00
parent 47d4fec5ec
commit 2f6fc5d80c
13 changed files with 199 additions and 83 deletions

View file

@ -65,6 +65,7 @@ typedef struct def_s {
struct scope_s *scope; // scope the var was defined in
struct defspace_s *space;
struct def_s *parent; // vector/quaternion member
struct def_s *alias; // def for which this is an alias
int obj_def; // index to def in qfo defs
@ -105,7 +106,6 @@ typedef enum {
st_local
} storage_class_t;
extern def_t def_ret, def_parms[MAX_PARMS];
extern def_t def_void;
extern def_t def_function;

View file

@ -155,6 +155,8 @@ expr_t *constant_expr (expr_t *var);
expr_t *new_bind_expr (expr_t *e1, expr_t *e2);
expr_t *new_self_expr (void);
expr_t *new_this_expr (void);
expr_t *new_ret_expr (struct type_s *type);
expr_t *new_param_expr (struct type_s *type, int num);
expr_t *new_move_expr (expr_t *e1, expr_t *e2, struct type_s *type);
void inc_users (expr_t *e);

View file

@ -45,10 +45,10 @@ extern struct opcode_s *op_goto;
extern struct opcode_s *op_jump;
extern struct opcode_s *op_jumpb;
struct def_s;
struct type_s;
struct opcode_s *opcode_find (const char *name, struct def_s *var_a,
struct def_s *var_b, struct def_s *var_c);
struct opcode_s *opcode_find (const char *name, struct type_s *type_a,
struct type_s *type_b, struct type_s *type_c);
void opcode_init (void);
#endif//__opcodes_h

View file

@ -73,6 +73,8 @@ extern type_t *type_category;
extern type_t *type_ivar;
extern type_t *type_module;
extern type_t type_va_list;
extern type_t *type_param;
extern type_t *type_zero;
extern type_t *vector_struct;

View file

@ -65,8 +65,6 @@ typedef struct locref_s {
def_t def_void = { &type_void, "def void" };
def_t def_function = { &type_function, "def function" };
def_t def_ret, def_parms[MAX_PARMS];
static def_t *free_temps[4]; // indexted by type size
static def_t temp_scope;
static def_t *free_defs;

View file

@ -102,6 +102,9 @@ add_statement_ref (def_t *def, dstatement_t *st, reloc_type type)
if (def) {
reloc_t *ref = new_reloc (st - pr.code->code, type);
if (def->alias)
def = def->alias;
ref->next = def->refs;
def->refs = ref;
@ -118,7 +121,7 @@ emit_statement (expr_t *e, opcode_t *op, def_t *var_a, def_t *var_b,
def_t *ret;
if (!op) {
error (e, "ice ice baby\n");
error (e, "ice ice baby");
abort ();
}
if (options.code.debug) {
@ -197,7 +200,8 @@ static def_t *
emit_function_call (expr_t *e, def_t *dest)
{
def_t *func = emit_sub_expr (e->e.expr.e1, 0);
def_t parm;
def_t *parm;
def_t *ret;
def_t *arg;
expr_t *earg;
opcode_t *op;
@ -208,32 +212,31 @@ emit_function_call (expr_t *e, def_t *dest)
ind = count;
for (earg = e->e.expr.e2; earg; earg = earg->next) {
ind--;
parm = def_parms[ind];
parm.type = get_type (earg);
if (parm.type->type == ev_struct) {
expr_t *a = assign_expr (new_def_expr (&parm), earg);
parm = emit_sub_expr (new_param_expr (get_type (earg), ind), 0);
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);
arg = emit_sub_expr (earg, parm);
if (arg != parm) {
op = opcode_find ("=", arg->type, arg->type, &type_void);
emit_statement (e, op, arg, parm, 0);
}
}
}
op = opcode_find (va ("<CALL%d>", count), &def_function, &def_void,
&def_void);
op = opcode_find (va ("<CALL%d>", count), &type_function, &type_void,
&type_void);
emit_statement (e, op, func, 0, 0);
def_ret.type = func->type->aux_type;
ret = emit_sub_expr (new_ret_expr (func->type->aux_type), 0);
if (dest) {
op = opcode_find ("=", dest, &def_ret, &def_void);
emit_statement (e, op, &def_ret, dest, 0);
op = opcode_find ("=", dest->type, ret->type, &type_void);
emit_statement (e, op, ret, dest, 0);
return dest;
} else {
return &def_ret;
return ret;
}
}
@ -273,7 +276,7 @@ emit_assign_expr (int oper, expr_t *e)
}
def_b = emit_sub_expr (e2, def_a);
if (def_b != def_a) {
op = opcode_find (operator, def_b, def_a, &def_void);
op = opcode_find (operator, def_b->type, def_a->type, &type_void);
emit_statement (e, op, def_b, def_a, 0);
}
return def_a;
@ -285,11 +288,11 @@ emit_assign_expr (int oper, expr_t *e)
&& e1->e.expr.e1->type < ex_string) {
def_a = emit_sub_expr (e1->e.expr.e1, 0);
def_c = emit_sub_expr (e1->e.expr.e2, 0);
op = opcode_find (operator, def_b, def_a, def_c);
op = opcode_find (operator, def_b->type, def_a->type, def_c->type);
} else {
def_a = emit_sub_expr (e1, 0);
def_c = 0;
op = opcode_find (operator, def_b, def_a, &def_void);
op = opcode_find (operator, def_b->type, def_a->type, &type_void);
}
emit_statement (e, op, def_b, def_a, def_c);
return def_b;
@ -348,7 +351,7 @@ emit_move_expr (expr_t *e)
}
size = emit_sub_expr (size_expr, 0);
op = opcode_find ("<MOVE>", src, size, dst);
op = opcode_find ("<MOVE>", src->type, size->type, dst->type);
return emit_statement (e, op, src, size, dst);
}
@ -360,7 +363,7 @@ emit_address_expr (expr_t *e)
def_a = emit_sub_expr (e->e.expr.e1, 0);
def_b = emit_sub_expr (e->e.expr.e2, 0);
op = opcode_find ("&", def_a, def_b, 0);
op = opcode_find ("&", def_a->type, def_b->type, 0);
d = emit_statement (e, op, def_a, def_b, 0);
return d;
}
@ -375,19 +378,21 @@ emit_deref_expr (expr_t *e, def_t *dest)
e = e->e.expr.e1;
if (e->type == ex_pointer) {
if (e->e.pointer.val >= 0 && e->e.pointer.val < 65536) {
if (e->e.pointer.def) {
d = new_def (e->e.pointer.type, 0, current_scope);
d->local = e->e.pointer.def->local;
d->ofs = e->e.pointer.def->ofs;
d->alias = e->e.pointer.def;
} else if (e->e.pointer.val >= 0 && e->e.pointer.val < 65536) {
d = new_def (e->e.pointer.type, 0, current_scope);
d->ofs = e->e.pointer.val;
} else {
d = ReuseConstant (e, 0);
zero.type = ex_short;
z = emit_sub_expr (&zero, 0);
op = opcode_find (".", d, z, dest);
op = opcode_find (".", d->type, z->type, dest->type);
d = emit_statement (e, op, d, z, dest);
}
if (e->e.pointer.def) {
d->local = e->e.pointer.def->local;
}
return d;
}
if (!dest && (e->type != ex_pointer
@ -406,7 +411,7 @@ emit_deref_expr (expr_t *e, def_t *dest)
if (dest && d != dest) {
zero.type = ex_short;
z = emit_sub_expr (&zero, 0);
op = opcode_find (".", d, z, dest);
op = opcode_find (".", d->type, z->type, dest->type);
d = emit_statement (e, op, d, z, dest);
} else {
if (!d->name)
@ -474,7 +479,8 @@ emit_sub_expr (expr_t *e, def_t *dest)
dest = get_tempdef (e->e.expr.type, current_scope);
dest->users += 2;
}
op = opcode_find (operator, def_a, def_b, dest);
op = opcode_find (operator, def_a->type, def_b->type,
e->e.expr.type);
d = emit_statement (e, op, def_a, def_b, dest);
break;
case ex_uexpr:
@ -538,7 +544,8 @@ emit_sub_expr (expr_t *e, def_t *dest)
default:
abort ();
}
op = opcode_find (operator, def_a, def_b, dest);
op = opcode_find (operator, def_a->type, def_b->type,
dest ? dest->type : 0);
d = emit_statement (e, op, def_a, def_b, dest);
break;
case ex_def:

View file

@ -668,6 +668,29 @@ new_this_expr (void)
return new_def_expr (def);
}
static expr_t *
param_expr (const char *name, type_t *type)
{
def_t *def = get_def (type_param, name, pr.scope, st_extern);;
expr_t *def_expr;
def_initialized (def);
def_expr = new_def_expr (def);
return unary_expr ('.', address_expr (def_expr, 0, type));
}
expr_t *
new_ret_expr (type_t *type)
{
return param_expr (".return", type);
}
expr_t *
new_param_expr (type_t *type, int num)
{
return param_expr (va (".param_%d", num), type);
}
expr_t *
new_move_expr (expr_t *e1, expr_t *e2, type_t *type)
{
@ -1436,7 +1459,7 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
if (e1->type == ex_block && e1->e.block.is_call
&& e2->type == ex_block && e2->e.block.is_call && e1->e.block.result) {
e = new_temp_def_expr (e1->e.block.result->e.def->type);
e = new_temp_def_expr (get_type (e1->e.block.result));
inc_users (e); // for the block itself
e1 = assign_expr (e, e1);
}
@ -1950,10 +1973,7 @@ function_expr (expr_t *e1, expr_t *e2)
e->e.expr.type = ftype->aux_type;
append_expr (call, e);
if (ftype->aux_type != &type_void) {
expr_t *ret = new_def_expr (new_def (ftype->aux_type, 0, 0));
ret->e.def->ofs = def_ret.ofs;
call->e.block.result = ret;
call->e.block.result = new_ret_expr (ftype->aux_type);
}
return call;
}
@ -2490,7 +2510,7 @@ message_expr (expr_t *receiver, keywordarg_t *message)
if (call->type == ex_error)
return receiver;
call->e.block.result->e.def->type = rec_type;
call->e.block.result = new_ret_expr (rec_type);
return call;
}

View file

@ -229,6 +229,8 @@ WriteProgdefs (const char *filename)
break;
if (!d->ofs)
continue;
if (!d->name || *d->name == '.' || !*d->name)
continue;
switch (d->type->type) {
case ev_float:

View file

@ -221,6 +221,16 @@ ReuseConstant (expr_t *expr, def_t *def)
}
memcpy (&search.i, &e.e, sizeof (search.i));
imm = (immediate_t *) Hash_FindElement (tab, &search);
if (imm && strcmp (imm->def->name, ".zero") == 0) {
if (def) {
imm = 0; //FIXME do full def aliasing
} else {
expr_t *e = new_def_expr (imm->def);
e = address_expr (e, 0, type);
e = unary_expr ('.', e);
return emit_sub_expr (e, 0);
}
}
if (imm) {
cn = imm->def;
if (def) {
@ -335,8 +345,7 @@ clear_immediates (void)
}
imm = calloc (1, sizeof (immediate_t));
imm->def = new_def (&type_void, ".imm", pr.scope);
imm->def->initialized = imm->def->constant = 1;
imm->def = get_def (type_zero, ".zero", pr.scope, st_extern);
Hash_AddElement (string_imm_defs, imm);
Hash_AddElement (float_imm_defs, imm);

View file

@ -89,6 +89,26 @@ typedef union defref_s {
union defref_s *next;
} defref_t;
typedef struct builtin_sym_s {
const char *name;
etype_t basic_type;
const char *full_type;
int size;
} builtin_sym_t;
static builtin_sym_t builtin_symbols[] = {
{".zero", ev_struct, "{-*fEFv(v)^viI}", 1},
{".return", ev_struct, "{-*fVEFv(v)^viI}", 3},
{".param_0", ev_struct, "{-*fVEFv(v)^viI}", 3},
{".param_1", ev_struct, "{-*fVEFv(v)^viI}", 3},
{".param_2", ev_struct, "{-*fVEFv(v)^viI}", 3},
{".param_3", ev_struct, "{-*fVEFv(v)^viI}", 3},
{".param_4", ev_struct, "{-*fVEFv(v)^viI}", 3},
{".param_5", ev_struct, "{-*fVEFv(v)^viI}", 3},
{".param_6", ev_struct, "{-*fVEFv(v)^viI}", 3},
{".param_7", ev_struct, "{-*fVEFv(v)^viI}", 3},
};
static defref_t *free_defrefs;
static hashtab_t *extern_defs;
@ -272,8 +292,16 @@ process_def (qfo_def_t *def)
if (!def->num_relocs)
return;
if ((_d = Hash_Find (defined_defs, STRING (def->name)))) {
def->ofs = deref_def (_d, &global_defs)->ofs;
def->flags = deref_def (_d, &global_defs)->flags;
d = deref_def (_d, &global_defs);
if (d->full_type != def->full_type) {
def_error (def, "type mismatch `%s' `%s'",
TYPE_STRING (def->full_type),
TYPE_STRING (d->full_type));
def_error (d, "previous definition");
return;
}
def->ofs = d->ofs;
def->flags = d->flags;
Hash_Add (defined_defs, get_defref (def, &global_defs));
} else {
Hash_Add (extern_defs, get_defref (def, &global_defs));
@ -628,12 +656,13 @@ merge_defgroups (void)
}
static void
define_def (const char *name, etype_t basic_type, const char *full_type, int v)
define_def (const char *name, etype_t basic_type, const char *full_type,
int size, int v)
{
qfo_def_t d;
pr_type_t val;
pr_type_t *val = calloc (size, sizeof (pr_type_t));
val.integer_var = v;
val->integer_var = v;
memset (&d, 0, sizeof (d));
d.basic_type = basic_type;
@ -645,7 +674,7 @@ define_def (const char *name, etype_t basic_type, const char *full_type, int v)
d.relocs = relocs.num_relocs;
d.num_relocs = 1;
}
defspace_adddata (data, &val, 1);
defspace_adddata (data, val, size);
defgroup_add_defs (&global_defs, &d, 1);
process_def (global_defs.defs + global_defs.num_defs - 1);
if (basic_type == ev_field) {
@ -655,11 +684,14 @@ define_def (const char *name, etype_t basic_type, const char *full_type, int v)
relocgroup_add_relocs (&relocs, &rel, 1);
process_field (def);
}
free (val);
}
void
linker_begin (void)
{
size_t i;
extern_defs = Hash_NewTable (16381, defs_get_key, 0, &global_defs);
defined_defs = Hash_NewTable (16381, defs_get_key, 0, &global_defs);
field_defs = Hash_NewTable (16381, defs_get_key, 0, &fields);
@ -671,6 +703,15 @@ linker_begin (void)
type_strings = strpool_new ();
pr.strings = strings;
if (!options.partial_link) {
for (i = 0;
i < sizeof (builtin_symbols) / sizeof (builtin_symbols[0]);
i++) {
define_def (builtin_symbols[i].name, builtin_symbols[i].basic_type,
builtin_symbols[i].full_type, builtin_symbols[i].size,
0);
}
}
}
static void
@ -806,11 +847,11 @@ linker_finish (void)
if (d->basic_type == ev_entity)
def_warning (d, "@self and self used together");
}
define_def (".self", ev_entity, "E", 0);
define_def (".self", ev_entity, "E", 1, 0);
did_self = 1;
} else if (strcmp (name, ".this") == 0 && !did_this) {
entity_base = 0;
define_def (".this", ev_field, "F@", entity->size);
define_def (".this", ev_field, "F@", 1, entity->size);
defspace_adddata (entity, 0, 1);
did_this = 1;
}

View file

@ -108,20 +108,20 @@ compare (void *_opa, void *_opb, void *_tab)
}
opcode_t *
opcode_find (const char *name, def_t *var_a, def_t *var_b, def_t *var_c)
opcode_find (const char *name, type_t *type_a, type_t *type_b, type_t *type_c)
{
opcode_t op;
hashtab_t **tab;
op.name = name;
if (var_a && var_b && var_c) {
op.type_a = var_a->type->type;
op.type_b = var_b->type->type;
op.type_c = var_c->type->type;
if (type_a && type_b && type_c) {
op.type_a = type_a->type;
op.type_b = type_b->type;
op.type_c = type_c->type;
tab = &opcode_type_table_abc;
} else if (var_a && var_b) {
op.type_a = var_a->type->type;
op.type_b = var_b->type->type;
} else if (type_a && type_b) {
op.type_a = type_a->type;
op.type_b = type_b->type;
tab = &opcode_type_table_ab;
} else {
tab = 0;

View file

@ -140,8 +140,6 @@ fix_backslash (char *path)
static void
InitData (void)
{
int i;
if (pr.code) {
codespace_delete (pr.code);
strpool_delete (pr.strings);
@ -163,10 +161,6 @@ InitData (void)
numglobaldefs = 1;
numfielddefs = 1;
def_ret.ofs = OFS_RETURN;
for (i = 0; i < MAX_PARMS; i++)
def_parms[i].ofs = OFS_PARM0 + 3 * i;
}
@ -186,6 +180,8 @@ WriteData (int crc)
for (def = pr.scope->head; def; def = def->def_next) {
if (def->local || !def->name)
continue;
if (options.traditional && *def->name == '.')
continue;
if (def->type->type == ev_func) {
} else if (def->type->type == ev_field) {
dd = &fields[numfielddefs++];
@ -342,16 +338,29 @@ WriteData (int crc)
return 0;
}
static void
begin_compilation (void)
{
pr.near_data->size = RESERVED_OFS;
pr.func_tail = &pr.func_head;
pr.error_count = 0;
}
static void
setup_param_block (void)
{
def_initialized (get_def (type_zero, ".zero", pr.scope, st_global));
def_initialized (get_def (type_param, ".return", pr.scope, st_global));
def_initialized (get_def (type_param, ".param_0", pr.scope, st_global));
def_initialized (get_def (type_param, ".param_1", pr.scope, st_global));
def_initialized (get_def (type_param, ".param_2", pr.scope, st_global));
def_initialized (get_def (type_param, ".param_3", pr.scope, st_global));
def_initialized (get_def (type_param, ".param_4", pr.scope, st_global));
def_initialized (get_def (type_param, ".param_5", pr.scope, st_global));
def_initialized (get_def (type_param, ".param_6", pr.scope, st_global));
def_initialized (get_def (type_param, ".param_7", pr.scope, st_global));
}
static qboolean
finish_compilation (void)
{
@ -670,6 +679,9 @@ progs_src_compile (void)
begin_compilation ();
if (!options.compile)
setup_param_block ();
// compile all the files
while ((src = COM_Parse (src))) {
int err;

View file

@ -92,6 +92,8 @@ type_t *type_category;
type_t *type_ivar;
type_t *type_module;
type_t type_va_list;
type_t *type_param;
type_t *type_zero;
type_t *vector_struct;
@ -367,7 +369,11 @@ _encode_type (dstring_t *encoding, type_t *type, int level)
dstring_appendstr (encoding, type->class->name);
}
if (level < 2) {
dstring_appendstr (encoding, "=");
if (type->type == ev_struct
&& ((struct_t *)type->class)->is_union)
dstring_appendstr (encoding, "-");
else
dstring_appendstr (encoding, "=");
for (field = type->struct_head; field; field = field->next)
_encode_type (encoding, field->type, level + 1);
}
@ -449,7 +455,7 @@ _parse_type (const char **str)
case '{':
new.type = ev_struct;
name = dstring_newstr ();
for (s = *str; *s && *s != '=' && *s !='}'; s++)
for (s = *str; *s && *s != '=' && *s != '-' && *s !='}'; s++)
;
if (!*s)
return 0;
@ -459,7 +465,7 @@ _parse_type (const char **str)
new.aux_type = find_struct (name->str);
if (new.aux_type) {
dstring_delete (name);
if (**str == '=') {
if (**str == '=' || **str == '-') {
(*str)++;
while (**str && **str != '}')
_parse_type (str);
@ -469,13 +475,15 @@ _parse_type (const char **str)
(*str)++;
return new.aux_type;
}
if (**str != '=') {
if (**str != '=' && **str != '-') {
dstring_delete (name);
return 0;
}
(*str)++;
new.aux_type = new_struct (*name->str ? name->str : 0);
if (**str == '-')
((struct_t *) new.aux_type->class)->is_union = 1;
dstring_delete (name);
(*str)++;
while (**str && **str != '}')
new_struct_field (new.aux_type, _parse_type (str), 0,
vis_public);
@ -586,6 +594,27 @@ init_types (void)
{
type_t *type;
type = type_zero = new_union (0);
new_struct_field (type, &type_string, "string_val", vis_public);
new_struct_field (type, &type_float, "float_val", vis_public);
new_struct_field (type, &type_entity, "entity_val", vis_public);
new_struct_field (type, &type_field, "field_val", vis_public);
new_struct_field (type, &type_function, "func_val", vis_public);
new_struct_field (type, &type_pointer, "pointer_val", vis_public);
new_struct_field (type, &type_integer, "integer_val", vis_public);
new_struct_field (type, &type_uinteger, "uinteger_val", vis_public);
type = type_param = new_union (0);
new_struct_field (type, &type_string, "string_val", vis_public);
new_struct_field (type, &type_float, "float_val", vis_public);
new_struct_field (type, &type_vector, "vector_val", vis_public);
new_struct_field (type, &type_entity, "entity_val", vis_public);
new_struct_field (type, &type_field, "field_val", vis_public);
new_struct_field (type, &type_function, "func_val", vis_public);
new_struct_field (type, &type_pointer, "pointer_val", vis_public);
new_struct_field (type, &type_integer, "integer_val", vis_public);
new_struct_field (type, &type_uinteger, "uinteger_val", vis_public);
if (options.traditional)
return;
@ -651,17 +680,8 @@ init_types (void)
init_struct (malloc (sizeof (struct_t)), &type_va_list, 0);
new_struct_field (&type_va_list, &type_integer, "count", vis_public);
type = new_union (0);
new_struct_field (type, &type_string, "string_val", vis_public);
new_struct_field (type, &type_float, "float_val", vis_public);
new_struct_field (type, &type_vector, "vector_val", vis_public);
new_struct_field (type, &type_entity, "entity_val", vis_public);
new_struct_field (type, &type_field, "field_val", vis_public);
new_struct_field (type, &type_function, "func_val", vis_public);
new_struct_field (type, &type_pointer, "pointer_val", vis_public);
new_struct_field (type, &type_integer, "integer_val", vis_public);
new_struct_field (type, &type_uinteger, "uinteger_val", vis_public);
new_struct_field (&type_va_list, pointer_type (type), "list", vis_public);
new_struct_field (&type_va_list, pointer_type (type_param), "list",
vis_public);
#if 0
type = type_module = new_struct ("obj_module_t");
new_struct_field (type, &type_integer, "version", vis_public);
@ -684,6 +704,9 @@ chain_initial_types (void)
chain_type (&type_pointer);
chain_type (&type_floatfield);
chain_type (type_param);
chain_type (type_zero);
if (options.traditional)
return;