Fix unary negation (-)
authorDale Weiler <weilercdale@gmail.com>
Mon, 28 Dec 2015 12:58:54 +0000 (07:58 -0500)
committerDale Weiler <weilercdale@gmail.com>
Mon, 28 Dec 2015 12:58:54 +0000 (07:58 -0500)
exec.c
include.mk
ir.c

diff --git a/exec.c b/exec.c
index 455a6c5..b24cda1 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -667,7 +667,7 @@ static qcvm_parameter *main_params = NULL;
     if (prog->argc != (num)) {                                                 \
         prog->vmerror++;                                                       \
         fprintf(stderr, "ERROR: invalid number of arguments for %s: %i, expected %i\n", \
-        __FUNCTION__, prog->argc, (num));                                      \
+        __func__, prog->argc, (num));                                      \
         return -1;                                                             \
     }                                                                          \
 } while (0)
index 1f90111..2a385a1 100644 (file)
@@ -6,7 +6,7 @@ DATADIR := $(PREFIX)/share
 MANDIR  := $(DATADIR)/man
 
 # default flags
-CFLAGS  += -Wall -Wextra -Werror -Wstrict-aliasing -Wno-attributes -O2
+CFLAGS  += -Wall -Wextra -Werror -Wstrict-aliasing -Wno-attributes -g3
 
 # compiler
 CC      ?= clang
diff --git a/ir.c b/ir.c
index 8d52898..73cbc9a 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -1917,6 +1917,9 @@ ir_value* ir_block_create_unary(ir_block *self, lex_ctx_t ctx,
                                 ir_value *operand)
 {
     int ot = TYPE_FLOAT;
+    ir_value *minus_1 = NULL;
+    if (opcode == VINSTR_NEG_F || opcode == VINSTR_NEG_V)
+        minus_1 = ir_builder_imm_float(self->owner->owner, -1.0f, false);
     switch (opcode) {
         case INSTR_NOT_F:
         case INSTR_NOT_V:
@@ -1926,15 +1929,11 @@ ir_value* ir_block_create_unary(ir_block *self, lex_ctx_t ctx,
         case INSTR_NOT_I:   */
             ot = TYPE_FLOAT;
             break;
-
-        /*
-         * Negation for virtual instructions is emulated with 0-value. Thankfully
-         * the operand for 0 already exists so we just source it from here.
-         */
+        /* Negation is implemented as -1 * <operand> */
         case VINSTR_NEG_F:
-            return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_F, NULL, operand, ot);
+            return ir_block_create_general_instr(self, ctx, label, INSTR_MUL_F, minus_1, operand, TYPE_FLOAT);
         case VINSTR_NEG_V:
-            return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_V, NULL, operand, TYPE_VECTOR);
+            return ir_block_create_general_instr(self, ctx, label, INSTR_MUL_FV, minus_1, operand, TYPE_VECTOR);
 
         default:
             ot = operand->vtype;