When TARGET_SALT is configured in the Xtensa ISA, a Boolean evaluation of
LT/GT[U] between address (GP) registers can be done in a single machine
instruction, making it easy to implement the spaceship operator by sub-
tracting one from the other result.
/* examples */
int test0(int a, int b) {
return a == b ? 0 : (a > b ? 1 : -1);
}
int test1(unsigned int a, unsigned int b) {
return a == b ? 0 : (a > b ? 1 : -1);
}
;; before (-msalt)
test0:
entry sp, 32
mov.n a8, a2
movi.n a2, 0
beq a8, a3, .L1
movi.n a2, -1
bge a3, a8, .L1
movi.n a2, 1
.L1:
retw.n
test1:
entry sp, 32
mov.n a8, a2
movi.n a2, 0
beq a8, a3, .L6
movi.n a2, -1
bgeu a3, a8, .L6
movi.n a2, 1
.L6:
retw.n
;; after (-msalt)
test0:
entry sp, 32
salt a8, a2, a3
salt a2, a3, a2
sub a2, a2, a8
retw.n
test1:
entry sp, 32
saltu a8, a2, a3
saltu a2, a3, a2
sub a2, a2, a8
retw.n
gcc/ChangeLog:
* config/xtensa/xtensa.md (spaceshipsi4):
New RTL generation pattern.
---
gcc/config/xtensa/xtensa.md | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 1e52bba1a46..639a5788cb3 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -2315,6 +2315,23 @@
(set_attr "mode" "SI")
(set_attr "length" "3")])
+(define_expand "spaceshipsi4"
+ [(match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")
+ (match_operand:SI 3 "const_int_operand")]
+ "TARGET_SALT"
+{
+ rtx (*gen_op)(rtx, rtx, rtx);
+ rtx temp0, temp1;
+ gcc_assert (operands[3] == const1_rtx || operands[3] == constm1_rtx);
+ gen_op = (operands[3] == const1_rtx) ? gen_saltu : gen_salt;
+ emit_insn (gen_op (temp0 = gen_reg_rtx (SImode), operands[1], operands[2]));
+ emit_insn (gen_op (temp1 = gen_reg_rtx (SImode), operands[2], operands[1]));
+ emit_insn (gen_subsi3 (operands[0], temp1, temp0));
+ DONE;
+})
+
(define_expand "cstoresf4"
[(match_operand:SI 0 "register_operand")
(match_operator:SI 1 "comparison_operator"
--
2.39.5