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 */
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;
}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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');
+}