From 494055572edd6d81902b1ae0953e8a54542747de Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 13 Aug 2025 09:17:33 -0700 Subject: [PATCH 1/2] [RISCV] Add MC support for more P extension instructions. These instructions are the shift by immediate and saturate by immediate instructions from the top half of page 9 of https://jhauser.us/RISCV/ext-P/RVP-instrEncodings-015.pdf I've also improved the CHECK lines in the invalid tests to check line and column number from the diagnostic. --- llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 44 +++++++++++++++++++++ llvm/test/MC/RISCV/rv32p-invalid.s | 48 +++++++++++++++-------- llvm/test/MC/RISCV/rv32p-valid.s | 30 ++++++++++++++ llvm/test/MC/RISCV/rv64p-invalid.s | 50 +++++++++++++++--------- llvm/test/MC/RISCV/rv64p-valid.s | 45 +++++++++++++++++++++ 5 files changed, 183 insertions(+), 34 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index 461f3d1036460..ed85f407513fd 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -98,6 +98,14 @@ class RVPShift_ri f, bits<3> funct3, string opcodestr, Operand ImmType> let Inst{27} = 0b0; } +class RVPShiftD_ri f, bits<3> funct3, string opcodestr> + : RVPShift_ri { + bits<6> shamt; + + let Inst{26} = 0b1; + let Inst{25-20} = shamt; +} + class RVPShiftW_ri f, bits<3> funct3, string opcodestr> : RVPShift_ri { bits<5> shamt; @@ -189,3 +197,39 @@ let Predicates = [HasStdExtP] in def PLUI_H : PLUI_i<0b1111000, "plui.h">; let Predicates = [HasStdExtP, IsRV64] in def PLUI_W : PLUI_i<0b1111001, "plui.w">; + +let Predicates = [HasStdExtP] in { + def PSRLI_B : RVPShiftB_ri<0b000, 0b100, "psrli.b">; + def PSRLI_H : RVPShiftH_ri<0b000, 0b100, "psrli.h">; + + def PUSATI_H : RVPShiftH_ri<0b010, 0b100, "pusati.h">; + + def PSRAI_B : RVPShiftB_ri<0b100, 0b100, "psrai.b">; + def PSRAI_H : RVPShiftH_ri<0b100, 0b100, "psrai.h">; + + def PSRARI_H : RVPShiftH_ri<0b101, 0b100, "psrari.h">; + + def PSATI_H : RVPShiftH_ri<0b110, 0b100, "psati.h">; +} // Predicates = [HasStdExtP] + +let Predicates = [HasStdExtP, IsRV32], DecoderNamespace = "RV32Only" in { + def USATI_RV32 : RVPShiftW_ri<0b010, 0b100, "usati">; + + def SRARI_RV32 : RVPShiftW_ri<0b101, 0b100, "srari">; + + def SATI_RV32 : RVPShiftW_ri<0b110, 0b100, "sati">; +} // Predicates = [HasStdExtP, IsRV64] + +let Predicates = [HasStdExtP, IsRV64] in { + def PSRLI_W : RVPShiftW_ri<0b000, 0b100, "psrli.w">; + def PSRAI_W : RVPShiftW_ri<0b100, 0b100, "psrai.w">; + + def PUSATI_W : RVPShiftW_ri<0b010, 0b100, "pusati.w">; + def USATI_RV64 : RVPShiftD_ri<0b010, 0b100, "usati">; + + def PSRARI_W : RVPShiftW_ri<0b101, 0b100, "psrari.w">; + def SRARI_RV64 : RVPShiftD_ri<0b101, 0b100, "srari">; + + def PSATI_W : RVPShiftW_ri<0b110, 0b100, "psati.w">; + def SATI_RV64 : RVPShiftD_ri<0b110, 0b100, "sati">; +} // Predicates = [HasStdExtP, IsRV64] diff --git a/llvm/test/MC/RISCV/rv32p-invalid.s b/llvm/test/MC/RISCV/rv32p-invalid.s index da3c67b73d0af..2ecce5fec84cf 100644 --- a/llvm/test/MC/RISCV/rv32p-invalid.s +++ b/llvm/test/MC/RISCV/rv32p-invalid.s @@ -1,19 +1,35 @@ # RUN: not llvm-mc -triple=riscv32 --mattr=+experimental-p %s 2>&1 \ -# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR +# RUN: | FileCheck %s # Imm overflow -pli.h a0, 0x400 -# CHECK-ERROR: immediate must be an integer in the range [-512, 511] -plui.h a1, 0x400 -# CHECK-ERROR: immediate must be an integer in the range [-512, 1023] -pli.b a0, 0x200 -# CHECK-ERROR: immediate must be an integer in the range [0, 255] - -pslli.b a6, a7, 100 -# CHECK-ERROR: immediate must be an integer in the range [0, 7] -pslli.h ra, sp, 100 -# CHECK-ERROR: immediate must be an integer in the range [0, 15] -psslai.h t0, t1, 100 -# CHECK-ERROR: immediate must be an integer in the range [0, 15] -sslai a4, a5, -1 -# CHECK-ERROR: immediate must be an integer in the range [0, 31] +pli.h a0, 0x400 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [-512, 511] +plui.h a1, 0x400 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-512, 1023] +pli.b a0, 0x200 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 255] + +pslli.b a6, a7, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 7] +pslli.h ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] +pslli.w ra, sp, 12 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set + +psslai.h t0, t1, 100 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 15] +psslai.w t0, t1, 27 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set +sslai a4, a5, -1 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31] + +psrli.b a6, a7, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 7] +psrli.h ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] +psrli.w ra, sp, 31 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set + +pusati.h ra, sp, 100 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 15] +pusati.w ra, sp, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set +usati ra, sp, 100 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31] + +psrai.b a6, a7, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 7] +psrai.h ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] +psrai.w ra, sp, 10 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set + +psrari.h ra, sp, 100 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 15] +psrari.w ra, sp, 15 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set +srari ra, sp, 100 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 31] + +psati.h ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] +psati.w ra, sp, 24 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set +sati ra, sp, 100 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31] diff --git a/llvm/test/MC/RISCV/rv32p-valid.s b/llvm/test/MC/RISCV/rv32p-valid.s index ffff0f25642a3..1d0fb6d95781b 100644 --- a/llvm/test/MC/RISCV/rv32p-valid.s +++ b/llvm/test/MC/RISCV/rv32p-valid.s @@ -76,3 +76,33 @@ plui.h gp, 32 # CHECK-ASM-AND-OBJ: plui.h gp, -412 # CHECK-ASM: encoding: [0x9b,0x21,0x99,0xf0] plui.h gp, 612 +# CHECK-ASM-AND-OBJ: psrli.b a6, a7, 0 +# CHECK-ASM: encoding: [0x1b,0xc8,0x88,0x80] +psrli.b a6, a7, 0 +# CHECK-ASM-AND-OBJ: psrli.h ra, sp, 1 +# CHECK-ASM: encoding: [0x9b,0x40,0x11,0x81] +psrli.h ra, sp, 1 +# CHECK-ASM-AND-OBJ: pusati.h t2, t3, 4 +# CHECK-ASM: encoding: [0x9b,0x43,0x4e,0xa1] +pusati.h t2, t3, 4 +# CHECK-ASM-AND-OBJ: usati t3, t4, 5 +# CHECK-ASM: encoding: [0x1b,0xce,0x5e,0xa2] +usati t3, t4, 5 +# CHECK-ASM-AND-OBJ: psrai.b a6, a7, 0 +# CHECK-ASM: encoding: [0x1b,0xc8,0x88,0xc0] +psrai.b a6, a7, 0 +# CHECK-ASM-AND-OBJ: psrai.h ra, sp, 1 +# CHECK-ASM: encoding: [0x9b,0x40,0x11,0xc1] +psrai.h ra, sp, 1 +# CHECK-ASM-AND-OBJ: psrari.h t4, t5, 6 +# CHECK-ASM: encoding: [0x9b,0x4e,0x6f,0xd1] +psrari.h t4, t5, 6 +# CHECK-ASM-AND-OBJ: srari t5, t6, 7 +# CHECK-ASM: encoding: [0x1b,0xcf,0x7f,0xd2] +srari t5, t6, 7 +# CHECK-ASM-AND-OBJ: psati.h t6, s11, 8 +# CHECK-ASM: encoding: [0x9b,0xcf,0x8d,0xe1] +psati.h t6, s11, 8 +# CHECK-ASM-AND-OBJ: sati s11, s10, 9 +# CHECK-ASM: encoding: [0x9b,0x4d,0x9d,0xe2] +sati s11, s10, 9 diff --git a/llvm/test/MC/RISCV/rv64p-invalid.s b/llvm/test/MC/RISCV/rv64p-invalid.s index 572a099fba4d4..ccccba2e9e544 100644 --- a/llvm/test/MC/RISCV/rv64p-invalid.s +++ b/llvm/test/MC/RISCV/rv64p-invalid.s @@ -1,21 +1,35 @@ # RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-p %s 2>&1 \ -# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR +# RUN: | FileCheck %s # Imm overflow -pli.h a0, 0x400 -# CHECK-ERROR: immediate must be an integer in the range [-512, 511] -plui.h a1, 0x400 -# CHECK-ERROR: immediate must be an integer in the range [-512, 1023] -pli.w a1, -0x201 -# CHECK-ERROR: immediate must be an integer in the range [-512, 511] - -pslli.b a6, a7, 100 -# CHECK-ERROR: immediate must be an integer in the range [0, 7] -pslli.h ra, sp, 100 -# CHECK-ERROR: immediate must be an integer in the range [0, 15] -pslli.w ra, sp, 100 -# CHECK-ERROR: immediate must be an integer in the range [0, 31] -psslai.h t0, t1, 100 -# CHECK-ERROR: immediate must be an integer in the range [0, 15] -psslai.w a4, a5, -1 -# CHECK-ERROR: error: immediate must be an integer in the range [0, 31] +pli.h a0, 0x400 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [-512, 511] +plui.h a1, 0x400 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-512, 1023] +pli.w a1, -0x201 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [-512, 511] + +pslli.b a6, a7, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 7] +pslli.h ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] +pslli.w ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31] + +psslai.h t0, t1, 100 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 15] +psslai.w a4, a5, -1 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 31] +sslai ra, sp, 10 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV32I Base Instruction Set + +psrli.b a6, a7, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 7] +psrli.h ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] +psrli.w ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31] + +pusati.h ra, sp, 100 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 15] +pusati.w ra, sp, 100 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 31] +usati ra, sp, 100 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 63] + +psrai.b a6, a7, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 7] +psrai.h ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] +psrai.w ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31] + +psrari.h ra, sp, 100 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 15] +psrari.w ra, sp, 100 # CHECK: :[[@LINE]]:18: error: immediate must be an integer in the range [0, 31] +srari ra, sp, 100 # CHECK: :[[@LINE]]:15: error: immediate must be an integer in the range [0, 63] + +psati.h ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] +psati.w ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31] +sati ra, sp, 100 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 63] diff --git a/llvm/test/MC/RISCV/rv64p-valid.s b/llvm/test/MC/RISCV/rv64p-valid.s index 636356a6b3cb3..13cfd5e8023b0 100644 --- a/llvm/test/MC/RISCV/rv64p-valid.s +++ b/llvm/test/MC/RISCV/rv64p-valid.s @@ -106,3 +106,48 @@ plui.w a2, 1 # CHECK-ASM-AND-OBJ: plui.w a2, -1 # CHECK-ASM: encoding: [0x1b,0xa6,0xff,0xf3] plui.w a2, 1023 +# CHECK-ASM-AND-OBJ: psrli.b a6, a7 +# CHECK-ASM: encoding: [0x1b,0xc8,0x88,0x80] +psrli.b a6, a7, 0 +# CHECK-ASM-AND-OBJ: psrli.h ra, sp, 1 +# CHECK-ASM: encoding: [0x9b,0x40,0x11,0x81] +psrli.h ra, sp, 1 +# CHECK-ASM-AND-OBJ: psrli.w ra, sp, 2 +# CHECK-ASM: encoding: [0x9b,0x40,0x21,0x82] +psrli.w ra, sp, 2 +# CHECK-ASM-AND-OBJ: pusati.h t2, t3, 4 +# CHECK-ASM: encoding: [0x9b,0x43,0x4e,0xa1] +pusati.h t2, t3, 4 +# CHECK-ASM-AND-OBJ: pusati.w t2, t3, 5 +# CHECK-ASM: encoding: [0x9b,0x43,0x5e,0xa2] +pusati.w t2, t3, 5 +# CHECK-ASM-AND-OBJ: usati t3, t4, 5 +# CHECK-ASM: encoding: [0x1b,0xce,0x5e,0xa4] +usati t3, t4, 5 +# CHECK-ASM-AND-OBJ: psrai.b a6, a7, 0 +# CHECK-ASM: encoding: [0x1b,0xc8,0x88,0xc0] +psrai.b a6, a7, 0 +# CHECK-ASM-AND-OBJ: psrai.h ra, sp, 1 +# CHECK-ASM: encoding: [0x9b,0x40,0x11,0xc1] +psrai.h ra, sp, 1 +# CHECK-ASM-AND-OBJ: psrai.w ra, sp, 2 +# CHECK-ASM: encoding: [0x9b,0x40,0x21,0xc2] +psrai.w ra, sp, 2 +# CHECK-ASM-AND-OBJ: psrari.h t4, t5, 6 +# CHECK-ASM: encoding: [0x9b,0x4e,0x6f,0xd1] +psrari.h t4, t5, 6 +# CHECK-ASM-AND-OBJ: psrari.w t5, t6, 7 +# CHECK-ASM: encoding: [0x1b,0xcf,0x7f,0xd2] +psrari.w t5, t6, 7 +# CHECK-ASM-AND-OBJ: srari t6, s11, 63 +# CHECK-ASM: encoding: [0x9b,0xcf,0xfd,0xd7] +srari t6, s11, 63 +# CHECK-ASM-AND-OBJ: psati.h s11, s10, 9 +# CHECK-ASM: encoding: [0x9b,0x4d,0x9d,0xe1] +psati.h s11, s10, 9 +# CHECK-ASM-AND-OBJ: psati.w s10, s9, 10 +# CHECK-ASM: encoding: [0x1b,0xcd,0xac,0xe2] +psati.w s10, s9, 10 +# CHECK-ASM-AND-OBJ: sati s9, s8, 32 +# CHECK-ASM: encoding: [0x9b,0x4c,0x0c,0xe6] +sati s9, s8, 32 From 9c1d59e5e44590a7beff6793df315b06adc2fc92 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 13 Aug 2025 13:57:07 -0700 Subject: [PATCH 2/2] fixup! Fix typo and format --- llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index ed85f407513fd..d17330f9da9f1 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -211,15 +211,13 @@ let Predicates = [HasStdExtP] in { def PSATI_H : RVPShiftH_ri<0b110, 0b100, "psati.h">; } // Predicates = [HasStdExtP] - let Predicates = [HasStdExtP, IsRV32], DecoderNamespace = "RV32Only" in { def USATI_RV32 : RVPShiftW_ri<0b010, 0b100, "usati">; def SRARI_RV32 : RVPShiftW_ri<0b101, 0b100, "srari">; def SATI_RV32 : RVPShiftW_ri<0b110, 0b100, "sati">; -} // Predicates = [HasStdExtP, IsRV64] - +} // Predicates = [HasStdExtP, IsRV32] let Predicates = [HasStdExtP, IsRV64] in { def PSRLI_W : RVPShiftW_ri<0b000, 0b100, "psrli.w">; def PSRAI_W : RVPShiftW_ri<0b100, 0b100, "psrai.w">;