21 for (
auto Instr : Res) {
23 bool Compressed =
false;
24 switch (Instr.getOpcode()) {
36 Compressed =
isInt<6>(Instr.getImm());
55 bool IsRV64 = STI.
hasFeature(RISCV::Feature64Bit);
64 if (!IsRV64 && STI.
hasFeature(RISCV::FeatureVendorXqcili)) {
65 bool FitsOneStandardInst = ((Val & 0xFFF) == 0) ||
isInt<12>(Val);
69 if (!FitsOneStandardInst &&
isInt<20>(Val)) {
76 if (!FitsOneStandardInst &&
isInt<32>(Val)) {
87 int32_t Bit31To0 = Val;
88 if (!IsRV64 || int32_t(Val >> 32) == Bit31To0)
91 int16_t Bit15To0 = Bit31To0;
92 if (Width == 32 && int16_t(Bit31To0 >> 16) == Bit15To0)
95 int8_t Bit7To0 = Bit15To0;
96 if (Width == 16 && int8_t(Bit15To0 >> 8) == Bit7To0) {
101 if (Width == 16 &&
isInt<10>(Bit15To0)) {
110 if (Width == 32 &&
isInt<10>(Bit31To0)) {
128 int64_t Hi20 = ((Val + 0x800) >> 12) & 0xFFFFF;
134 if (Lo12 || Hi20 == 0) {
135 unsigned AddiOpc = RISCV::ADDI;
136 if (IsRV64 && Hi20) {
142 AddiOpc = RISCV::ADDIW;
149 assert(IsRV64 &&
"Can't emit >32-bit imm for non-RV64 target");
177 unsigned ShiftAmount = 0;
178 unsigned ShiftOpc = RISCV::SLLI;
188 if (ShiftAmount > 12 && !
isInt<12>(Val)) {
200 ShiftOpc = RISCV::SLLI_UW;
210 ShiftOpc = RISCV::SLLI_UW;
232 if (TrailingOnes > 0 && TrailingOnes < 64 &&
233 (LeadingOnes + TrailingOnes) > (64 - 12))
234 return 64 - TrailingOnes;
239 if (UpperTrailingOnes < 32 &&
240 (UpperTrailingOnes + LowerLeadingOnes) > (64 - 12))
241 return 32 - UpperTrailingOnes;
251 for (
bool Negative : {
true,
false}) {
252 uint64_t Run = Negative ? Val : ~Val;
253 unsigned RunTop = Negative ? 64 : 64 + 12;
254 for (
unsigned RunEnd :
256 unsigned Rotate = (RunTop - RunEnd) % 64;
268 assert(Val > 0 &&
"Expected positive val");
281 if ((TmpSeq.
size() + 1) < Res.
size() ||
293 if ((TmpSeq.
size() + 1) < Res.
size() ||
301 if (LeadingZeros == 32 && STI.
hasFeature(RISCV::FeatureStdExtZba)) {
308 if ((TmpSeq.
size() + 1) < Res.
size() ||
324 if ((Val & 0xfff) != 0 && (Val & 1) == 0 && Res.
size() >= 2) {
326 int64_t ShiftedVal = Val >> TrailingZeros;
331 bool IsShiftedCompressible =
337 if ((TmpSeq.
size() + 1) < Res.
size() || IsShiftedCompressible) {
349 "Expected RV32 to only need 2 instructions");
356 if ((Val & 0xfff) != 0 && (Val & 0x1800) == 0x1000) {
357 int64_t Imm12 = -(0x800 - (Val & 0xfff));
358 int64_t AdjustedVal = Val - Imm12;
363 if ((TmpSeq.
size() + 1) < Res.
size()) {
371 if (Val > 0 && Res.
size() > 2) {
377 if (Val < 0 && Res.
size() > 3) {
378 uint64_t InvertedVal = ~(uint64_t)Val;
392 if (Res.
size() > 2 && (STI.
hasFeature(RISCV::FeatureStdExtZbkb) ||
396 if (LoVal == HiVal) {
399 if ((TmpSeq.
size() + 1) < Res.
size()) {
411 uint64_t
Lo = Val & 0x7fffffff;
412 uint64_t
Hi = Val ^
Lo;
428 if (Res[0].getOpcode() == RISCV::ADDI && Res[0].
getImm() == 1 &&
429 Res[1].getOpcode() == RISCV::SLLI) {
440 uint64_t
Lo = Val | 0xffffffff80000000;
441 uint64_t
Hi = Val ^
Lo;
462 if ((Val % 3) == 0 &&
isInt<32>(Val / 3)) {
465 }
else if ((Val % 5) == 0 &&
isInt<32>(Val / 5)) {
468 }
else if ((Val % 9) == 0 &&
isInt<32>(Val / 9)) {
475 if ((TmpSeq.
size() + 1) < Res.
size()) {
481 int64_t Hi52 = ((uint64_t)Val + 0x800ull) & ~0xfffull;
484 if (
isInt<32>(Hi52 / 3) && (Hi52 % 3) == 0) {
487 }
else if (
isInt<32>(Hi52 / 5) && (Hi52 % 5) == 0) {
490 }
else if (
isInt<32>(Hi52 / 9) && (Hi52 % 9) == 0) {
499 "unexpected instruction sequence for immediate materialisation");
502 if ((TmpSeq.
size() + 2) < Res.
size()) {
514 STI.
hasFeature(RISCV::FeatureVendorXTHeadBb))) {
516 STI.
hasFeature(RISCV::FeatureStdExtZbb) ? RISCV::RORI : RISCV::TH_SRRI;
524 "Expected a value LUI can load");
525 TmpSeq.
emplace_back(RISCV::LUI, (Rotated >> 12) & 0xFFFFF);
572 unsigned &ShiftAmt,
unsigned &AddOpc) {
578 uint64_t Tmp = (uint64_t)Val - (uint64_t)LoVal;
587 assert(TzLo < 32 && TzHi >= 32);
588 ShiftAmt = TzHi - TzLo;
591 if (Tmp == ((uint64_t)LoVal << ShiftAmt))
597 AddOpc = RISCV::ADD_UW;
605 bool CompressionCost,
bool FreeZeroes) {
606 bool IsRV64 = STI.
hasFeature(RISCV::Feature64Bit);
607 bool HasRVC = CompressionCost && STI.
hasFeature(RISCV::FeatureStdExtZca);
608 int PlatRegSize = IsRV64 ? 64 : 32;
613 for (
unsigned ShiftVal = 0; ShiftVal <
Size; ShiftVal += PlatRegSize) {
620 return std::max(FreeZeroes ? 0 : 1,
Cost);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static void generateInstSeqLeadingZeros(int64_t Val, const MCSubtargetInfo &STI, RISCVMatInt::InstSeq &Res)
static void generateInstSeqImpl(int64_t Val, const MCSubtargetInfo &STI, RISCVMatInt::InstSeq &Res)
static unsigned extractRotateInfo(int64_t Val)
static int getInstSeqCost(RISCVMatInt::InstSeq &Res, bool HasRVC)
Class for arbitrary precision integers.
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
int64_t getSExtValue() const
Get sign extended value.
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Wrapper class representing physical registers. Should be passed by value.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
unsigned getOpcode() const
OpndKind getOpndKind() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
int getIntMatCost(const APInt &Val, unsigned Size, const MCSubtargetInfo &STI, bool CompressionCost, bool FreeZeroes)
InstSeq generateTwoRegInstSeq(int64_t Val, const MCSubtargetInfo &STI, unsigned &ShiftAmt, unsigned &AddOpc)
SmallVector< Inst, 8 > InstSeq
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
int countl_one(T Value)
Count the number of ones from the most significant bit to the first zero bit.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
constexpr T maskTrailingZeros(unsigned N)
Create a bitmask with the N right-most bits set to 0, and all other bits set to 1.
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
constexpr T rotl(T V, int R)