diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td index 157bad8034072..1e22c2d355108 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td @@ -25,7 +25,7 @@ def SImm8UnsignedAsmOperand : SImmAsmOperand<8, "Unsigned"> { } // A 8-bit signed immediate allowing range [-128, 255] -// but represented as [-128, 127]. +// but represented as [-128, 255]. def simm8_unsigned : RISCVOp { let ParserMatchClass = SImm8UnsignedAsmOperand; let EncoderMethod = "getImmOpValue"; @@ -62,49 +62,40 @@ def simm10_unsigned : RISCVOp { // Instruction class templates //===----------------------------------------------------------------------===// -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class PLI_i funct7, string opcodestr> - : RVInst<(outs GPR:$rd), (ins simm10:$imm10), opcodestr, "$rd, $imm10", [], +// Common base for pli.b/h/w and plui.h/w +class RVPLoadImm_i funct7, dag ins, string opcodestr, + string argstr> + : RVInst<(outs GPR:$rd), ins, opcodestr, argstr, [], InstFormatOther> { - bits<10> imm10; bits<5> rd; let Inst{31-25} = funct7; - let Inst{24-16} = imm10{8-0}; - let Inst{15} = imm10{9}; let Inst{14-12} = 0b010; let Inst{11-7} = rd; let Inst{6-0} = OPC_OP_IMM_32.Value; + + let hasSideEffects = 0; + let mayLoad = 0; + let mayStore = 0; } -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class PLUI_i funct7, string opcodestr> - : RVInst<(outs GPR:$rd), (ins simm10_unsigned:$imm10), opcodestr, - "$rd, $imm10", [], InstFormatOther> { +// Base for pli.h/w. +class PLI_i funct7, string opcodestr> + : RVPLoadImm_i { bits<10> imm10; - bits<5> rd; - let Inst{31-25} = funct7; - let Inst{24} = imm10{0}; - let Inst{23-15} = imm10{9-1}; - let Inst{14-12} = 0b010; - let Inst{11-7} = rd; - let Inst{6-0} = OPC_OP_IMM_32.Value; + let Inst{24-16} = imm10{8-0}; + let Inst{15} = imm10{9}; } -let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in -class PLI_B_i funct8, string opcodestr> - : RVInst<(outs GPR:$rd), (ins simm8_unsigned:$imm8), opcodestr, - "$rd, $imm8", [], InstFormatOther> { - bits<8> imm8; - bits<5> rd; +// Base for plui.h/w. +class PLUI_i funct7, string opcodestr> + : RVPLoadImm_i { + bits<10> imm10; - let Inst{31-24} = funct8; - let Inst{23-16} = imm8; - let Inst{15} = 0b0; - let Inst{14-12} = 0b010; - let Inst{11-7} = rd; - let Inst{6-0} = OPC_OP_IMM_32.Value; + let Inst{24} = imm10{0}; + let Inst{23-15} = imm10{9-1}; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in @@ -180,7 +171,8 @@ class RVPBinary_rr f, bits<2> w, bits<3> funct3, string opcodestr> let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVPTernary_rrr f, bits<2> w, bits<3> funct3, string opcodestr> : RVInstRBase { + (ins GPR:$rd, GPR:$rs1, GPR:$rs2), opcodestr, + "$rd, $rs1, $rs2"> { let Inst{31} = 0b1; let Inst{30-27} = f; let Inst{26-25} = w; @@ -188,6 +180,24 @@ class RVPTernary_rrr f, bits<2> w, bits<3> funct3, string opcodestr> let Constraints = "$rd = $rd_wb"; } +// Common base for pli.db/h/w and plui.dh/w +class RVPPairLoadImm_i funct7, dag ins, string opcodestr, + string argstr> + : RVInst<(outs GPRPairRV32:$rd), ins, opcodestr, argstr, [], + InstFormatOther> { + bits<5> rd; + + let Inst{31-25} = funct7; + let Inst{14-12} = 0b010; + let Inst{11-8} = rd{4-1}; + let Inst{7} = 0b0; + let Inst{6-0} = OPC_OP_IMM_32.Value; + + let hasSideEffects = 0; + let mayLoad = 0; + let mayStore = 0; +} + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -229,8 +239,16 @@ let Predicates = [HasStdExtP] in def PLI_H : PLI_i<0b1011000, "pli.h">; let Predicates = [HasStdExtP, IsRV64] in def PLI_W : PLI_i<0b1011001, "pli.w">; -let Predicates = [HasStdExtP] in -def PLI_B : PLI_B_i<0b10110100, "pli.b">; +let Predicates = [HasStdExtP] in { + def PLI_B : RVPLoadImm_i<0b1011010, (ins simm8_unsigned:$imm8), "pli.b", + "$rd, $imm8"> { + bits<8> imm8; + + let Inst{24} = 0b0; + let Inst{23-16} = imm8; + let Inst{15} = 0b0; + } +} let Predicates = [HasStdExtP] in { def PSEXT_H_B : RVPUnary_ri<0b00, 0b00100, "psext.h.b">; @@ -578,3 +596,30 @@ let Predicates = [HasStdExtP, IsRV64] in { def PPACKT_W : RVPBinary_rr<0b0110, 0b01, 0b100, "ppackt.w">; def PACKT_RV64 : RVPBinary_rr<0b0110, 0b11, 0b100, "packt">; } // Predicates = [HasStdExtP, IsRV64] + +let Predicates = [HasStdExtP, IsRV32] in { + def PLI_DH : RVPPairLoadImm_i<0b0011000, (ins simm10:$imm10), "pli.dh", + "$rd, $imm10"> { + bits<10> imm10; + + let Inst{24-16} = imm10{8-0}; + let Inst{15} = imm10{9}; + } + + def PLI_DB : RVPPairLoadImm_i<0b0011010, (ins simm8_unsigned:$imm8), "pli.db", + "$rd, $imm8"> { + bits<8> imm8; + + let Inst{24} = 0b0; + let Inst{23-16} = imm8; + let Inst{15} = 0b0; + } + + def PLUI_DH : RVPPairLoadImm_i<0b0111000, (ins simm10_unsigned:$imm10), + "plui.dh", "$rd, $imm10"> { + bits<10> imm10; + + let Inst{24} = imm10{0}; + let Inst{23-15} = imm10{9-1}; + } +} diff --git a/llvm/test/MC/RISCV/rv32p-invalid.s b/llvm/test/MC/RISCV/rv32p-invalid.s index 7184241477d69..b00c39b8811dc 100644 --- a/llvm/test/MC/RISCV/rv32p-invalid.s +++ b/llvm/test/MC/RISCV/rv32p-invalid.s @@ -106,3 +106,11 @@ ppack.w t5, a2, a4 # CHECK: :[[@LINE]]:1: error: instruction requires the follow ppackbt.w t5, s0, t5 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set ppacktb.w t5, t1, t1 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set ppackt.w t3, a0, s2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set + +pli.dh a1, 1 # CHECK: :[[@LINE]]:8: error: register must be even +pli.db s1, 1 # CHECK: :[[@LINE]]:8: error: register must be even +plui.dh t2, 1 # CHECK: :[[@LINE]]:9: error: register must be even + +pli.dh a0, 0x400 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-512, 511] +pli.db a0, 0x200 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-128, 255] +plui.dh a0, 0x400 # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-512, 1023] diff --git a/llvm/test/MC/RISCV/rv32p-valid.s b/llvm/test/MC/RISCV/rv32p-valid.s index d5e8299131f10..bc7ec6587c5fc 100644 --- a/llvm/test/MC/RISCV/rv32p-valid.s +++ b/llvm/test/MC/RISCV/rv32p-valid.s @@ -376,3 +376,19 @@ ppackt.h t3, s0, s0 # CHECK-ASM-AND-OBJ: packt a2, t3, t1 # CHECK-ASM: encoding: [0x3b,0x46,0x6e,0xb2] packt a2, t3, t1 + +# CHECK-ASM-AND-OBJ: pli.dh a4, 16 +# CHECK-ASM: encoding: [0x1b,0x27,0x10,0x30] +pli.dh a4, 16 +# CHECK-ASM-AND-OBJ: pli.db a6, 16 +# CHECK-ASM: encoding: [0x1b,0x28,0x10,0x34] +pli.db a6, 16 +# CHECK-ASM-AND-OBJ: pli.db a6, -128 +# CHECK-ASM: encoding: [0x1b,0x28,0x80,0x34] +pli.db a6, -128 +# CHECK-ASM-AND-OBJ: plui.dh tp, 32 +# CHECK-ASM: encoding: [0x1b,0x22,0x08,0x70] +plui.dh tp, 32 +# CHECK-ASM-AND-OBJ: plui.dh tp, -412 +# CHECK-ASM: encoding: [0x1b,0x22,0x99,0x70] +plui.dh tp, 612 diff --git a/llvm/test/MC/RISCV/rv64p-invalid.s b/llvm/test/MC/RISCV/rv64p-invalid.s index 58f5dfb822dea..e18c9ec0e29ea 100644 --- a/llvm/test/MC/RISCV/rv64p-invalid.s +++ b/llvm/test/MC/RISCV/rv64p-invalid.s @@ -65,3 +65,8 @@ mulsu.h00 a4, s4, s6 # CHECK: :[[@LINE]]:1: error: instruction requires the foll maccsu.h00 s4, s4, s0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV32I Base Instruction Set mulsu.h11 s8, s4, s0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV32I Base Instruction Set maccsu.h11 s0, a2, s6 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV32I Base Instruction Set + +# FIXME: This error doesn't make sense. Should say that we need RV32I. +pli.dh a0, 1 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction +pli.db s0, 1 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction +plui.dh t1, 1 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction