21 for (
auto Instr : Res) {
23 bool Compressed =
false;
24 switch (Instr.getOpcode()) {
32 Compressed = isInt<6>(Instr.getImm());
51 bool IsRV64 = STI.
hasFeature(RISCV::Feature64Bit);
55 (!isInt<32>(Val) || Val == 0x800)) {
68 int64_t Hi20 = ((Val + 0x800) >> 12) & 0xFFFFF;
69 int64_t Lo12 = SignExtend64<12>(Val);
74 if (Lo12 || Hi20 == 0) {
75 unsigned AddiOpc = (IsRV64 && Hi20) ? RISCV::ADDIW : RISCV::ADDI;
81 assert(IsRV64 &&
"Can't emit >32-bit imm for non-RV64 target");
106 int64_t Lo12 = SignExtend64<12>(Val);
113 if (!isInt<32>(Val)) {
120 if (ShiftAmount > 12 && !isInt<12>(Val)) {
121 if (isInt<32>((
uint64_t)Val << 12)) {
126 }
else if (isUInt<32>((
uint64_t)Val << 12) &&
131 Val = ((
uint64_t)Val << 12) | (0xffffffffull << 32);
141 Val = ((
uint64_t)Val) | (0xffffffffull << 32);
150 unsigned Opc =
Unsigned ? RISCV::SLLI_UW : RISCV::SLLI;
162 if (TrailingOnes > 0 && TrailingOnes < 64 &&
163 (LeadingOnes + TrailingOnes) > (64 - 12))
164 return 64 - TrailingOnes;
169 if (UpperTrailingOnes < 32 &&
170 (UpperTrailingOnes + LowerLeadingOnes) > (64 - 12))
171 return 32 - UpperTrailingOnes;
178 assert(Val > 0 &&
"Expected postive val");
185 ShiftedVal |= maskTrailingOnes<uint64_t>(LeadingZeros);
191 if ((TmpSeq.
size() + 1) < Res.
size() ||
198 ShiftedVal &= maskTrailingZeros<uint64_t>(LeadingZeros);
203 if ((TmpSeq.
size() + 1) < Res.
size() ||
211 if (LeadingZeros == 32 && STI.
hasFeature(RISCV::FeatureStdExtZba)) {
213 uint64_t LeadingOnesVal = Val | maskLeadingOnes<uint64_t>(LeadingZeros);
218 if ((TmpSeq.
size() + 1) < Res.
size() ||
234 if ((Val & 0xfff) != 0 && (Val & 1) == 0 && Res.
size() >= 2) {
236 int64_t ShiftedVal = Val >> TrailingZeros;
241 bool IsShiftedCompressible =
242 isInt<6>(ShiftedVal) && !STI.
hasFeature(RISCV::TuneLUIADDIFusion);
247 if ((TmpSeq.
size() + 1) < Res.
size() || IsShiftedCompressible) {
259 "Expected RV32 to only need 2 instructions");
266 if ((Val & 0xfff) != 0 && (Val & 0x1800) == 0x1000) {
267 int64_t Imm12 = -(0x800 - (Val & 0xfff));
268 int64_t AdjustedVal = Val - Imm12;
273 if ((TmpSeq.
size() + 1) < Res.
size()) {
281 if (Val > 0 && Res.
size() > 2) {
287 if (Val < 0 && Res.
size() > 3) {
303 int64_t LoVal = SignExtend64<32>(Val);
304 int64_t HiVal = SignExtend64<32>(Val >> 32);
305 if (LoVal == HiVal) {
308 if ((TmpSeq.
size() + 1) < Res.
size()) {
363 if ((Val % 3) == 0 && isInt<32>(Val / 3)) {
366 }
else if ((Val % 5) == 0 && isInt<32>(Val / 5)) {
369 }
else if ((Val % 9) == 0 && isInt<32>(Val / 9)) {
376 if ((TmpSeq.
size() + 1) < Res.
size()) {
382 int64_t Hi52 = ((
uint64_t)Val + 0x800ull) & ~0xfffull;
383 int64_t Lo12 = SignExtend64<12>(Val);
385 if (isInt<32>(Hi52 / 3) && (Hi52 % 3) == 0) {
388 }
else if (isInt<32>(Hi52 / 5) && (Hi52 % 5) == 0) {
391 }
else if (isInt<32>(Hi52 / 9) && (Hi52 % 9) == 0) {
400 "unexpected instruction sequence for immediate materialisation");
403 if ((TmpSeq.
size() + 2) < Res.
size()) {
415 STI.
hasFeature(RISCV::FeatureVendorXTHeadBb))) {
418 uint64_t NegImm12 = llvm::rotl<uint64_t>(Val, Rotate);
419 assert(isInt<12>(NegImm12));
469 unsigned &ShiftAmt,
unsigned &AddOpc) {
470 int64_t LoVal = SignExtend64<32>(Val);
484 assert(TzLo < 32 && TzHi >= 32);
485 ShiftAmt = TzHi - TzLo;
488 if (Tmp == ((
uint64_t)LoVal << ShiftAmt))
494 AddOpc = RISCV::ADD_UW;
502 bool CompressionCost,
bool FreeZeroes) {
503 bool IsRV64 = STI.
hasFeature(RISCV::Feature64Bit);
506 int PlatRegSize = IsRV64 ? 64 : 32;
511 for (
unsigned ShiftVal = 0; ShiftVal <
Size; ShiftVal += PlatRegSize) {
518 return std::max(FreeZeroes ? 0 : 1,
Cost);
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
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(unsigned 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)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
#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)
SmallVector< Inst, 8 > InstSeq
InstSeq generateTwoRegInstSeq(int64_t Val, const MCSubtargetInfo &STI, unsigned &ShiftAmt, unsigned &AddOpc)
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
This is an optimization pass for GlobalISel generic memory operations.
int popcount(T Value) noexcept
Count the number of set bits in a value.
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.)
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.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
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.