22 void MipsAnalyzeImmediate::AddInstr(
InstSeqLs &SeqLs,
const Inst &
I) {
33 void MipsAnalyzeImmediate::GetInstSeqLsADDiu(uint64_t Imm,
unsigned RemSize,
35 GetInstSeqLs((Imm + 0x8000ULL) & 0xffffffffffff0000ULL, RemSize, SeqLs);
36 AddInstr(SeqLs,
Inst(ADDiu, Imm & 0xffffULL));
39 void MipsAnalyzeImmediate::GetInstSeqLsORi(uint64_t Imm,
unsigned RemSize,
41 GetInstSeqLs(Imm & 0xffffffffffff0000ULL, RemSize, SeqLs);
42 AddInstr(SeqLs,
Inst(ORi, Imm & 0xffffULL));
45 void MipsAnalyzeImmediate::GetInstSeqLsSLL(uint64_t Imm,
unsigned RemSize,
48 GetInstSeqLs(Imm >> Shamt, RemSize - Shamt, SeqLs);
49 AddInstr(SeqLs,
Inst(SLL, Shamt));
52 void MipsAnalyzeImmediate::GetInstSeqLs(uint64_t Imm,
unsigned RemSize,
54 uint64_t MaskedImm = Imm & (0xffffffffffffffffULL >> (64 - Size));
62 AddInstr(SeqLs,
Inst(ADDiu, MaskedImm));
67 if (!(Imm & 0xffff)) {
68 GetInstSeqLsSLL(Imm, RemSize, SeqLs);
72 GetInstSeqLsADDiu(Imm, RemSize, SeqLs);
78 GetInstSeqLsORi(Imm, RemSize, SeqLsORi);
79 SeqLs.
append(std::make_move_iterator(SeqLsORi.
begin()),
80 std::make_move_iterator(SeqLsORi.
end()));
90 void MipsAnalyzeImmediate::ReplaceADDiuSLLWithLUi(
InstSeq &Seq) {
93 if ((Seq.
size() < 2) || (Seq[0].
Opc != ADDiu) ||
94 (Seq[1].Opc != SLL) || (Seq[1].
ImmOpnd < 16))
98 int64_t Imm = SignExtend64<16>(Seq[0].ImmOpnd);
99 int64_t ShiftedImm = (uint64_t)Imm << (Seq[1].
ImmOpnd - 16);
106 Seq[0].ImmOpnd = (
unsigned)(ShiftedImm & 0xffff);
110 void MipsAnalyzeImmediate::GetShortestSeq(
InstSeqLs &SeqLs,
InstSeq &Insts) {
113 unsigned ShortestLength = 8;
116 ReplaceADDiuSLLWithLUi(*S);
119 if (S->size() < ShortestLength) {
121 ShortestLength = S->size();
126 Insts.
append(ShortestSeq->begin(), ShortestSeq->end());
131 bool LastInstrIsADDiu) {
140 ADDiu = Mips::DADDiu;
149 if (LastInstrIsADDiu | !Imm)
150 GetInstSeqLsADDiu(Imm, Size, SeqLs);
152 GetInstSeqLs(Imm, Size, SeqLs);
155 GetShortestSeq(SeqLs, Insts);
This class represents lattice values for constants.
void push_back(const T &Elt)
constexpr bool isInt< 16 >(int64_t x)
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
iterator erase(const_iterator CI)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
typename SuperClass::iterator iterator
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
LLVM_NODISCARD bool empty() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())