mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
customTF is now down to 4989 pr_globals. all parameters, local veriables and
termporary variables sit in one pool of memory (at the end of the globals) thus drasticly reducing globals requirements. This works because the whole lot is declared to be in the function's local variable space which is copied to the locals stack in the progs engine.
This commit is contained in:
parent
a26f799de4
commit
bbb37d0080
5 changed files with 100 additions and 29 deletions
|
@ -275,15 +275,23 @@ typedef struct type_s
|
|||
struct type_s *parm_types[MAX_PARMS]; // only [num_parms] allocated
|
||||
} type_t;
|
||||
|
||||
typedef struct statref_s {
|
||||
struct statref_s *next;
|
||||
dstatement_t *statement;
|
||||
int field; // a, b, c (0, 1, 2)
|
||||
} statref_t;
|
||||
|
||||
typedef struct def_s
|
||||
{
|
||||
type_t *type;
|
||||
const char *name;
|
||||
struct def_s *next;
|
||||
int num_locals;
|
||||
struct def_s *scope_next; // to facilitate hash table removal
|
||||
gofs_t ofs;
|
||||
struct def_s *scope; // function the var was defined in, or NULL
|
||||
int initialized; // 1 when a declaration included "= immediate"
|
||||
statref_t *refs; // for relocations
|
||||
} def_t;
|
||||
|
||||
//============================================================================
|
||||
|
@ -332,6 +340,8 @@ extern def_t def_pointer;
|
|||
|
||||
struct function_s
|
||||
{
|
||||
struct function_s *next;
|
||||
dfunction_t *dfunc;
|
||||
int builtin; // if non 0, call an internal function
|
||||
int code; // first statement
|
||||
const char *file; // source file with definition
|
||||
|
@ -340,6 +350,7 @@ struct function_s
|
|||
int parm_ofs[MAX_PARMS]; // allways contiguous, right?
|
||||
};
|
||||
|
||||
function_t *pr_functions;
|
||||
|
||||
//
|
||||
// output generated by prog parsing
|
||||
|
@ -439,7 +450,7 @@ extern int pr_error_count;
|
|||
|
||||
void PR_NewLine (void);
|
||||
def_t *PR_GetDef (type_t *type, const char *name, def_t *scope,
|
||||
qboolean allocate);
|
||||
int *allocate);
|
||||
def_t *PR_NewDef (type_t *type, const char *name, def_t *scope);
|
||||
def_t *PR_GetTempDef (type_t *type, def_t *scope);
|
||||
void PR_FreeTempDefs ();
|
||||
|
@ -447,7 +458,7 @@ void PR_ResetTempDefs ();
|
|||
void PR_FlushScope (def_t *scope);
|
||||
|
||||
void PR_PrintDefs (void);
|
||||
|
||||
void PR_PrintFunction (def_t *def);
|
||||
void PR_SkipToSemicolon (void);
|
||||
|
||||
extern char pr_parm_names[MAX_PARMS][MAX_NAME];
|
||||
|
|
|
@ -457,7 +457,7 @@ PR_ParseState (void)
|
|||
PR_Expect (tt_punct, ",");
|
||||
|
||||
name = PR_ParseName ();
|
||||
def = PR_GetDef (&type_function, name, 0, true);
|
||||
def = PR_GetDef (&type_function, name, 0, &numpr_globals);
|
||||
|
||||
PR_Expect (tt_punct, "]");
|
||||
|
||||
|
@ -478,6 +478,9 @@ PR_ParseImmediateStatements (type_t *type)
|
|||
|
||||
f = malloc (sizeof (function_t));
|
||||
|
||||
f->next = pr_functions;
|
||||
pr_functions = f;
|
||||
|
||||
// check for builtin function definition #1, #2, etc
|
||||
if (PR_Check (tt_punct, "#")) {
|
||||
if (pr_token_type != tt_immediate
|
||||
|
@ -495,7 +498,7 @@ PR_ParseImmediateStatements (type_t *type)
|
|||
|
||||
// define the parms
|
||||
for (i = 0; i < type->num_parms; i++) {
|
||||
defs[i] = PR_GetDef (type->parm_types[i], pr_parm_names[i], pr_scope, true);
|
||||
defs[i] = PR_GetDef (type->parm_types[i], pr_parm_names[i], pr_scope, &pr_scope->num_locals);
|
||||
f->parm_ofs[i] = defs[i]->ofs;
|
||||
if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i - 1])
|
||||
Error ("bad parm order");
|
||||
|
@ -543,7 +546,7 @@ PR_ParseDefs (void)
|
|||
do {
|
||||
name = PR_ParseName ();
|
||||
|
||||
def = PR_GetDef (type, name, pr_scope, true);
|
||||
def = PR_GetDef (type, name, pr_scope, pr_scope ? &pr_scope->num_locals : &numpr_globals);
|
||||
|
||||
// check for an initialization
|
||||
if (PR_Check (tt_punct, "=")) {
|
||||
|
@ -563,17 +566,11 @@ PR_ParseDefs (void)
|
|||
|
||||
// if (pr_dumpasm)
|
||||
// PR_PrintFunction (def);
|
||||
//{
|
||||
// def_t *d;
|
||||
// printf ("%s\n", def->name);
|
||||
// for (d = def->scope_next; d; d = d->scope_next) {
|
||||
// printf ("%s: %d %d %d\n", d->name, d->ofs, d->type->type, type_size[d->type->type]);
|
||||
// }
|
||||
//}
|
||||
|
||||
// fill in the dfunction
|
||||
df = &functions[numfunctions];
|
||||
numfunctions++;
|
||||
f->dfunc = df;
|
||||
|
||||
if (f->builtin)
|
||||
df->first_statement = -f->builtin;
|
||||
|
@ -583,7 +580,7 @@ PR_ParseDefs (void)
|
|||
df->s_name = ReuseString (f->def->name);
|
||||
df->s_file = s_file;
|
||||
df->numparms = f->def->type->num_parms;
|
||||
df->locals = locals_end - locals_start;
|
||||
df->locals = f->def->num_locals;
|
||||
df->parm_start = locals_start;
|
||||
for (i = 0; i < df->numparms; i++)
|
||||
df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
|
||||
|
|
|
@ -51,7 +51,7 @@ defs_get_key (void *_def, void *_tab)
|
|||
If allocate is true, a new def will be allocated if it can't be found
|
||||
*/
|
||||
def_t *
|
||||
PR_GetDef (type_t *type, const char *name, def_t *scope, qboolean allocate)
|
||||
PR_GetDef (type_t *type, const char *name, def_t *scope, int *allocate)
|
||||
{
|
||||
def_t *def;
|
||||
char element[MAX_NAME];
|
||||
|
@ -77,8 +77,8 @@ PR_GetDef (type_t *type, const char *name, def_t *scope, qboolean allocate)
|
|||
def = PR_NewDef (type, name, scope);
|
||||
Hash_Add (defs_by_name, def);
|
||||
|
||||
def->ofs = numpr_globals;
|
||||
pr_global_defs[numpr_globals] = def;
|
||||
def->ofs = *allocate;
|
||||
pr_global_defs[*allocate] = def;
|
||||
|
||||
/*
|
||||
make automatic defs for the vectors elements
|
||||
|
@ -86,15 +86,15 @@ PR_GetDef (type_t *type, const char *name, def_t *scope, qboolean allocate)
|
|||
*/
|
||||
if (type->type == ev_vector) {
|
||||
sprintf (element, "%s_x", name);
|
||||
PR_GetDef (&type_float, element, scope, true);
|
||||
PR_GetDef (&type_float, element, scope, allocate);
|
||||
|
||||
sprintf (element, "%s_y", name);
|
||||
PR_GetDef (&type_float, element, scope, true);
|
||||
PR_GetDef (&type_float, element, scope, allocate);
|
||||
|
||||
sprintf (element, "%s_z", name);
|
||||
PR_GetDef (&type_float, element, scope, true);
|
||||
PR_GetDef (&type_float, element, scope, allocate);
|
||||
} else {
|
||||
numpr_globals += type_size[type->type];
|
||||
*allocate += type_size[type->type];
|
||||
}
|
||||
|
||||
if (type->type == ev_field) {
|
||||
|
@ -102,13 +102,13 @@ PR_GetDef (type_t *type, const char *name, def_t *scope, qboolean allocate)
|
|||
|
||||
if (type->aux_type->type == ev_vector) {
|
||||
sprintf (element, "%s_x", name);
|
||||
PR_GetDef (&type_floatfield, element, scope, true);
|
||||
PR_GetDef (&type_floatfield, element, scope, allocate);
|
||||
|
||||
sprintf (element, "%s_y", name);
|
||||
PR_GetDef (&type_floatfield, element, scope, true);
|
||||
PR_GetDef (&type_floatfield, element, scope, allocate);
|
||||
|
||||
sprintf (element, "%s_z", name);
|
||||
PR_GetDef (&type_floatfield, element, scope, true);
|
||||
PR_GetDef (&type_floatfield, element, scope, allocate);
|
||||
} else {
|
||||
pr.size_fields += type_size[type->aux_type->type];
|
||||
}
|
||||
|
@ -156,10 +156,8 @@ PR_GetTempDef (type_t *type, def_t *scope)
|
|||
def->type = type;
|
||||
} else {
|
||||
def = PR_NewDef (type, 0, scope);
|
||||
}
|
||||
if (!def->ofs) {
|
||||
def->ofs = numpr_globals;
|
||||
numpr_globals += type_size[size];
|
||||
def->ofs = scope->num_locals;
|
||||
scope->num_locals += type_size[size];
|
||||
}
|
||||
def->next = temp_scope.next;
|
||||
temp_scope.next = def;
|
||||
|
@ -187,7 +185,7 @@ PR_ResetTempDefs (void)
|
|||
int i;
|
||||
//def_t *d;
|
||||
|
||||
for (i = 0; i < ev_type_count; i++) {
|
||||
for (i = 0; i < sizeof (free_temps) / sizeof (free_temps[0]); i++) {
|
||||
free_temps[i] = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,18 @@ opcode_t pr_opcodes[] = {
|
|||
{"|", "BITOR", OP_BITOR, 2, false, &def_float, &def_float, &def_float},
|
||||
};
|
||||
|
||||
void
|
||||
PR_AddStatementRef (def_t *def, dstatement_t *st, int field)
|
||||
{
|
||||
if (def) {
|
||||
statref_t *ref = calloc (1, sizeof (statref_t));
|
||||
ref->next = def->refs;
|
||||
def->refs = ref;
|
||||
ref->statement = st;
|
||||
ref->field = field;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
PR_Statement
|
||||
|
||||
|
@ -157,6 +169,9 @@ PR_Statement (opcode_t * op, def_t * var_a, def_t * var_b)
|
|||
var_c = PR_GetTempDef (op->type_c->type, pr_scope);
|
||||
statement->c = var_c->ofs;
|
||||
}
|
||||
PR_AddStatementRef (var_a, statement, 0);
|
||||
PR_AddStatementRef (var_b, statement, 1);
|
||||
PR_AddStatementRef (var_c, statement, 2);
|
||||
|
||||
if (op->right_associative)
|
||||
return var_a;
|
||||
|
|
|
@ -611,6 +611,10 @@ PR_FinishCompilation (void)
|
|||
{
|
||||
def_t *d;
|
||||
qboolean errors = false;
|
||||
function_t *f;
|
||||
int num_locals = 0;
|
||||
def_t *def;
|
||||
statref_t *ref;
|
||||
|
||||
// check to make sure all functions prototyped have code
|
||||
for (d = pr.def_head.next; d; d = d->next) {
|
||||
|
@ -624,6 +628,35 @@ PR_FinishCompilation (void)
|
|||
}
|
||||
}
|
||||
|
||||
if (errors)
|
||||
return !errors;
|
||||
|
||||
for (f = pr_functions; f; f = f->next) {
|
||||
if (f->builtin)
|
||||
continue;
|
||||
if (f->def->num_locals > num_locals)
|
||||
num_locals = f->def->num_locals;
|
||||
f->dfunc->parm_start = numpr_globals;
|
||||
for (def = f->def->scope_next; def; def = def->scope_next) {
|
||||
for (ref = def->refs; ref; ref = ref->next) {
|
||||
switch (ref->field) {
|
||||
case 0:
|
||||
ref->statement->a += numpr_globals;
|
||||
break;
|
||||
case 1:
|
||||
ref->statement->b += numpr_globals;
|
||||
break;
|
||||
case 2:
|
||||
ref->statement->c += numpr_globals;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
numpr_globals += num_locals;
|
||||
|
||||
return !errors;
|
||||
}
|
||||
|
||||
|
@ -727,7 +760,7 @@ PR_WriteProgdefs (char *filename)
|
|||
|
||||
|
||||
void
|
||||
PrintFunction (char *name)
|
||||
PrintFunction (const char *name)
|
||||
{
|
||||
int i;
|
||||
dstatement_t *ds;
|
||||
|
@ -753,6 +786,23 @@ PrintFunction (char *name)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
PR_PrintFunction (def_t *def)
|
||||
{
|
||||
def_t *d;
|
||||
statref_t *r;
|
||||
|
||||
printf ("%s\n", def->name);
|
||||
for (d = def->scope_next; d; d = d->scope_next) {
|
||||
printf ("%s: %d %d %d\n",
|
||||
d->name ? d->name : "<temp>",
|
||||
d->ofs, d->type->type, type_size[d->type->type]);
|
||||
for (r = d->refs; r; r = r->next)
|
||||
printf (" %d", r->statement - statements);
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
|
Loading…
Reference in a new issue