diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h index d8dcd963050b5..dbf5cfe6ef463 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -393,7 +393,6 @@ enum OperandType : unsigned { OPERAND_UIMM14_LSB00, OPERAND_UIMM16, OPERAND_UIMM16_NONZERO, - OPERAND_UIMM20, OPERAND_UIMMLOG2XLEN, OPERAND_UIMMLOG2XLEN_NONZERO, OPERAND_UIMM32, @@ -412,13 +411,11 @@ enum OperandType : unsigned { OPERAND_SIMM10_LSB0000_NONZERO, OPERAND_SIMM10_UNSIGNED, OPERAND_SIMM11, - OPERAND_SIMM12, OPERAND_SIMM12_LSB00000, OPERAND_SIMM16, OPERAND_SIMM16_NONZERO, OPERAND_SIMM20_LI, OPERAND_SIMM26, - OPERAND_BARE_SIMM32, OPERAND_CLUI_IMM, OPERAND_VTYPEI10, OPERAND_VTYPEI11, @@ -447,6 +444,15 @@ enum OperandType : unsigned { // Vtype operand for XSfmm extension. OPERAND_XSFMM_VTYPE, OPERAND_LAST_RISCV_IMM = OPERAND_XSFMM_VTYPE, + + OPERAND_UIMM20_LUI, + OPERAND_UIMM20_AUIPC, + + // Simm12 or constant pool, global, basicblock, etc. + OPERAND_SIMM12_LO, + + OPERAND_BARE_SIMM32, + // Operand is either a register or uimm5, this is used by V extension pseudo // instructions to represent a value that be passed as AVL to either vsetvli // or vsetivli. diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp index 2bd63e75d060b..ee327f3d61a62 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp @@ -2850,22 +2850,21 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, MCInstrDesc const &Desc = MI.getDesc(); for (const auto &[Index, Operand] : enumerate(Desc.operands())) { + const MachineOperand &MO = MI.getOperand(Index); unsigned OpType = Operand.OperandType; if (OpType >= RISCVOp::OPERAND_FIRST_RISCV_IMM && OpType <= RISCVOp::OPERAND_LAST_RISCV_IMM) { - const MachineOperand &MO = MI.getOperand(Index); - if (MO.isReg()) { - ErrInfo = "Expected a non-register operand."; + if (!MO.isImm()) { + ErrInfo = "Expected an immediate operand."; return false; } - if (MO.isImm()) { - int64_t Imm = MO.getImm(); - bool Ok; - switch (OpType) { - default: - llvm_unreachable("Unexpected operand type"); + int64_t Imm = MO.getImm(); + bool Ok; + switch (OpType) { + default: + llvm_unreachable("Unexpected operand type"); - // clang-format off + // clang-format off #define CASE_OPERAND_UIMM(NUM) \ case RISCVOp::OPERAND_UIMM##NUM: \ Ok = isUInt(Imm); \ @@ -2874,181 +2873,208 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI, case RISCVOp::OPERAND_SIMM##NUM: \ Ok = isInt(Imm); \ break; - CASE_OPERAND_UIMM(1) - CASE_OPERAND_UIMM(2) - CASE_OPERAND_UIMM(3) - CASE_OPERAND_UIMM(4) - CASE_OPERAND_UIMM(5) - CASE_OPERAND_UIMM(6) - CASE_OPERAND_UIMM(7) - CASE_OPERAND_UIMM(8) - CASE_OPERAND_UIMM(9) - CASE_OPERAND_UIMM(10) - CASE_OPERAND_UIMM(12) - CASE_OPERAND_UIMM(16) - CASE_OPERAND_UIMM(20) - CASE_OPERAND_UIMM(32) - CASE_OPERAND_UIMM(48) - CASE_OPERAND_UIMM(64) - // clang-format on - case RISCVOp::OPERAND_UIMM2_LSB0: - Ok = isShiftedUInt<1, 1>(Imm); - break; - case RISCVOp::OPERAND_UIMM5_LSB0: - Ok = isShiftedUInt<4, 1>(Imm); - break; - case RISCVOp::OPERAND_UIMM5_NONZERO: - Ok = isUInt<5>(Imm) && (Imm != 0); - break; - case RISCVOp::OPERAND_UIMM5_GT3: - Ok = isUInt<5>(Imm) && (Imm > 3); - break; - case RISCVOp::OPERAND_UIMM5_PLUS1: - Ok = Imm >= 1 && Imm <= 32; - break; - case RISCVOp::OPERAND_UIMM6_LSB0: - Ok = isShiftedUInt<5, 1>(Imm); - break; - case RISCVOp::OPERAND_UIMM7_LSB00: - Ok = isShiftedUInt<5, 2>(Imm); - break; - case RISCVOp::OPERAND_UIMM7_LSB000: - Ok = isShiftedUInt<4, 3>(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 RISCVOp::OPERAND_UIMM8_GE32: - Ok = isUInt<8>(Imm) && Imm >= 32; - break; - case RISCVOp::OPERAND_UIMM9_LSB000: - Ok = isShiftedUInt<6, 3>(Imm); - break; - case RISCVOp::OPERAND_SIMM8_UNSIGNED: - Ok = isInt<8>(Imm); - break; - case RISCVOp::OPERAND_SIMM10_LSB0000_NONZERO: - Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0); - break; - case RISCVOp::OPERAND_UIMM10_LSB00_NONZERO: - Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0); - break; - case RISCVOp::OPERAND_UIMM16_NONZERO: - Ok = isUInt<16>(Imm) && (Imm != 0); - break; - case RISCVOp::OPERAND_THREE: - Ok = Imm == 3; - break; - case RISCVOp::OPERAND_FOUR: - Ok = Imm == 4; - break; - case RISCVOp::OPERAND_IMM5_ZIBI: - Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1; - break; - // clang-format off - CASE_OPERAND_SIMM(5) - CASE_OPERAND_SIMM(6) - CASE_OPERAND_SIMM(10) - CASE_OPERAND_SIMM(11) - CASE_OPERAND_SIMM(12) - CASE_OPERAND_SIMM(26) + CASE_OPERAND_UIMM(1) + CASE_OPERAND_UIMM(2) + CASE_OPERAND_UIMM(3) + CASE_OPERAND_UIMM(4) + CASE_OPERAND_UIMM(5) + CASE_OPERAND_UIMM(6) + CASE_OPERAND_UIMM(7) + CASE_OPERAND_UIMM(8) + CASE_OPERAND_UIMM(9) + CASE_OPERAND_UIMM(10) + CASE_OPERAND_UIMM(12) + CASE_OPERAND_UIMM(16) + CASE_OPERAND_UIMM(32) + CASE_OPERAND_UIMM(48) + CASE_OPERAND_UIMM(64) // clang-format on - case RISCVOp::OPERAND_SIMM5_PLUS1: - Ok = Imm >= -15 && Imm <= 16; - break; - case RISCVOp::OPERAND_SIMM5_NONZERO: - Ok = isInt<5>(Imm) && (Imm != 0); - break; - case RISCVOp::OPERAND_SIMM6_NONZERO: - Ok = Imm != 0 && isInt<6>(Imm); - break; - case RISCVOp::OPERAND_VTYPEI10: - Ok = isUInt<10>(Imm); - break; - case RISCVOp::OPERAND_VTYPEI11: - Ok = isUInt<11>(Imm); - break; - case RISCVOp::OPERAND_SIMM12_LSB00000: - Ok = isShiftedInt<7, 5>(Imm); - break; - case RISCVOp::OPERAND_SIMM16_NONZERO: - Ok = isInt<16>(Imm) && (Imm != 0); - break; - case RISCVOp::OPERAND_SIMM20_LI: - Ok = isInt<20>(Imm); - break; - case RISCVOp::OPERAND_BARE_SIMM32: - Ok = isInt<32>(Imm); - break; - case RISCVOp::OPERAND_UIMMLOG2XLEN: - Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm); - break; - case RISCVOp::OPERAND_UIMMLOG2XLEN_NONZERO: - Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm); - Ok = Ok && Imm != 0; - break; - case RISCVOp::OPERAND_CLUI_IMM: - Ok = (isUInt<5>(Imm) && Imm != 0) || - (Imm >= 0xfffe0 && Imm <= 0xfffff); - break; - case RISCVOp::OPERAND_RVKRNUM: - Ok = Imm >= 0 && Imm <= 10; - break; - case RISCVOp::OPERAND_RVKRNUM_0_7: - Ok = Imm >= 0 && Imm <= 7; - break; - case RISCVOp::OPERAND_RVKRNUM_1_10: - Ok = Imm >= 1 && Imm <= 10; - break; - case RISCVOp::OPERAND_RVKRNUM_2_14: - Ok = Imm >= 2 && Imm <= 14; - break; - case RISCVOp::OPERAND_RLIST: - Ok = Imm >= RISCVZC::RA && Imm <= RISCVZC::RA_S0_S11; - break; - case RISCVOp::OPERAND_RLIST_S0: - Ok = Imm >= RISCVZC::RA_S0 && Imm <= RISCVZC::RA_S0_S11; - break; - case RISCVOp::OPERAND_STACKADJ: - Ok = Imm >= 0 && Imm <= 48 && Imm % 16 == 0; - break; - case RISCVOp::OPERAND_FRMARG: + case RISCVOp::OPERAND_UIMM2_LSB0: + Ok = isShiftedUInt<1, 1>(Imm); + break; + case RISCVOp::OPERAND_UIMM5_LSB0: + Ok = isShiftedUInt<4, 1>(Imm); + break; + case RISCVOp::OPERAND_UIMM5_NONZERO: + Ok = isUInt<5>(Imm) && (Imm != 0); + break; + case RISCVOp::OPERAND_UIMM5_GT3: + Ok = isUInt<5>(Imm) && (Imm > 3); + break; + case RISCVOp::OPERAND_UIMM5_PLUS1: + Ok = Imm >= 1 && Imm <= 32; + break; + case RISCVOp::OPERAND_UIMM6_LSB0: + Ok = isShiftedUInt<5, 1>(Imm); + break; + case RISCVOp::OPERAND_UIMM7_LSB00: + Ok = isShiftedUInt<5, 2>(Imm); + break; + case RISCVOp::OPERAND_UIMM7_LSB000: + Ok = isShiftedUInt<4, 3>(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 RISCVOp::OPERAND_UIMM8_GE32: + Ok = isUInt<8>(Imm) && Imm >= 32; + break; + case RISCVOp::OPERAND_UIMM9_LSB000: + Ok = isShiftedUInt<6, 3>(Imm); + break; + case RISCVOp::OPERAND_SIMM8_UNSIGNED: + Ok = isInt<8>(Imm); + break; + case RISCVOp::OPERAND_SIMM10_LSB0000_NONZERO: + Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0); + break; + case RISCVOp::OPERAND_UIMM10_LSB00_NONZERO: + Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0); + break; + case RISCVOp::OPERAND_UIMM16_NONZERO: + Ok = isUInt<16>(Imm) && (Imm != 0); + break; + case RISCVOp::OPERAND_THREE: + Ok = Imm == 3; + break; + case RISCVOp::OPERAND_FOUR: + Ok = Imm == 4; + break; + case RISCVOp::OPERAND_IMM5_ZIBI: + Ok = (isUInt<5>(Imm) && Imm != 0) || Imm == -1; + break; + // clang-format off + CASE_OPERAND_SIMM(5) + CASE_OPERAND_SIMM(6) + CASE_OPERAND_SIMM(10) + CASE_OPERAND_SIMM(11) + CASE_OPERAND_SIMM(26) + // clang-format on + case RISCVOp::OPERAND_SIMM5_PLUS1: + Ok = Imm >= -15 && Imm <= 16; + break; + case RISCVOp::OPERAND_SIMM5_NONZERO: + Ok = isInt<5>(Imm) && (Imm != 0); + break; + case RISCVOp::OPERAND_SIMM6_NONZERO: + Ok = Imm != 0 && isInt<6>(Imm); + break; + case RISCVOp::OPERAND_VTYPEI10: + Ok = isUInt<10>(Imm); + break; + case RISCVOp::OPERAND_VTYPEI11: + Ok = isUInt<11>(Imm); + break; + case RISCVOp::OPERAND_SIMM12_LSB00000: + Ok = isShiftedInt<7, 5>(Imm); + break; + case RISCVOp::OPERAND_SIMM16_NONZERO: + Ok = isInt<16>(Imm) && (Imm != 0); + break; + case RISCVOp::OPERAND_SIMM20_LI: + Ok = isInt<20>(Imm); + break; + case RISCVOp::OPERAND_UIMMLOG2XLEN: + Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm); + break; + case RISCVOp::OPERAND_UIMMLOG2XLEN_NONZERO: + Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm); + Ok = Ok && Imm != 0; + break; + case RISCVOp::OPERAND_CLUI_IMM: + Ok = (isUInt<5>(Imm) && Imm != 0) || (Imm >= 0xfffe0 && Imm <= 0xfffff); + break; + case RISCVOp::OPERAND_RVKRNUM: + Ok = Imm >= 0 && Imm <= 10; + break; + case RISCVOp::OPERAND_RVKRNUM_0_7: + Ok = Imm >= 0 && Imm <= 7; + break; + case RISCVOp::OPERAND_RVKRNUM_1_10: + Ok = Imm >= 1 && Imm <= 10; + break; + case RISCVOp::OPERAND_RVKRNUM_2_14: + Ok = Imm >= 2 && Imm <= 14; + break; + case RISCVOp::OPERAND_RLIST: + Ok = Imm >= RISCVZC::RA && Imm <= RISCVZC::RA_S0_S11; + break; + case RISCVOp::OPERAND_RLIST_S0: + Ok = Imm >= RISCVZC::RA_S0 && Imm <= RISCVZC::RA_S0_S11; + break; + case RISCVOp::OPERAND_STACKADJ: + Ok = Imm >= 0 && Imm <= 48 && Imm % 16 == 0; + break; + case RISCVOp::OPERAND_FRMARG: + Ok = RISCVFPRndMode::isValidRoundingMode(Imm); + break; + case RISCVOp::OPERAND_RTZARG: + Ok = Imm == RISCVFPRndMode::RTZ; + break; + case RISCVOp::OPERAND_COND_CODE: + Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID; + break; + case RISCVOp::OPERAND_VEC_POLICY: + Ok = (Imm & (RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC)) == + Imm; + break; + case RISCVOp::OPERAND_SEW: + Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm)); + break; + case RISCVOp::OPERAND_SEW_MASK: + Ok = Imm == 0; + break; + case RISCVOp::OPERAND_VEC_RM: + assert(RISCVII::hasRoundModeOp(Desc.TSFlags)); + if (RISCVII::usesVXRM(Desc.TSFlags)) + Ok = isUInt<2>(Imm); + else Ok = RISCVFPRndMode::isValidRoundingMode(Imm); - break; - case RISCVOp::OPERAND_RTZARG: - Ok = Imm == RISCVFPRndMode::RTZ; - break; - case RISCVOp::OPERAND_COND_CODE: - Ok = Imm >= 0 && Imm < RISCVCC::COND_INVALID; - break; - case RISCVOp::OPERAND_VEC_POLICY: - Ok = (Imm & - (RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC)) == Imm; - break; - case RISCVOp::OPERAND_SEW: - Ok = (isUInt<5>(Imm) && RISCVVType::isValidSEW(1 << Imm)); - break; - case RISCVOp::OPERAND_SEW_MASK: - Ok = Imm == 0; - break; - case RISCVOp::OPERAND_VEC_RM: - assert(RISCVII::hasRoundModeOp(Desc.TSFlags)); - if (RISCVII::usesVXRM(Desc.TSFlags)) - Ok = isUInt<2>(Imm); - else - Ok = RISCVFPRndMode::isValidRoundingMode(Imm); - break; - case RISCVOp::OPERAND_XSFMM_VTYPE: - Ok = RISCVVType::isValidXSfmmVType(Imm); - break; - } - if (!Ok) { - ErrInfo = "Invalid immediate"; - return false; - } + break; + case RISCVOp::OPERAND_XSFMM_VTYPE: + Ok = RISCVVType::isValidXSfmmVType(Imm); + break; + } + if (!Ok) { + ErrInfo = "Invalid immediate"; + return false; + } + } else if (OpType == RISCVOp::OPERAND_SIMM12_LO) { + // TODO: We could be stricter about what non-register operands are + // allowed. + if (MO.isReg()) { + ErrInfo = "Expected a non-register operand."; + return false; + } + if (MO.isImm() && !isInt<12>(MO.getImm())) { + ErrInfo = "Invalid immediate"; + return false; + } + } else if (OpType == RISCVOp::OPERAND_UIMM20_LUI || + OpType == RISCVOp::OPERAND_UIMM20_AUIPC) { + // TODO: We could be stricter about what non-register operands are + // allowed. + if (MO.isReg()) { + ErrInfo = "Expected a non-register operand."; + return false; + } + if (MO.isImm() && !isUInt<20>(MO.getImm())) { + ErrInfo = "Invalid immediate"; + return false; + } + } else if (OpType == RISCVOp::OPERAND_BARE_SIMM32) { + // TODO: We could be stricter about what non-register operands are + // allowed. + if (MO.isReg()) { + ErrInfo = "Expected a non-register operand."; + return false; + } + if (MO.isImm() && !isInt<32>(MO.getImm())) { + ErrInfo = "Invalid immediate"; + return false; } } } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index a27c46ebf3a99..9a4eb12ca0eb0 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -349,6 +349,7 @@ def simm12_lo : RISCVSImmLeafOp<12> { return isInt<12>(Imm); return MCOp.isBareSymbolRef(); }]; + let OperandType = "OPERAND_SIMM12_LO"; } // A 12-bit signed immediate which cannot fit in 6-bit signed immediate, @@ -394,9 +395,11 @@ class UImm20OperandMaybeSym : RISCVUImmOp<20> { def uimm20_lui : UImm20OperandMaybeSym { let ParserMatchClass = UImmAsmOperand<20, "LUI">; + let OperandType = "OPERAND_UIMM20_LUI"; } def uimm20_auipc : UImm20OperandMaybeSym { let ParserMatchClass = UImmAsmOperand<20, "AUIPC">; + let OperandType = "OPERAND_UIMM20_AUIPC"; } def uimm20 : RISCVUImmOp<20>; diff --git a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp index 74633bedad450..6eeb07f1cf279 100644 --- a/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp +++ b/llvm/tools/llvm-exegesis/lib/RISCV/Target.cpp @@ -864,10 +864,17 @@ Error ExegesisRISCVTarget::randomizeTargetMCOperand( // 5-bit unsigned immediate value. AssignedValue = MCOperand::createImm(randomIndex(31)); break; + case RISCVOp::OPERAND_SIMM12_LO: + case RISCVOp::OPERAND_UIMM20_LUI: + case RISCVOp::OPERAND_UIMM20_AUIPC: + case RISCVOp::OPERAND_BARE_SIMM32: + AssignedValue = MCOperand::createImm(0); + break; default: if (OperandType >= RISCVOp::OPERAND_FIRST_RISCV_IMM && OperandType <= RISCVOp::OPERAND_LAST_RISCV_IMM) AssignedValue = MCOperand::createImm(0); + break; } return Error::success(); }