From 29cac0fe3aa52c80a9e5a9479f07e3093234dc30 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 7 Mar 2011 10:21:40 +0900 Subject: [PATCH] Optionally create *_[xyz] symbols for accessing vector components. "vector-components" in code options controls this feature. The default is off for advanced code and on for traditional code. Disabling vector-components prevents the comonent names polluting the namespace and reduces the number of globals needed for vector fields if the components of that field are never used. --- tools/qfcc/doc/man/qfcc.1 | 6 ++++++ tools/qfcc/include/options.h | 1 + tools/qfcc/source/def.c | 28 ++++++++++++++++++++++++++++ tools/qfcc/source/options.c | 10 +++++++++- 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/tools/qfcc/doc/man/qfcc.1 b/tools/qfcc/doc/man/qfcc.1 index 130580e7d..0e24df0cc 100644 --- a/tools/qfcc/doc/man/qfcc.1 +++ b/tools/qfcc/doc/man/qfcc.1 @@ -240,6 +240,12 @@ This can save a good number of pr_globals where those vectors contain many duplicate coordinates but do not match entirely. However, this will generate slower code for such calls. .TP +.B vector\-components +Create extra symbols for accessing the components of a vector variable or +field. For example, \fBvector vel\fP will also create \fBvel_x\fP, +\fBvel_y\fP, and \fBvel_z\fP. Defaults to on for traditional code and off +for advanced. +.TP .B v6only Restrict the compiler to only version 6 progs (original Quake/QuakeWorld) features. diff --git a/tools/qfcc/include/options.h b/tools/qfcc/include/options.h index fbc08a02f..935c15ba1 100644 --- a/tools/qfcc/include/options.h +++ b/tools/qfcc/include/options.h @@ -42,6 +42,7 @@ typedef struct { qboolean vector_calls; // use floats instead of vectors for constant function args qboolean local_merging; // merge function locals into one block unsigned progsversion; // Progs version to generate code for + qboolean vector_components; // add *_[xyz] symbols for vectors } code_options_t; typedef struct { diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index f83de77e8..a8a7974dc 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -283,6 +283,30 @@ init_elements (struct def_s *def, expr_t *eles) free (elements); } +static void +init_vector_components (symbol_t *vector_sym, int is_field) +{ + expr_t *vector_expr; + expr_t *expr; + symbol_t *sym; + int i; + static const char *fields[] = { "x", "y", "z" }; + + vector_expr = new_symbol_expr (vector_sym); + for (i = 0; i < 3; i++) { + if (is_field) { + expr = new_field_expr (i, &type_float, vector_sym->s.def); + } else { + expr = binary_expr ('.', vector_expr, + new_symbol_expr (new_symbol (fields[i]))); + } + sym = new_symbol (va ("%s_%s", vector_sym->name, fields[i])); + sym->sy_type = sy_expr; + sym->s.expr = expr; + symtab_addsymbol (current_symtab, sym); + } +} + static void init_field_def (def_t *def) { @@ -298,6 +322,8 @@ init_field_def (def_t *def) reloc_def_field (def, field_def); def->constant = 1; def->nosave = 1; + if (type == &type_vector && options.code.vector_components) + init_vector_components (field_sym, 1); } void @@ -348,6 +374,8 @@ initialize_def (symbol_t *sym, type_t *type, expr_t *init, defspace_t *space, } if (!sym->s.def) sym->s.def = new_def (sym->name, type, space, storage); + if (type == &type_vector && options.code.vector_components) + init_vector_components (sym, 0); if (storage == st_extern) { if (init) warning (0, "initializing external variable"); diff --git a/tools/qfcc/source/options.c b/tools/qfcc/source/options.c index e174e5cdf..c7cb912e9 100644 --- a/tools/qfcc/source/options.c +++ b/tools/qfcc/source/options.c @@ -61,7 +61,7 @@ static int files_size; // keep me sane when adding long options :P enum { - start_opts = 255, // not used, just for starting the enum. + start_opts = 255, // not used, starts the enum. OPT_ADVANCED, OPT_CPP, OPT_INCLUDE, @@ -192,6 +192,7 @@ code_usage (void) " [no-]vector-calls Generate slower but data efficient code for\n" " passing\n" " vectors to functiosn.\n" +" [no-]vector-components Create *_[xyz] symbols for vector variables.\n" " [no-]v6only Restrict output code to version 6 progs\n" " features.\n" "\n" @@ -270,6 +271,7 @@ DecodeArgs (int argc, char **argv) options.code.short_circuit = -1; options.code.local_merging = -1; + options.code.vector_components = -1; options.code.fast_float = true; options.warnings.uninited_variable = true; options.warnings.unused = true; @@ -391,6 +393,8 @@ DecodeArgs (int argc, char **argv) options.single_cpp = flag; } else if (!(strcasecmp (temp, "vector-calls"))) { options.code.vector_calls = flag; + } else if (!(strcasecmp (temp, "vector-components"))) { + options.code.vector_components = flag; } else if (!(strcasecmp (temp, "v6only"))) { if (flag) options.code.progsversion = PROG_ID_VERSION; @@ -555,6 +559,8 @@ DecodeArgs (int argc, char **argv) options.code.short_circuit = false; if (options.code.local_merging == (qboolean) -1) options.code.local_merging = false; + if (options.code.vector_components == (qboolean) -1) + options.code.vector_components = true; } if (!options.code.progsversion) options.code.progsversion = PROG_VERSION; @@ -566,6 +572,8 @@ DecodeArgs (int argc, char **argv) options.code.short_circuit = true; if (options.code.local_merging == (qboolean) -1) options.code.local_merging = true; + if (options.code.vector_components == (qboolean) -1) + options.code.vector_components = false; } if (options.code.progsversion == PROG_ID_VERSION) add_cpp_def ("-D__VERSION6__=1");