]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
xtensa: Add 'spaceshipsi4' insn pattern
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Tue, 24 Feb 2026 21:28:17 +0000 (06:28 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Wed, 25 Feb 2026 14:54:10 +0000 (06:54 -0800)
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

index 1e52bba1a465915f6665059eba18f5f7e478e500..639a5788cb3c18b560edf178ba8e4508141b46b3 100644 (file)
    (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"