// Build an instruction sequence to load an immediate that is too large to fit // in 16-bit and add the result to Reg. static void expandLargeImm(unsigned Reg, int64_t Imm, const Cpu0InstrInfo &TII, MachineBasicBlock& MBB, MachineBasicBlock::iterator II, DebugLoc DL) { unsigned LUi = Cpu0::LUi; unsigned ADDu = Cpu0::ADDu; unsigned ZEROReg = Cpu0::ZERO; unsigned ATReg = Cpu0::AT; Cpu0AnalyzeImmediate AnalyzeImm; const Cpu0AnalyzeImmediate::InstSeq &Seq = AnalyzeImm.Analyze(Imm, 32, false /* LastInstrIsADDiu */); Cpu0AnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); // The first instruction can be a LUi, which is different from other // instructions (ADDiu, ORI and SLL) in that it does not have a register // operand. if (Inst->Opc == LUi) BuildMI(MBB, II, DL, TII.get(LUi), ATReg) .addImm(SignExtend64<16>(Inst->ImmOpnd)); else BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ZEROReg) .addImm(SignExtend64<16>(Inst->ImmOpnd)); // Build the remaining instructions in Seq. for (++Inst; Inst != Seq.end(); ++Inst) BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ATReg) .addImm(SignExtend64<16>(Inst->ImmOpnd)); BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(Reg).addReg(ATReg); } // lbd document - mark - expandLargeImm
// Build an instruction sequence to load an immediate that is too large to fit // in 16-bit and add the result to Reg. static void expandLargeImm(unsigned Reg, int64_t Imm, const Cpu0InstrInfo &TII, MachineBasicBlock& MBB, MachineBasicBlock::iterator II, DebugLoc DL) { unsigned ADDu = Cpu0::ADDu; unsigned ZEROReg = Cpu0::ZERO; unsigned ATReg = Cpu0::AT; Cpu0AnalyzeImmediate AnalyzeImm; const Cpu0AnalyzeImmediate::InstSeq &Seq = AnalyzeImm.Analyze(Imm, 32, false /* LastInstrIsADDiu */); Cpu0AnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ZEROReg) .addImm(SignExtend64<16>(Inst->ImmOpnd)); // Build the remaining instructions in Seq. for (++Inst; Inst != Seq.end(); ++Inst) BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ATReg) .addImm(SignExtend64<16>(Inst->ImmOpnd)); BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(Reg).addReg(ATReg); }
/// This function generates the sequence of instructions needed to get the /// result of adding register REG and immediate IMM. unsigned Cpu0SEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, unsigned *NewImm) const { Cpu0AnalyzeImmediate AnalyzeImm; unsigned Size = 32; unsigned LUi = Cpu0::LUi; unsigned ZEROReg = Cpu0::ZERO; unsigned ATReg = Cpu0::AT; bool LastInstrIsADDiu = NewImm; const Cpu0AnalyzeImmediate::InstSeq &Seq = AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu); Cpu0AnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); assert(Seq.size() && (!LastInstrIsADDiu || (Seq.size() > 1))); // The first instruction can be a LUi, which is different from other // instructions (ADDiu, ORI and SLL) in that it does not have a register // operand. if (Inst->Opc == LUi) BuildMI(MBB, II, DL, get(LUi), ATReg).addImm(SignExtend64<16>(Inst->ImmOpnd)); else BuildMI(MBB, II, DL, get(Inst->Opc), ATReg).addReg(ZEROReg) .addImm(SignExtend64<16>(Inst->ImmOpnd)); // Build the remaining instructions in Seq. for (++Inst; Inst != Seq.end() - LastInstrIsADDiu; ++Inst) BuildMI(MBB, II, DL, get(Inst->Opc), ATReg).addReg(ATReg) .addImm(SignExtend64<16>(Inst->ImmOpnd)); if (LastInstrIsADDiu) *NewImm = Inst->ImmOpnd; return ATReg; }