]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
fix -fshort-logic to cast to true boolean values
authorWolfgang Bumiller <blub@speed.at>
Sat, 22 Dec 2012 19:05:15 +0000 (20:05 +0100)
committerWolfgang Bumiller <blub@speed.at>
Sat, 22 Dec 2012 19:05:15 +0000 (20:05 +0100)
ast.c
tests/correct-vs-short-1.tmpl [new file with mode: 0644]
tests/correct-vs-short-2.tmpl [new file with mode: 0644]
tests/correct-vs-short-3.tmpl [new file with mode: 0644]
tests/correct-vs-short.qc [new file with mode: 0644]

diff --git a/ast.c b/ast.c
index 2eb9faa72d868cdc52a65cd0e6139150d2c41a06..5dc131ea38bc617289aac9a5dae09d91985502d0 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1699,7 +1699,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
         return true;
     }
 
-    if (OPTS_FLAG(SHORT_LOGIC) &&
+    if ((OPTS_FLAG(SHORT_LOGIC) || OPTS_FLAG(PERL_LOGIC)) &&
         (self->op == INSTR_AND || self->op == INSTR_OR))
     {
         /* short circuit evaluation */
@@ -1750,12 +1750,50 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
         vec_push(func->ir_func->blocks, merge);
 
         func->curblock = merge;
-        phi = ir_block_create_phi(func->curblock, ast_ctx(self), ast_function_label(func, "sce_value"), TYPE_FLOAT);
+        phi = ir_block_create_phi(func->curblock, ast_ctx(self),
+                                  ast_function_label(func, "sce_value"),
+                                  self->expression.vtype);
         ir_phi_add(phi, from_left, left);
         ir_phi_add(phi, from_right, right);
         *out = ir_phi_value(phi);
         if (!*out)
             return false;
+
+        if (!OPTS_FLAG(PERL_LOGIC)) {
+            /* cast-to-bool */
+            if (OPTS_FLAG(CORRECT_LOGIC) && (*out)->vtype == TYPE_VECTOR) {
+                *out = ir_block_create_unary(func->curblock, ast_ctx(self),
+                                             ast_function_label(func, "sce_bool_v"),
+                                             INSTR_NOT_V, *out);
+                if (!*out)
+                    return false;
+                *out = ir_block_create_unary(func->curblock, ast_ctx(self),
+                                             ast_function_label(func, "sce_bool"),
+                                             INSTR_NOT_F, *out);
+                if (!*out)
+                    return false;
+            }
+            else if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && (*out)->vtype == TYPE_STRING) {
+                *out = ir_block_create_unary(func->curblock, ast_ctx(self),
+                                             ast_function_label(func, "sce_bool_s"),
+                                             INSTR_NOT_S, *out);
+                if (!*out)
+                    return false;
+                *out = ir_block_create_unary(func->curblock, ast_ctx(self),
+                                             ast_function_label(func, "sce_bool"),
+                                             INSTR_NOT_F, *out);
+                if (!*out)
+                    return false;
+            }
+            else {
+                *out = ir_block_create_binop(func->curblock, ast_ctx(self),
+                                             ast_function_label(func, "sce_bool"),
+                                             INSTR_AND, *out, *out);
+                if (!*out)
+                    return false;
+            }
+        }
+
         self->expression.outr = *out;
         return true;
     }
diff --git a/tests/correct-vs-short-1.tmpl b/tests/correct-vs-short-1.tmpl
new file mode 100644 (file)
index 0000000..9a2ac9b
--- /dev/null
@@ -0,0 +1,14 @@
+I: correct-vs-short.qc
+D: correct-logic vs short-logic without perl-logic
+T: -execute
+C: -std=fteqcc
+M: X               & | B
+M: 0 0 0, 0 0 0 :: 0 0 0
+M: 0 0 0, 5 0 0 :: 0 2 1
+M: 5 0 0, 0 0 0 :: 0 2 1
+M: 5 0 0, 5 0 0 :: 2 2 2
+M: Y               & | B
+M: 0 0 0, 0 0 0 :: 0 0 0
+M: 0 0 0, 0 5 0 :: 0 0 0
+M: 0 5 0, 0 0 0 :: 0 0 0
+M: 0 5 0, 0 5 0 :: 0 0 0
diff --git a/tests/correct-vs-short-2.tmpl b/tests/correct-vs-short-2.tmpl
new file mode 100644 (file)
index 0000000..09897e5
--- /dev/null
@@ -0,0 +1,14 @@
+I: correct-vs-short.qc
+D: correct-logic vs short-logic without perl-logic
+T: -execute
+C: -std=fteqcc -fcorrect-logic
+M: X               & | B
+M: 0 0 0, 0 0 0 :: 0 0 0
+M: 0 0 0, 5 0 0 :: 0 2 1
+M: 5 0 0, 0 0 0 :: 0 2 1
+M: 5 0 0, 5 0 0 :: 2 2 2
+M: Y               & | B
+M: 0 0 0, 0 0 0 :: 0 0 0
+M: 0 0 0, 0 5 0 :: 0 2 1
+M: 0 5 0, 0 0 0 :: 0 2 1
+M: 0 5 0, 0 5 0 :: 2 2 2
diff --git a/tests/correct-vs-short-3.tmpl b/tests/correct-vs-short-3.tmpl
new file mode 100644 (file)
index 0000000..787ae22
--- /dev/null
@@ -0,0 +1,14 @@
+I: correct-vs-short.qc
+D: correct-logic vs short-logic without perl-logic
+T: -execute
+C: -std=fteqcc -fcorrect-logic -fshort-logic
+M: X               & | B
+M: 0 0 0, 0 0 0 :: 0 0 0
+M: 0 0 0, 5 0 0 :: 0 2 1
+M: 5 0 0, 0 0 0 :: 0 2 1
+M: 5 0 0, 5 0 0 :: 2 2 2
+M: Y               & | B
+M: 0 0 0, 0 0 0 :: 0 0 0
+M: 0 0 0, 0 5 0 :: 0 2 1
+M: 0 5 0, 0 0 0 :: 0 2 1
+M: 0 5 0, 0 5 0 :: 2 2 2
diff --git a/tests/correct-vs-short.qc b/tests/correct-vs-short.qc
new file mode 100644 (file)
index 0000000..81f9b7a
--- /dev/null
@@ -0,0 +1,21 @@
+void   print(...)   = #1;
+string ftos (float) = #2;
+
+void test(vector a, vector b) {
+    print(ftos((a && b) + (a && b)), " ");
+    print(ftos((a || b) + (a || b)), " ");
+    print(ftos((a && b) + (a || b)), "\n");
+}
+
+void main() {
+    print("X               & | B\n");
+    print("0 0 0, 0 0 0 :: "); test('0 0 0', '0 0 0');
+    print("0 0 0, 5 0 0 :: "); test('0 0 0', '5 0 0');
+    print("5 0 0, 0 0 0 :: "); test('5 0 0', '0 0 0');
+    print("5 0 0, 5 0 0 :: "); test('5 0 0', '5 0 0');
+    print("Y               & | B\n");
+    print("0 0 0, 0 0 0 :: "); test('0 0 0', '0 0 0');
+    print("0 0 0, 0 5 0 :: "); test('0 0 0', '0 5 0');
+    print("0 5 0, 0 0 0 :: "); test('0 5 0', '0 0 0');
+    print("0 5 0, 0 5 0 :: "); test('0 5 0', '0 5 0');
+}