mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-16 17:01:53 +00:00
[qfcc] Make the meaning of vec * vec selectable
Currently only via pragma (not command line options), but I needed to test the concept. Converting legacy code is just too error prone. Telling the compiler how to treat the operator makes more sense. When * acts as @dot with Ruamoko progs, the result is automatically aliased as a float as this is the legacy meaning (ie, float result for dot product).
This commit is contained in:
parent
ff08ef3fa3
commit
5f6e0767d7
5 changed files with 57 additions and 3 deletions
|
@ -49,6 +49,10 @@ typedef struct {
|
|||
qboolean promote_float; // promote float through ...
|
||||
} code_options_t;
|
||||
|
||||
typedef struct {
|
||||
int vector_mult; // operation for vector * vector
|
||||
} math_options_t;
|
||||
|
||||
typedef struct {
|
||||
qboolean promote; // Promote warnings to errors
|
||||
qboolean cow; // Warn on copy-on-write detection
|
||||
|
@ -93,6 +97,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
code_options_t code; // Code generation options
|
||||
math_options_t math; // Various math options
|
||||
warn_options_t warnings; // Warning options
|
||||
notice_options_t notices; // Notice options
|
||||
bug_options_t bug; // Bug options
|
||||
|
|
|
@ -745,9 +745,15 @@ vector_compare (int op, expr_t *e1, expr_t *e2)
|
|||
static expr_t *vector_multiply (int op, expr_t *e1, expr_t *e2)
|
||||
{
|
||||
expr_t *e = new_binary_expr ('*', e1, e2);
|
||||
if (options.code.progsversion < PROG_VERSION) {
|
||||
if (options.math.vector_mult == DOT) {
|
||||
// vector * vector is dot product in v6 progs (ick)
|
||||
e->e.expr.type = &type_float;
|
||||
e->e.expr.op = DOT;
|
||||
if (options.code.progsversion == PROG_VERSION) {
|
||||
e->e.expr.type = &type_vector;
|
||||
e = new_alias_expr (&type_float, e);
|
||||
} else {
|
||||
e->e.expr.type = &type_float;
|
||||
}
|
||||
} else {
|
||||
// component-wise multiplication
|
||||
e->e.expr.type = &type_vector;
|
||||
|
|
|
@ -51,6 +51,9 @@
|
|||
#include "tools/qfcc/include/options.h"
|
||||
#include "tools/qfcc/include/qfcc.h"
|
||||
#include "tools/qfcc/include/strpool.h"
|
||||
#include "tools/qfcc/include/type.h"
|
||||
|
||||
#include "tools/qfcc/source/qc-parse.h"
|
||||
|
||||
const char *this_program;
|
||||
const char **source_files;
|
||||
|
@ -720,6 +723,8 @@ DecodeArgs (int argc, char **argv)
|
|||
options.code.local_merging = false;
|
||||
if (options.code.vector_components == (qboolean) -1)
|
||||
options.code.vector_components = true;
|
||||
if (options.math.vector_mult == 0)
|
||||
options.math.vector_mult = DOT;
|
||||
}
|
||||
if (!options.code.progsversion)
|
||||
options.code.progsversion = PROG_VERSION;
|
||||
|
@ -736,6 +741,8 @@ DecodeArgs (int argc, char **argv)
|
|||
options.code.local_merging = true;
|
||||
if (options.code.vector_components == (qboolean) -1)
|
||||
options.code.vector_components = false;
|
||||
if (options.math.vector_mult == 0)
|
||||
options.math.vector_mult = options.advanced == 1 ? DOT : '*';
|
||||
} else {
|
||||
options.code.promote_float = 0;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
#include "tools/qfcc/include/strpool.h"
|
||||
#include "tools/qfcc/include/type.h"
|
||||
|
||||
#include "tools/qfcc/source/qc-parse.h"
|
||||
|
||||
typedef struct pragma_arg_s {
|
||||
struct pragma_arg_s *next;
|
||||
const char *arg;
|
||||
|
@ -139,7 +141,7 @@ static void
|
|||
set_optimize (pragma_arg_t *args)
|
||||
{
|
||||
if (!args) {
|
||||
warning (0, "missing warn flag");
|
||||
warning (0, "missing optimize flag");
|
||||
return;
|
||||
}
|
||||
const char *flag = args->arg;
|
||||
|
@ -153,6 +155,37 @@ set_optimize (pragma_arg_t *args)
|
|||
}
|
||||
}
|
||||
|
||||
static pragma_arg_t *
|
||||
set_vector_mult (pragma_arg_t *args)
|
||||
{
|
||||
if (!args) {
|
||||
warning (0, "missing vector_mult arg");
|
||||
return args;
|
||||
}
|
||||
const char *op = args->arg;
|
||||
if (!strcmp (op, "@dot")) {
|
||||
options.math.vector_mult = DOT;
|
||||
} else {
|
||||
warning (0, "unknown vector_mult arg: %s", op);
|
||||
}
|
||||
return args->next;
|
||||
}
|
||||
|
||||
static void
|
||||
set_math (pragma_arg_t *args)
|
||||
{
|
||||
if (!args) {
|
||||
warning (0, "missing math arg");
|
||||
return;
|
||||
}
|
||||
while (args) {
|
||||
const char *a = args->arg;
|
||||
if (!strcmp (a, "vector_mult")) {
|
||||
args = set_vector_mult (args->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pragma_process ()
|
||||
{
|
||||
|
@ -175,6 +208,8 @@ pragma_process ()
|
|||
set_warn (pragma_args->next);
|
||||
} else if (!strcmp (id, "optimize")) {
|
||||
set_optimize (pragma_args->next);
|
||||
} else if (!strcmp (id, "math")) {
|
||||
set_math (pragma_args->next);
|
||||
} else {
|
||||
warning (0, "unknown pragma: '%s'", id);
|
||||
}
|
||||
|
|
|
@ -284,6 +284,7 @@ STRING \"(\\.|[^"\\])*\"
|
|||
BEGIN (GRAB_OTHER); // ignore rest of line
|
||||
}
|
||||
<PRAGMA>{ID} { pragma_add_arg (yytext); }
|
||||
<PRAGMA>@{ID} { pragma_add_arg (yytext); }
|
||||
|
||||
<*>\r*\n {
|
||||
if (YY_START == PRAGMA) {
|
||||
|
|
Loading…
Reference in a new issue