60 if (CFSize >= ((1 << 8) - 1) * 4 / 2)
71 unsigned ScratchReg,
unsigned MIFlags) {
74 if (std::abs(NumBytes) > 508 * 3) {
79 if (ScratchReg == ARM::NoRegister)
83 if (ST.genExecuteOnly()) {
84 unsigned XOInstr = ST.useMovt() ? ARM::t2MOVi32imm : ARM::tMOVi32imm;
128 unsigned Amount =
TII.getFrameSize(Old);
137 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
140 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
162 assert(NumBytes >= ArgRegsSaveSize &&
163 "ArgRegsSaveSize is included in NumBytes");
175 NumBytes = (NumBytes + 3) & ~3;
180 unsigned FRSize = 0, GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
181 int FramePtrSpillFI = 0;
183 if (ArgRegsSaveSize) {
186 CFAOffset += ArgRegsSaveSize;
195 if (NumBytes - ArgRegsSaveSize != 0) {
197 -(NumBytes - ArgRegsSaveSize),
199 CFAOffset += NumBytes - ArgRegsSaveSize;
209 bool HasFrameRecordArea =
hasFP(MF) && ARM::hGPRRegClass.contains(
FramePtr);
213 int FI =
I.getFrameIdx();
215 FramePtrSpillFI = FI;
218 if (HasFrameRecordArea) {
232 if (HasFrameRecordArea) {
249 if (HasFrameRecordArea) {
254 std::advance(
MBBI, 2);
285 unsigned DPRCSOffset = NumBytes - ArgRegsSaveSize -
286 (FRSize + GPRCS1Size + GPRCS2Size + DPRCSSize);
287 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
288 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
289 bool HasFP =
hasFP(MF);
293 if (HasFrameRecordArea)
298 NumBytes = DPRCSOffset;
300 int FramePtrOffsetInBlock = 0;
301 unsigned adjustedGPRCS1Size = GPRCS1Size;
302 if (GPRCS1Size > 0 && GPRCS2Size == 0 &&
304 FramePtrOffsetInBlock = NumBytes;
305 adjustedGPRCS1Size += NumBytes;
308 CFAOffset += adjustedGPRCS1Size;
313 HasFrameRecordArea ? std::next(FRPush) : std::next(GPRCS1Push);
314 if (HasFrameRecordArea) {
322 FramePtrOffsetInBlock +=
326 .
addImm(FramePtrOffsetInBlock / 4)
331 if(FramePtrOffsetInBlock) {
333 nullptr,
MRI->getDwarfRegNum(
FramePtr,
true), (CFAOffset - FramePtrOffsetInBlock)));
334 BuildMI(
MBB, AfterPush, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
341 BuildMI(
MBB, AfterPush, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
352 if (GPRCS1Size > 0) {
354 if (adjustedGPRCS1Size) {
357 BuildMI(
MBB, Pos, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
363 int FI =
I.getFrameIdx();
384 BuildMI(
MBB, Pos, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
393 if (GPRCS2Size > 0) {
395 for (
auto &
I : CSI) {
397 int FI =
I.getFrameIdx();
406 BuildMI(
MBB, Pos, dl,
TII.get(TargetOpcode::CFI_INSTRUCTION))
423 unsigned ScratchRegister = ARM::NoRegister;
424 for (
auto &
I : CSI) {
427 ScratchRegister = Reg;
434 CFAOffset += NumBytes;
451 if (RegInfo->hasStackRealignment(MF)) {
515 assert((
unsigned)NumBytes >= ArgRegsSaveSize &&
516 "ArgRegsSaveSize is included in NumBytes");
520 if (NumBytes - ArgRegsSaveSize != 0)
522 NumBytes - ArgRegsSaveSize, ARM::NoRegister,
543 unsigned ScratchRegister = ARM::NoRegister;
544 bool HasFP =
hasFP(MF);
548 ScratchRegister = Reg;
559 assert(ScratchRegister != ARM::NoRegister &&
560 "No scratch register to restore SP from FP!");
585 if (needPopSpecialFixUp(MF)) {
586 bool Done = emitPopSpecialFixUp(
MBB,
true);
588 assert(
Done &&
"Emission of the special fixup failed!?");
597 return emitPopSpecialFixUp(*TmpMBB,
false);
600bool Thumb1FrameLowering::needPopSpecialFixUp(
const MachineFunction &MF)
const {
608 if (CSI.getReg() == ARM::LR)
619 for (
auto Reg : GPRsNoLRSP.
set_bits()) {
622 if (PopFriendly.
test(Reg)) {
651 bool CanRestoreDirectly =
STI.hasV5TOps() && !ArgRegsSaveSize;
652 if (CanRestoreDirectly) {
654 CanRestoreDirectly = (
MBBI->getOpcode() == ARM::tBX_RET ||
655 MBBI->getOpcode() == ARM::tPOP_RET);
657 auto MBBI_prev =
MBBI;
659 assert(MBBI_prev->getOpcode() == ARM::tPOP);
661 if ((*
MBB.
succ_begin())->begin()->getOpcode() == ARM::tBX_RET)
664 CanRestoreDirectly =
false;
668 if (CanRestoreDirectly) {
669 if (!DoIt ||
MBBI->getOpcode() == ARM::tPOP_RET)
676 for (
auto MO:
MBBI->operands())
677 if (MO.isReg() && (MO.isImplicit() || MO.isDef()))
689 UsedRegs.addLiveOuts(
MBB);
695 for (
unsigned i = 0; CSRegs[i]; ++i)
696 UsedRegs.addReg(CSRegs[i]);
700 dl =
MBBI->getDebugLoc();
701 auto InstUpToMBBI =
MBB.
end();
702 while (InstUpToMBBI !=
MBBI)
705 UsedRegs.stepBackward(*--InstUpToMBBI);
711 unsigned TemporaryReg = 0;
713 TRI.getAllocatableSet(MF,
TRI.getRegClass(ARM::tGPRRegClassID));
718 PopFriendly.
set(ARM::R7);
720 assert(PopFriendly.
any() &&
"No allocatable pop-friendly register?!");
724 TRI.getAllocatableSet(MF,
TRI.getRegClass(ARM::hGPRRegClassID));
725 GPRsNoLRSP |= PopFriendly;
726 GPRsNoLRSP.
reset(ARM::LR);
727 GPRsNoLRSP.
reset(ARM::SP);
728 GPRsNoLRSP.
reset(ARM::PC);
735 bool UseLDRSP =
false;
737 auto PrevMBBI =
MBBI;
739 if (PrevMBBI->getOpcode() == ARM::tPOP) {
740 UsedRegs.stepBackward(*PrevMBBI);
750 if (!DoIt && !PopReg && !TemporaryReg)
753 assert((PopReg || TemporaryReg) &&
"Cannot get LR");
756 assert(PopReg &&
"Do not know how to get LR");
774 ArgRegsSaveSize + 4, ARM::NoRegister,
780 assert(!PopReg &&
"Unnecessary MOV is about to be inserted");
797 for (
auto MO:
MBBI->operands())
798 if (MO.isReg() && (MO.isImplicit() || MO.isDef()) &&
799 MO.getReg() != ARM::PC) {
801 if (!MO.isImplicit())
814 assert(PopReg &&
"Do not know how to get LR");
844 ARM::R0, ARM::R1, ARM::R2, ARM::R3, ARM::R4,
845 ARM::R5, ARM::R6, ARM::R7, ARM::LR};
848 std::set<Register> &LowRegs,
849 std::set<Register> &HighRegs) {
851 if (ARM::tGPRRegClass.
contains(Reg) || Reg == ARM::LR) {
853 }
else if (ARM::hGPRRegClass.
contains(Reg) && Reg != ARM::LR) {
854 HighRegs.insert(Reg);
861template <
typename It>
863 const std::set<Register> &RegSet) {
864 return std::find_if(OrderedStartIt, OrderedEndIt,
865 [&](
Register Reg) {
return RegSet.count(Reg); });
871 const std::set<Register> &RegsToSave,
872 const std::set<Register> &CopyRegs) {
877 std::set<Register> LowRegs, HighRegs;
881 if (!LowRegs.empty()) {
885 if (LowRegs.count(Reg)) {
886 bool isKill = !
MRI.isLiveIn(Reg);
887 if (isKill && !
MRI.isReserved(Reg))
925 if (HighRegs.count(*HiRegToSave)) {
926 bool isKill = !
MRI.isLiveIn(*HiRegToSave);
927 if (isKill && !
MRI.isReserved(*HiRegToSave))
961 const std::set<Register> &RegsToRestore,
962 const std::set<Register> &AvailableCopyRegs,
963 bool IsVarArg,
bool HasV5Ops) {
964 if (RegsToRestore.empty())
971 std::set<Register> LowRegs, HighRegs;
985 std::set<Register> CopyRegs = AvailableCopyRegs;
987 if (!HighRegs.empty() && CopyRegs.empty()) {
990 LowScratchReg = ARM::R0;
996 CopyRegs.insert(LowScratchReg);
1000 assert(!CopyRegs.empty());
1033 if (LowScratchReg.
isValid()) {
1042 if (!LowRegs.empty()) {
1047 bool NeedsPop =
false;
1049 if (!LowRegs.count(Reg))
1052 if (Reg == ARM::LR) {
1054 MI->getOpcode() == ARM::TCRETURNdi ||
1055 MI->getOpcode() == ARM::TCRETURNri)
1076 (*MIB).setDesc(
TII.get(ARM::tPOP_RET));
1107 bool NeedsFrameRecordPush =
hasFP(MF) && ARM::hGPRRegClass.contains(FPReg);
1109 std::set<Register> FrameRecord;
1110 std::set<Register> SpilledGPRs;
1113 if (NeedsFrameRecordPush && (Reg == FPReg || Reg == ARM::LR))
1114 FrameRecord.insert(Reg);
1116 SpilledGPRs.insert(Reg);
1124 std::set<Register> CopyRegs;
1126 if ((ARM::tGPRRegClass.
contains(Reg) || Reg == ARM::LR) &&
1128 CopyRegs.insert(Reg);
1129 for (
unsigned ArgReg : {ARM::R0, ARM::R1, ARM::R2, ARM::R3})
1131 CopyRegs.insert(ArgReg);
1154 bool NeedsFrameRecordPop =
hasFP(MF) && ARM::hGPRRegClass.contains(FPReg);
1156 std::set<Register> FrameRecord;
1157 std::set<Register> SpilledGPRs;
1160 if (NeedsFrameRecordPop && (Reg == FPReg || Reg == ARM::LR))
1161 FrameRecord.insert(Reg);
1163 SpilledGPRs.insert(Reg);
1166 I.setRestored(
false);
1172 std::set<Register> CopyRegs;
1173 std::set<Register> UnusedReturnRegs;
1175 if ((ARM::tGPRRegClass.
contains(Reg)) && !(
hasFP(MF) && Reg == FPReg))
1176 CopyRegs.insert(Reg);
1178 if (Terminator !=
MBB.
end() && Terminator->getOpcode() == ARM::tBX_RET) {
1179 UnusedReturnRegs.insert(ARM::R0);
1180 UnusedReturnRegs.insert(ARM::R1);
1181 UnusedReturnRegs.insert(ARM::R2);
1182 UnusedReturnRegs.insert(ARM::R3);
1183 for (
auto Op : Terminator->implicit_operands()) {
1185 UnusedReturnRegs.erase(
Op.getReg());
1188 CopyRegs.insert(UnusedReturnRegs.begin(), UnusedReturnRegs.end());
1196 assert((!SpilledGPRs.count(ARM::LR) || FrameRecord.empty()) &&
1197 "Can't insert pop after return sequence");
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file implements the BitVector class.
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static void findTemporariesForLR(const BitVector &GPRsNoLRSP, const BitVector &PopFriendly, const LivePhysRegs &UsedRegs, unsigned &PopReg, unsigned &TmpReg, MachineRegisterInfo &MRI)
static void emitCallSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const TargetInstrInfo &TII, const DebugLoc &dl, const ThumbRegisterInfo &MRI, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags)
static const SmallVector< Register > OrderedCopyRegs
static const SmallVector< Register > OrderedLowRegs
static void splitLowAndHighRegs(const std::set< Register > &Regs, std::set< Register > &LowRegs, std::set< Register > &HighRegs)
It getNextOrderedReg(It OrderedStartIt, It OrderedEndIt, const std::set< Register > &RegSet)
static void emitPrologueEpilogueSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const TargetInstrInfo &TII, const DebugLoc &dl, const ThumbRegisterInfo &MRI, int NumBytes, unsigned ScratchReg, unsigned MIFlags)
static const SmallVector< Register > OrderedHighRegs
static void popRegsFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MI, const TargetInstrInfo &TII, const std::set< Register > &RegsToRestore, const std::set< Register > &AvailableCopyRegs, bool IsVarArg, bool HasV5Ops)
static void pushRegsToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const TargetInstrInfo &TII, const std::set< Register > &RegsToSave, const std::set< Register > &CopyRegs)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static const unsigned FramePtr
bool hasBasePointer(const MachineFunction &MF) const
Register getFrameRegister(const MachineFunction &MF) const override
Register getBaseRegister() const
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
void setDPRCalleeSavedAreaSize(unsigned s)
bool hasStackFrame() const
unsigned getGPRCalleeSavedArea1Size() const
void setGPRCalleeSavedArea2Size(unsigned s)
void setDPRCalleeSavedAreaOffset(unsigned o)
void setFramePtrSpillOffset(unsigned o)
unsigned getGPRCalleeSavedArea2Size() const
void setGPRCalleeSavedArea1Size(unsigned s)
bool isCmseNSEntryFunction() const
unsigned getDPRCalleeSavedAreaSize() const
unsigned getFramePtrSpillOffset() const
bool shouldRestoreSPFromFP() const
void setFrameRecordSavedAreaSize(unsigned s)
unsigned getArgRegsSaveSize() const
void setGPRCalleeSavedArea2Offset(unsigned o)
unsigned getFrameRecordSavedAreaSize() const
void setGPRCalleeSavedArea1Offset(unsigned o)
void setShouldRestoreSPFromFP(bool s)
const ARMBaseInstrInfo * getInstrInfo() const override
MCPhysReg getFramePointerReg() const
const ARMBaseRegisterInfo * getRegisterInfo() const override
bool splitFramePushPop(const MachineFunction &MF) const
Returns true if the frame setup is split into two separate pushes (first r0-r7,lr then r8-r11),...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
bool test(unsigned Idx) const
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
bool any() const
any - Returns true if any bit is set.
iterator_range< const_set_bits_iterator > set_bits() const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
This class represents an Operation in the Expression.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
bool available(const MachineRegisterInfo &MRI, MCPhysReg Reg) const
Returns true if register Reg and no aliasing register is in the set.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
succ_iterator succ_begin()
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
int getOffsetAdjustment() const
Return the correction for frame offsets.
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
MachineFunctionProperties & reset(Property P)
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void deleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineModuleInfo & getMMI() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
This class contains meta information specific to a module.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isLiveIn(Register Reg) const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
Thumb1FrameLowering(const ARMSubtarget &sti)
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a epilogue for the target.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Define
Register definition.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Tries to add registers to the reglist of a given base-updating push/pop instruction to adjust the sta...
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
auto reverse(ContainerTy &&C)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=0)
emitThumbRegPlusImmediate - Emits a series of instructions to materialize a destreg = basereg + immed...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
unsigned Log2(Align A)
Returns the log2 of the alignment.