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.
This commit is contained in:
Stephen Williams 2015-09-30 12:35:19 -07:00
parent 81f54ec0cb
commit 571109481f
1 changed files with 46 additions and 12 deletions

View File

@ -189,21 +189,48 @@ static int draw_condition_binary_le(ivl_expr_t expr)
char use_opcode = ivl_expr_opcode(expr); char use_opcode = ivl_expr_opcode(expr);
char s_flag = (ivl_expr_signed(le) && ivl_expr_signed(re)) ? 's' : 'u'; char s_flag = (ivl_expr_signed(le) && ivl_expr_signed(re)) ? 's' : 'u';
/* If this is a > or >=, then convert it to < or <= by if (test_immediate_vec4_ok(le) && !test_immediate_vec4_ok(re)) {
swapping the operands. Adjust the opcode to match. */
switch (use_opcode) {
case 'G':
tmp = le; tmp = le;
le = re; le = re;
re = tmp; re = tmp;
use_opcode = 'L';
break; switch (use_opcode) {
case '>': case 'G':
tmp = le; use_opcode = 'L';
le = re; break;
re = tmp; case 'L':
use_opcode = '<'; use_opcode = 'G';
break; 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 /* 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) { 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 '<': case '<':
return 5; return 5;
case 'L': case 'L':