diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -772,6 +772,16 @@ VK == RISCVMCExpr::VK_RISCV_None; } + bool isSImm5Plus1NonZero() const { + if (!isImm()) + return false; + RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; + int64_t Imm; + bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); + return (Imm != 0) && IsConstantImm && isInt<5>(Imm - 1) && + VK == RISCVMCExpr::VK_RISCV_None; + } + /// getStartLoc - Gets location of the first token of this operand SMLoc getStartLoc() const override { return StartLoc; } /// getEndLoc - Gets location of the last token of this operand @@ -1279,6 +1289,11 @@ (1 << 4), "immediate must be in the range"); } + case Match_InvalidSImm5Plus1NonZero: { + return generateImmOutOfRangeError( + Operands, ErrorInfo, -(1 << 4) + 1, (1 << 4), + "immediate must be not 0 and be in the range"); + } case Match_InvalidRnumArg: { return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10); } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -216,14 +216,28 @@ OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET, OPERAND_UIMM2 = OPERAND_FIRST_RISCV_IMM, OPERAND_UIMM3, + OPERAND_UIMM4, OPERAND_UIMM5, OPERAND_UIMM7, + OPERAND_UIMM7_LSB00, + OPERAND_UIMM8_LSB00, + OPERAND_UIMM8_LSB000, OPERAND_UIMM12, + OPERAND_ZERO, + OPERAND_SIMM5, + OPERAND_SIMM5_PLUS1, + OPERAND_SIMM5_PLUS1_NONZERO, + OPERAND_SIMM6, + OPERAND_SIMM6_NONZERO, OPERAND_SIMM12, OPERAND_SIMM12_LSB00000, OPERAND_UIMM20, OPERAND_UIMMLOG2XLEN, + OPERAND_UIMMLOG2XLEN_NONZERO, + OPERAND_UIMM_SHFL, + OPERAND_VI10, + OPERAND_VI11, OPERAND_RVKRNUM, OPERAND_LAST_RISCV_IMM = OPERAND_RVKRNUM, // Operand is either a register or uimm5, this is used by V extension pseudo diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -1127,20 +1127,59 @@ CASE_OPERAND_UIMM(4) CASE_OPERAND_UIMM(5) CASE_OPERAND_UIMM(7) + case RISCVOp::OPERAND_UIMM7_LSB00: + Ok = isShiftedUInt<5, 2>(Imm); + break; + case RISCVOp::OPERAND_UIMM8_LSB00: + Ok = isShiftedUInt<6, 2>(Imm); + break; + case RISCVOp::OPERAND_UIMM8_LSB000: + Ok = isShiftedUInt<5, 3>(Imm); + break; CASE_OPERAND_UIMM(12) CASE_OPERAND_UIMM(20) // clang-format on + case RISCVOp::OPERAND_ZERO: + Ok = Imm == 0; + break; + case RISCVOp::OPERAND_SIMM5: + Ok = isInt<5>(Imm); + break; + case RISCVOp::OPERAND_SIMM5_PLUS1: + Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16; + break; + case RISCVOp::OPERAND_SIMM5_PLUS1_NONZERO: + Ok = Imm != 0 && ((isInt<5>(Imm) && Imm != -16) || Imm == 16); + break; + case RISCVOp::OPERAND_SIMM6: + Ok = isInt<6>(Imm); + break; + case RISCVOp::OPERAND_SIMM6_NONZERO: + Ok = Imm != 0 && isInt<6>(Imm); + break; + case RISCVOp::OPERAND_VI10: + Ok = isUInt<10>(Imm); + break; + case RISCVOp::OPERAND_VI11: + Ok = isUInt<11>(Imm); + break; case RISCVOp::OPERAND_SIMM12: Ok = isInt<12>(Imm); break; case RISCVOp::OPERAND_SIMM12_LSB00000: Ok = isShiftedInt<7, 5>(Imm); break; - case RISCVOp::OPERAND_UIMMLOG2XLEN: - if (STI.getTargetTriple().isArch64Bit()) - Ok = isUInt<6>(Imm); - else - Ok = isUInt<5>(Imm); + Ok = STI.getTargetTriple().isArch64Bit() ? isUInt<6>(Imm) + : isUInt<5>(Imm); + break; + case RISCVOp::OPERAND_UIMMLOG2XLEN_NONZERO: + Ok = STI.getTargetTriple().isArch64Bit() ? isUInt<6>(Imm) + : isUInt<5>(Imm); + Ok = Ok && Imm != 0; + break; + case RISCVOp::OPERAND_UIMM_SHFL: + Ok = STI.getTargetTriple().isArch64Bit() ? isUInt<5>(Imm) + : isUInt<4>(Imm); break; case RISCVOp::OPERAND_RVKRNUM: Ok = Imm >= 0 && Imm <= 10; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -26,6 +26,8 @@ let ParserMatchClass = UImmLog2XLenNonZeroAsmOperand; // TODO: should ensure invalid shamt is rejected when decoding. let DecoderMethod = "decodeUImmOperand<6>"; + let OperandType = "OPERAND_UIMMLOG2XLEN_NONZERO"; + let OperandNamespace = "RISCVOp"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm)) @@ -40,6 +42,8 @@ let ParserMatchClass = SImmAsmOperand<6>; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<6>"; + let OperandType = "OPERAND_SIMM6"; + let OperandNamespace = "RISCVOp"; let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) @@ -53,6 +57,8 @@ let ParserMatchClass = SImmAsmOperand<6, "NonZero">; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<6>"; + let OperandType = "OPERAND_SIMM6_NONZERO"; + let OperandNamespace = "RISCVOp"; let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) @@ -64,6 +70,8 @@ def immzero : Operand, ImmLeaf { let ParserMatchClass = ImmZeroAsmOperand; + let OperandType = "OPERAND_ZERO"; + let OperandNamespace = "RISCVOp"; } def CLUIImmAsmOperand : AsmOperandClass { @@ -100,6 +108,8 @@ let ParserMatchClass = UImmAsmOperand<7, "Lsb00">; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeUImmOperand<7>"; + let OperandType = "OPERAND_UIMM7_LSB00"; + let OperandNamespace = "RISCVOp"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm)) @@ -114,6 +124,8 @@ let ParserMatchClass = UImmAsmOperand<8, "Lsb00">; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeUImmOperand<8>"; + let OperandType = "OPERAND_UIMM8_LSB00"; + let OperandNamespace = "RISCVOp"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm)) @@ -128,6 +140,8 @@ let ParserMatchClass = UImmAsmOperand<8, "Lsb000">; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeUImmOperand<8>"; + let OperandType = "OPERAND_UIMM8_LSB000"; + let OperandNamespace = "RISCVOp"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm)) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td @@ -28,10 +28,18 @@ let ParserMatchClass = VTypeIAsmOperand; let PrintMethod = "printVTypeI"; let DecoderMethod = "decodeUImmOperand<"#VTypeINum#">"; + let OperandType = "OPERAND_VI" # VTypeINum; + let OperandNamespace = "RISCVOp"; + let MCOperandPredicate = [{ + int64_t Imm; + if (MCOp.evaluateAsConstantImm(Imm)) + return isUInt(Imm); + return MCOp.isBareSymbolRef(); + }]; } -def VTypeIOp10 : VTypeIOp<10>; -def VTypeIOp11 : VTypeIOp<11>; +def VTypeIOp10 : VTypeIOp<10>, ImmLeaf(Imm);}]>; +def VTypeIOp11 : VTypeIOp<11>, ImmLeaf(Imm);}]>; def VMaskAsmOperand : AsmOperandClass { let Name = "RVVMaskRegOpOperand"; @@ -54,6 +62,8 @@ let ParserMatchClass = SImmAsmOperand<5>; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<5>"; + let OperandType = "OPERAND_SIMM5"; + let OperandNamespace = "RISCVOp"; let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) @@ -71,6 +81,8 @@ def simm5_plus1 : Operand, ImmLeaf(Imm) && Imm != -16) || Imm == 16;}]> { let ParserMatchClass = SImm5Plus1AsmOperand; + let OperandType = "OPERAND_SIMM5_PLUS1"; + let OperandNamespace = "RISCVOp"; let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) @@ -79,8 +91,25 @@ }]; } -def simm5_plus1_nonzero : ImmLeaf(Imm) && Imm != -16) || Imm == 16);}]>; + +def SImm5Plus1NonZeroAsmOperand : AsmOperandClass { + let Name = "SImm5Plus1NonZero"; + let RenderMethod = "addImmOperands"; + let DiagnosticType = "InvalidSImm5Plus1NonZero"; +} + +def simm5_plus1_nonzero : Operand, ImmLeaf(Imm) && Imm != -16) || Imm == 16);}]> { + let ParserMatchClass = SImm5Plus1NonZeroAsmOperand; + let OperandType = "OPERAND_SIMM5_PLUS1_NONZERO"; + let OperandNamespace = "RISCVOp"; + let MCOperandPredicate = [{ + int64_t Imm; + if (MCOp.evaluateAsConstantImm(Imm)) + return Imm != 0 && ((isInt<5>(Imm) && Imm != -16) || Imm == 16); + return MCOp.isBareSymbolRef(); + }]; +} //===----------------------------------------------------------------------===// // Scheduling definitions. diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td @@ -71,6 +71,8 @@ }]> { let ParserMatchClass = UImmLog2XLenHalfAsmOperand; let DecoderMethod = "decodeUImmOperand<5>"; + let OperandType = "OPERAND_UIMM_SHFL"; + let OperandNamespace = "RISCVOp"; let MCOperandPredicate = [{ int64_t Imm; if (!MCOp.evaluateAsConstantImm(Imm))