diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index 30c20bcd5..e6b58c0a3 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -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]; diff --git a/tools/qfcc/source/pr_comp.c b/tools/qfcc/source/pr_comp.c index 420c57804..754fa54ae 100644 --- a/tools/qfcc/source/pr_comp.c +++ b/tools/qfcc/source/pr_comp.c @@ -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]; diff --git a/tools/qfcc/source/pr_def.c b/tools/qfcc/source/pr_def.c index ea06d5c5b..6a8fc06ef 100644 --- a/tools/qfcc/source/pr_def.c +++ b/tools/qfcc/source/pr_def.c @@ -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; } } diff --git a/tools/qfcc/source/pr_opcode.c b/tools/qfcc/source/pr_opcode.c index a44ef0544..651c40d6e 100644 --- a/tools/qfcc/source/pr_opcode.c +++ b/tools/qfcc/source/pr_opcode.c @@ -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; diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 11f32d839..667572606 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -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 : "", + 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"); + } +} + //============================================================================