From 571109481fa1f58b3f8bffb8d2bc81385b549b35 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Wed, 30 Sep 2015 12:35:19 -0700 Subject: [PATCH] Use cmpi in more cases Before this patch, only literals on the right side of a < compare (or left side of a > compare) would be blended into a %cmpi instruction. This patch broadends the cases where the %cmpi can be used. --- tgt-vvp/eval_condit.c | 58 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/tgt-vvp/eval_condit.c b/tgt-vvp/eval_condit.c index d4cd104a6..59c7a88c6 100644 --- a/tgt-vvp/eval_condit.c +++ b/tgt-vvp/eval_condit.c @@ -189,21 +189,48 @@ static int draw_condition_binary_le(ivl_expr_t expr) char use_opcode = ivl_expr_opcode(expr); char s_flag = (ivl_expr_signed(le) && ivl_expr_signed(re)) ? 's' : 'u'; - /* If this is a > or >=, then convert it to < or <= by - swapping the operands. Adjust the opcode to match. */ - switch (use_opcode) { - case 'G': + if (test_immediate_vec4_ok(le) && !test_immediate_vec4_ok(re)) { tmp = le; le = re; re = tmp; - use_opcode = 'L'; - break; - case '>': - tmp = le; - le = re; - re = tmp; - use_opcode = '<'; - break; + + switch (use_opcode) { + case 'G': + use_opcode = 'L'; + break; + case 'L': + use_opcode = 'G'; + break; + case '>': + use_opcode = '<'; + break; + case '<': + use_opcode = '>'; + break; + default: + assert(0); + break; + } + + } else if (!test_immediate_vec4_ok(re)) { + /* If this is a > or >=, then convert it to < or <= by + swapping the operands. Adjust the opcode to match. Do + this because the instruction really only supports < + and <= and we can avoid a %flag_inv instruction. */ + switch (use_opcode) { + case 'G': + tmp = le; + le = re; + re = tmp; + use_opcode = 'L'; + break; + case '>': + tmp = le; + le = re; + re = tmp; + use_opcode = '<'; + break; + } } /* NOTE: I think I would rather the elaborator handle the @@ -231,6 +258,13 @@ static int draw_condition_binary_le(ivl_expr_t expr) } switch (use_opcode) { + case '>': + fprintf(vvp_out, " %%flag_or 5, 4; GT is !LE\n"); + fprintf(vvp_out, " %%flag_inv 5;\n"); + return 5; + case 'G': + fprintf(vvp_out, " %%flag_inv 5; GE is !LT\n"); + return 5; case '<': return 5; case 'L':