mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-23 03:01:30 +00:00
Some things. Fix testsuite as well. One test will fail (inexact).
This commit is contained in:
parent
bbeb2517c0
commit
05e20bcdda
4 changed files with 29 additions and 21 deletions
37
fold.c
37
fold.c
|
@ -48,11 +48,11 @@ typedef union {
|
|||
} sfloat_cast_t;
|
||||
|
||||
typedef enum {
|
||||
SFLOAT_INVALID = 1 << 0,
|
||||
SFLOAT_DIVBYZERO = 1 << 1,
|
||||
SFLOAT_OVERFLOW = 1 << 2,
|
||||
SFLOAT_UNDERFLOW = 1 << 3,
|
||||
SFLOAT_INEXACT = 1 << 4
|
||||
SFLOAT_INVALID = 1,
|
||||
SFLOAT_DIVBYZERO = 4,
|
||||
SFLOAT_OVERFLOW = 8,
|
||||
SFLOAT_UNDERFLOW = 16,
|
||||
SFLOAT_INEXACT = 32
|
||||
} sfloat_exceptionflags_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -692,6 +692,7 @@ ast_expression *fold_constgen_float(fold_t *fold, qcfloat_t value, bool inexact)
|
|||
out->hasvalue = true;
|
||||
out->inexact = inexact;
|
||||
out->constval.vfloat = value;
|
||||
(void)inexact;
|
||||
|
||||
vec_push(fold->imm_float, out);
|
||||
|
||||
|
@ -820,7 +821,7 @@ static bool fold_check_except_float(sfloat_t (*callback)(sfloat_state_t *, sfloa
|
|||
sfloat_cast_t ca;
|
||||
sfloat_cast_t cb;
|
||||
|
||||
if (!OPTS_FLAG(ARITHMETIC_EXCEPTIONS))
|
||||
if (!OPTS_FLAG(ARITHMETIC_EXCEPTIONS) && !OPTS_WARN(WARN_INEXACT_COMPARES))
|
||||
return false;
|
||||
|
||||
s.roundingmode = SFLOAT_ROUND_NEAREST_EVEN;
|
||||
|
@ -833,27 +834,26 @@ static bool fold_check_except_float(sfloat_t (*callback)(sfloat_state_t *, sfloa
|
|||
if (s.exceptionflags == 0)
|
||||
return false;
|
||||
|
||||
if (!OPTS_FLAG(ARITHMETIC_EXCEPTIONS))
|
||||
goto inexact_possible;
|
||||
|
||||
if (s.exceptionflags & SFLOAT_DIVBYZERO)
|
||||
compile_error(fold_ctx(fold), "division by zero");
|
||||
#if 0
|
||||
/*
|
||||
* To be enabled once softfloat implementations for stuff like sqrt()
|
||||
* exist
|
||||
*/
|
||||
if (s.exceptionflags & SFLOAT_INVALID)
|
||||
compile_error(fold_ctx(fold), "invalid argument");
|
||||
#endif
|
||||
|
||||
compile_error(fold_ctx(fold), "undefined (inf)");
|
||||
if (s.exceptionflags & SFLOAT_OVERFLOW)
|
||||
compile_error(fold_ctx(fold), "arithmetic overflow");
|
||||
if (s.exceptionflags & SFLOAT_UNDERFLOW)
|
||||
compile_error(fold_ctx(fold), "arithmetic underflow");
|
||||
|
||||
return s.exceptionflags == SFLOAT_INEXACT;
|
||||
inexact_possible:
|
||||
return s.exceptionflags & SFLOAT_INEXACT;
|
||||
}
|
||||
|
||||
static bool fold_check_inexact_float(fold_t *fold, ast_value *a, ast_value *b) {
|
||||
lex_ctx_t ctx = fold_ctx(fold);
|
||||
if (!OPTS_WARN(WARN_INEXACT_COMPARES))
|
||||
return false;
|
||||
if (!a->inexact && !b->inexact)
|
||||
return false;
|
||||
return compile_warning(ctx, WARN_INEXACT_COMPARES, "inexact value in comparison");
|
||||
|
@ -923,7 +923,11 @@ static GMQCC_INLINE ast_expression *fold_op_div(fold_t *fold, ast_value *a, ast_
|
|||
if (isfloat(a)) {
|
||||
if (fold_can_2(a, b)) {
|
||||
bool inexact = fold_check_except_float(&sfloat_div, fold, a, b);
|
||||
return fold_constgen_float(fold, fold_immvalue_float(a) / fold_immvalue_float(b), inexact);
|
||||
ast_expression *e;
|
||||
con_out("inexact: %d (%x:%x)\n", inexact, a, b);
|
||||
e = fold_constgen_float(fold, fold_immvalue_float(a) / fold_immvalue_float(b), inexact);
|
||||
con_out("%x\n", e);
|
||||
return e;
|
||||
} else if (fold_can_1(b)) {
|
||||
return (ast_expression*)ast_binary_new(
|
||||
fold_ctx(fold),
|
||||
|
@ -1079,6 +1083,7 @@ static GMQCC_INLINE ast_expression *fold_op_cmp(fold_t *fold, ast_value *a, ast_
|
|||
if (isfloat(a) && isfloat(b)) {
|
||||
float la = fold_immvalue_float(a);
|
||||
float lb = fold_immvalue_float(b);
|
||||
con_out("CMP: %x:%x\n", a, b);
|
||||
fold_check_inexact_float(fold, a, b);
|
||||
return (ast_expression*)fold->imm_float[!(ne ? la == lb : la != lb)];
|
||||
} if (isvector(a) && isvector(b)) {
|
||||
|
|
5
test.c
5
test.c
|
@ -1100,6 +1100,7 @@ static size_t task_schedualize(size_t *pad) {
|
|||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
size_t failed = 0;
|
||||
int status = 0;
|
||||
|
||||
util_snprintf(space[0], sizeof(space[0]), "%d", (int)vec_size(task_tasks));
|
||||
|
||||
|
@ -1167,7 +1168,9 @@ static size_t task_schedualize(size_t *pad) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (task_pclose(task_tasks[i].runhandles) != EXIT_SUCCESS && strcmp(task_tasks[i].tmpl->proceduretype, "-fail")) {
|
||||
status = task_pclose(task_tasks[i].runhandles);
|
||||
if ((!strcmp(task_tasks[i].tmpl->proceduretype, "-fail") && status == EXIT_SUCCESS)
|
||||
|| ( strcmp(task_tasks[i].tmpl->proceduretype, "-fail") && status == EXIT_FAILURE)) {
|
||||
con_out("failure: `%s` %*s %*s\n",
|
||||
task_tasks[i].tmpl->description,
|
||||
(pad[0] + pad[1] - strlen(task_tasks[i].tmpl->description)) + (strlen(task_tasks[i].tmpl->rulesfile) - pad[1]),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const float huge = 340282346638528859811704183484516925440; // FLT_MAX
|
||||
const float huge = 340282346638528859811704183484516925440.000000; // FLT_MAX
|
||||
|
||||
#ifdef DIVBYZERO
|
||||
const float a = 1.0 / 0.0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
void main() {
|
||||
const float a = 1.0 / 3.0;
|
||||
const float b = 0.3333333333333;
|
||||
const float a = 1.0 / 3.0;
|
||||
const float b = 0.33333333333;
|
||||
|
||||
void main() {
|
||||
if (a == b) {
|
||||
// Should trigger warning
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue