Preliminary support for ARM frame save directives emission via MI flags.

This is just very first approximation how the stuff should be done
(e.g. ARM-only for now). More to follow.

llvm-svn: 127101
This commit is contained in:
Anton Korobeynikov 2011-03-05 18:43:32 +00:00
parent 961013686e
commit e7410dd0d5
18 changed files with 215 additions and 50 deletions

View File

@ -41,6 +41,9 @@ public:
/// getOpcodeName - Return the name of the specified opcode enum (e.g.
/// "MOV32ri") or empty if we can't resolve it.
virtual StringRef getOpcodeName(unsigned Opcode) const;
/// getRegName - Return the assembler register name.
virtual StringRef getRegName(unsigned RegNo) const;
};
} // namespace llvm

View File

@ -465,6 +465,10 @@ namespace llvm {
virtual void EmitCantUnwind();
virtual void EmitPersonality(const MCSymbol *Personality);
virtual void EmitHandlerData();
virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
virtual void EmitPad(int64_t Offset);
virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector);
/// Finish - Finish emission of machine code.
virtual void Finish() = 0;

View File

@ -197,6 +197,10 @@ public:
virtual void EmitCantUnwind();
virtual void EmitPersonality(const MCSymbol *Personality);
virtual void EmitHandlerData();
virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
virtual void EmitPad(int64_t Offset);
virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool);
virtual void EmitInstruction(const MCInst &Inst);
@ -890,6 +894,36 @@ void MCAsmStreamer::EmitPersonality(const MCSymbol *Personality) {
EmitEOL();
}
void MCAsmStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
OS << "\t.setfp\t" << InstPrinter->getRegName(FpReg)
<< ", " << InstPrinter->getRegName(SpReg);
if (Offset)
OS << ", #" << Offset;
EmitEOL();
}
void MCAsmStreamer::EmitPad(int64_t Offset) {
OS << "\t.pad\t#" << Offset;
EmitEOL();
}
void MCAsmStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector) {
assert(RegList.size() && "RegList should not be empty");
if (isVector)
OS << "\t.vsave\t{";
else
OS << "\t.save\t{";
OS << InstPrinter->getRegName(RegList[0]);
for (unsigned i = 1, e = RegList.size(); i != e; ++i)
OS << ", " << InstPrinter->getRegName(RegList[i]);
OS << "}";
EmitEOL();
}
void MCAsmStreamer::EmitInstruction(const MCInst &Inst) {
assert(getCurrentSection() && "Cannot emit contents before setting section!");

View File

@ -19,3 +19,8 @@ MCInstPrinter::~MCInstPrinter() {
StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const {
return "";
}
StringRef MCInstPrinter::getRegName(unsigned RegNo) const {
assert(0 && "Target should implement this");
return "";
}

View File

@ -284,6 +284,21 @@ void MCStreamer::EmitPersonality(const MCSymbol *Personality) {
abort();
}
void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::EmitPad(int64_t Offset) {
errs() << "Not implemented yet\n";
abort();
}
void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) {
errs() << "Not implemented yet\n";
abort();
}
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.

View File

@ -811,6 +811,87 @@ void ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI,
OutStreamer.EmitInstruction(TmpInst);
}
void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
assert(MI->getFlag(MachineInstr::FrameSetup) &&
"Only instruction which are involved into frame setup code are allowed");
const MachineFunction &MF = *MI->getParent()->getParent();
const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
unsigned FramePtr = RegInfo->getFrameRegister(MF);
unsigned SrcReg = MI->getOperand(1).getReg();
unsigned DstReg = MI->getOperand(0).getReg();
unsigned Opc = MI->getOpcode();
// Try to figure out the unwinding opcode out of src / dst regs.
if (MI->getDesc().mayStore()) {
// Register saves.
assert(DstReg == ARM::SP &&
"Only stack pointer as a destination reg is supported");
SmallVector<unsigned, 4> RegList;
switch (Opc) {
default:
MI->dump();
assert(0 && "Unsupported opcode for unwinding information");
case ARM::STMDB_UPD:
case ARM::VSTMDDB_UPD:
assert(SrcReg == ARM::SP &&
"Only stack pointer as a source reg is supported");
for (unsigned i = 4, NumOps = MI->getNumOperands(); i != NumOps; ++i)
RegList.push_back(MI->getOperand(i).getReg());
break;
case ARM::STR_PRE:
assert(MI->getOperand(2).getReg() == ARM::SP &&
"Only stack pointer as a source reg is supported");
RegList.push_back(SrcReg);
break;
}
OutStreamer.EmitRegSave(RegList, Opc == ARM::VSTMDDB_UPD);
} else {
// Changes of stack / frame pointer.
if (SrcReg == ARM::SP) {
int64_t Offset = 0;
switch (Opc) {
default:
MI->dump();
assert(0 && "Unsupported opcode for unwinding information");
case ARM::MOVr:
Offset = 0;
break;
case ARM::ADDri:
Offset = -MI->getOperand(2).getImm();
break;
case ARM::SUBri:
Offset = MI->getOperand(2).getImm();
break;
}
if (DstReg == FramePtr && FramePtr != ARM::SP)
// Set-up of the frame pointer.
OutStreamer.EmitSetFP(FramePtr, ARM::SP, Offset);
else if (DstReg == ARM::SP) {
// Change of SP by an offset. Positive values corresponds to "sub"
// instruction.
OutStreamer.EmitPad(Offset);
} else {
MI->dump();
assert(0 && "Unsupported opcode for unwinding information");
}
} else if (DstReg == ARM::SP) {
// FIXME: .movsp goes here
MI->dump();
assert(0 && "Unsupported opcode for unwinding information");
}
else {
MI->dump();
assert(0 && "Unsupported opcode for unwinding information");
}
}
}
extern cl::opt<bool> EnableARMEHABI;
void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
unsigned Opc = MI->getOpcode();
switch (Opc) {
@ -1564,6 +1645,11 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInst TmpInst;
LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
// Emit unwinding stuff for frame-related instructions
if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup))
EmitUnwindingInstruction(MI);
OutStreamer.EmitInstruction(TmpInst);
}

View File

@ -82,6 +82,8 @@ private:
// Generic helper used to emit e.g. ARMv5 mul pseudos
void EmitPatchedInstruction(const MachineInstr *MI, unsigned TargetOpc);
void EmitUnwindingInstruction(const MachineInstr *MI);
public:
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);

View File

@ -1328,7 +1328,7 @@ void llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, DebugLoc dl,
unsigned DestReg, unsigned BaseReg, int NumBytes,
ARMCC::CondCodes Pred, unsigned PredReg,
const ARMBaseInstrInfo &TII) {
const ARMBaseInstrInfo &TII, unsigned MIFlags) {
bool isSub = NumBytes < 0;
if (isSub) NumBytes = -NumBytes;
@ -1346,7 +1346,8 @@ void llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB,
unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
.addReg(BaseReg, RegState::Kill).addImm(ThisVal)
.addImm((unsigned)Pred).addReg(PredReg).addReg(0);
.addImm((unsigned)Pred).addReg(PredReg).addReg(0)
.setMIFlags(MIFlags);
BaseReg = DestReg;
}
}

View File

@ -496,19 +496,19 @@ void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, DebugLoc dl,
unsigned DestReg, unsigned BaseReg, int NumBytes,
ARMCC::CondCodes Pred, unsigned PredReg,
const ARMBaseInstrInfo &TII);
const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
void emitT2RegPlusImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, DebugLoc dl,
unsigned DestReg, unsigned BaseReg, int NumBytes,
ARMCC::CondCodes Pred, unsigned PredReg,
const ARMBaseInstrInfo &TII);
const ARMBaseInstrInfo &TII, unsigned MIFlags = 0);
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
MachineBasicBlock::iterator &MBBI, DebugLoc dl,
unsigned DestReg, unsigned BaseReg,
int NumBytes, const TargetInstrInfo &TII,
const ARMBaseRegisterInfo& MRI,
DebugLoc dl);
unsigned MIFlags = 0);
/// rewriteARMFrameIndex / rewriteT2FrameIndex -

View File

@ -726,9 +726,8 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
llvm::emitT2RegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
FramePtr, -NumBytes, ARMCC::AL, 0, *TII);
} else if (AFI->isThumbFunction()) {
llvm::emitThumbRegPlusImmediate(MBB, MBBI, ARM::R6,
FramePtr, -NumBytes,
*TII, RI, MI.getDebugLoc());
llvm::emitThumbRegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
FramePtr, -NumBytes, *TII, RI);
} else {
llvm::emitARMRegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
FramePtr, -NumBytes, ARMCC::AL, 0,

View File

@ -106,14 +106,13 @@ static void
emitSPUpdate(bool isARM,
MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
DebugLoc dl, const ARMBaseInstrInfo &TII,
int NumBytes,
ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
int NumBytes, unsigned MIFlags = MachineInstr::NoFlags) {
if (isARM)
emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
Pred, PredReg, TII);
ARMCC::AL, 0, TII, MIFlags);
else
emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
Pred, PredReg, TII);
ARMCC::AL, 0, TII, MIFlags);
}
void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
@ -141,11 +140,13 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
// Allocate the vararg register save area. This is not counted in NumBytes.
if (VARegSaveSize)
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize);
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize,
MachineInstr::FrameSetup);
if (!AFI->hasStackFrame()) {
if (NumBytes != 0)
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes);
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
MachineInstr::FrameSetup);
return;
}
@ -196,7 +197,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
MachineInstrBuilder MIB =
BuildMI(MBB, MBBI, dl, TII.get(ADDriOpc), FramePtr)
.addFrameIndex(FramePtrSpillFI).addImm(0);
.addFrameIndex(FramePtrSpillFI).addImm(0)
.setMIFlag(MachineInstr::FrameSetup);
AddDefaultCC(AddDefaultPred(MIB));
}
@ -226,7 +228,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
NumBytes = DPRCSOffset;
if (NumBytes) {
// Adjust SP after all the callee-save spills.
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes);
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes,
MachineInstr::FrameSetup);
if (HasFP && isARM)
// Restore from fp only in ARM mode: e.g. sub sp, r7, #24
// Note it's not safe to do this in Thumb2 mode because it would have
@ -282,6 +285,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
// of the stack pointer is at this point. Any variable size objects
// will be allocated after this, so we can still use the base pointer
// to reference locals.
// FIXME: Clarify FrameSetup flags here.
if (RegInfo->hasBasePointer(MF)) {
if (isARM)
BuildMI(MBB, MBBI, dl,
@ -524,7 +528,8 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
const std::vector<CalleeSavedInfo> &CSI,
unsigned StmOpc, unsigned StrOpc,
bool NoGap,
bool(*Func)(unsigned, bool)) const {
bool(*Func)(unsigned, bool),
unsigned MIFlags) const {
MachineFunction &MF = *MBB.getParent();
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
@ -567,14 +572,14 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
if (Regs.size() > 1 || StrOpc== 0) {
MachineInstrBuilder MIB =
AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(StmOpc), ARM::SP)
.addReg(ARM::SP));
.addReg(ARM::SP).setMIFlags(MIFlags));
for (unsigned i = 0, e = Regs.size(); i < e; ++i)
MIB.addReg(Regs[i].first, getKillRegState(Regs[i].second));
} else if (Regs.size() == 1) {
MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc),
ARM::SP)
.addReg(Regs[0].first, getKillRegState(Regs[0].second))
.addReg(ARM::SP);
.addReg(ARM::SP).setMIFlags(MIFlags);
// ARM mode needs an extra reg0 here due to addrmode2. Will go away once
// that refactoring is complete (eventually).
if (StrOpc == ARM::STR_PRE) {
@ -676,9 +681,12 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
unsigned PushOpc = AFI->isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD;
unsigned PushOneOpc = AFI->isThumbFunction() ? ARM::t2STR_PRE : ARM::STR_PRE;
unsigned FltOpc = ARM::VSTMDDB_UPD;
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register);
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea2Register);
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register);
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register,
MachineInstr::FrameSetup);
emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea2Register,
MachineInstr::FrameSetup);
emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register,
MachineInstr::FrameSetup);
return true;
}

View File

@ -62,7 +62,8 @@ public:
void emitPushInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI, unsigned StmOpc,
unsigned StrOpc, bool NoGap,
bool(*Func)(unsigned, bool)) const;
bool(*Func)(unsigned, bool),
unsigned MIFlags = 0) const;
void emitPopInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI, unsigned LdmOpc,
unsigned LdrOpc, bool isVarArg, bool NoGap,

View File

@ -16,7 +16,7 @@
using namespace llvm;
static cl::opt<bool>
cl::opt<bool>
EnableARMEHABI("arm-enable-ehabi", cl::Hidden,
cl::desc("Generate ARM EHABI tables"),
cl::init(false));

View File

@ -29,6 +29,9 @@ StringRef ARMInstPrinter::getOpcodeName(unsigned Opcode) const {
return getInstructionName(Opcode);
}
StringRef ARMInstPrinter::getRegName(unsigned RegNo) const {
return getRegisterName(RegNo);
}
void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
unsigned Opcode = MI->getOpcode();

View File

@ -25,6 +25,7 @@ public:
virtual void printInst(const MCInst *MI, raw_ostream &O);
virtual StringRef getOpcodeName(unsigned Opcode) const;
virtual StringRef getRegName(unsigned RegNo) const;
static const char *getInstructionName(unsigned Opcode);

View File

@ -39,8 +39,8 @@ static void emitSPUpdate(MachineBasicBlock &MBB,
const TargetInstrInfo &TII, DebugLoc dl,
const Thumb1RegisterInfo &MRI,
int NumBytes) {
emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
MRI, dl);
emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII,
MRI);
}
void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
@ -232,8 +232,8 @@ void Thumb1FrameLowering::emitEpilogue(MachineFunction &MF,
if (NumBytes) {
assert(MF.getRegInfo().isPhysRegUsed(ARM::R4) &&
"No scratch register to restore SP from FP!");
emitThumbRegPlusImmediate(MBB, MBBI, ARM::R4, FramePtr, -NumBytes,
TII, *RegInfo, dl);
emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes,
TII, *RegInfo);
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
.addReg(ARM::R4);
} else

View File

@ -151,10 +151,10 @@ static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
/// a destreg = basereg + immediate in Thumb code.
void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
DebugLoc dl,
unsigned DestReg, unsigned BaseReg,
int NumBytes, const TargetInstrInfo &TII,
const ARMBaseRegisterInfo& MRI,
DebugLoc dl) {
const ARMBaseRegisterInfo& MRI, unsigned) {
bool isSub = NumBytes < 0;
unsigned Bytes = (unsigned)NumBytes;
if (isSub) Bytes = -NumBytes;
@ -283,8 +283,8 @@ static void emitSPUpdate(MachineBasicBlock &MBB,
const TargetInstrInfo &TII, DebugLoc dl,
const Thumb1RegisterInfo &MRI,
int NumBytes) {
emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII,
MRI, dl);
emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII,
MRI);
}
void Thumb1RegisterInfo::
@ -337,7 +337,7 @@ static void emitThumbConstant(MachineBasicBlock &MBB,
DestReg))
.addImm(ThisVal));
if (Imm > 0)
emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl);
emitThumbRegPlusImmediate(MBB, MBBI, dl, DestReg, DestReg, Imm, TII, MRI);
if (isSub) {
const TargetInstrDesc &TID = TII.get(ARM::tRSB);
AddDefaultPred(AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TID, DestReg))
@ -430,8 +430,8 @@ rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx,
// MI would expand into a large number of instructions. Don't try to
// simplify the immediate.
if (NumMIs > 2) {
emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII,
*this, dl);
emitThumbRegPlusImmediate(MBB, II, dl, DestReg, FrameReg, Offset, TII,
*this);
MBB.erase(II);
return true;
}
@ -450,8 +450,8 @@ rewriteFrameIndex(MachineBasicBlock::iterator II, unsigned FrameRegIdx,
}
Offset = (Offset - Mask * Scale);
MachineBasicBlock::iterator NII = llvm::next(II);
emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII,
*this, dl);
emitThumbRegPlusImmediate(MBB, NII, dl, DestReg, DestReg, Offset, TII,
*this);
} else {
// Translate r0 = add sp, -imm to
// r0 = -imm (this is then translated into a series of instructons)
@ -652,8 +652,8 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
UseRR = true;
}
} else {
emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII,
*this, dl);
emitThumbRegPlusImmediate(MBB, II, dl, TmpReg, FrameReg, Offset, TII,
*this);
}
MI.setDesc(TII.get(UseRR ? ARM::tLDRr : ARM::tLDRi));
@ -675,8 +675,8 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
UseRR = true;
}
} else
emitThumbRegPlusImmediate(MBB, II, VReg, FrameReg, Offset, TII,
*this, dl);
emitThumbRegPlusImmediate(MBB, II, dl, VReg, FrameReg, Offset, TII,
*this);
MI.setDesc(TII.get(UseRR ? ARM::tSTRr : ARM::tSTRi));
MI.getOperand(i).ChangeToRegister(VReg, false, false, true);
if (UseRR)

View File

@ -184,7 +184,7 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, DebugLoc dl,
unsigned DestReg, unsigned BaseReg, int NumBytes,
ARMCC::CondCodes Pred, unsigned PredReg,
const ARMBaseInstrInfo &TII) {
const ARMBaseInstrInfo &TII, unsigned MIFlags) {
bool isSub = NumBytes < 0;
if (isSub) NumBytes = -NumBytes;
@ -198,14 +198,14 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
// Use a movw to materialize the 16-bit constant.
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), DestReg)
.addImm(NumBytes)
.addImm((unsigned)Pred).addReg(PredReg);
.addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
Fits = true;
} else if ((NumBytes & 0xffff) == 0) {
// Use a movt to materialize the 32-bit constant.
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVTi16), DestReg)
.addReg(DestReg)
.addImm(NumBytes >> 16)
.addImm((unsigned)Pred).addReg(PredReg);
.addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
Fits = true;
}
@ -214,12 +214,14 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr), DestReg)
.addReg(BaseReg, RegState::Kill)
.addReg(DestReg, RegState::Kill)
.addImm((unsigned)Pred).addReg(PredReg).addReg(0);
.addImm((unsigned)Pred).addReg(PredReg).addReg(0)
.setMIFlags(MIFlags);
} else {
BuildMI(MBB, MBBI, dl, TII.get(ARM::t2ADDrr), DestReg)
.addReg(DestReg, RegState::Kill)
.addReg(BaseReg, RegState::Kill)
.addImm((unsigned)Pred).addReg(PredReg).addReg(0);
.addImm((unsigned)Pred).addReg(PredReg).addReg(0)
.setMIFlags(MIFlags);
}
return;
}
@ -230,7 +232,8 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
unsigned Opc = 0;
if (DestReg == ARM::SP && BaseReg != ARM::SP) {
// mov sp, rn. Note t2MOVr cannot be used.
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),DestReg).addReg(BaseReg);
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr),DestReg)
.addReg(BaseReg).setMIFlags(MIFlags);
BaseReg = ARM::SP;
continue;
}
@ -243,7 +246,7 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
// FIXME: Fix Thumb1 immediate encoding.
BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
.addReg(BaseReg).addImm(ThisVal/4);
.addReg(BaseReg).addImm(ThisVal/4).setMIFlags(MIFlags);
NumBytes = 0;
continue;
}
@ -283,7 +286,7 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
MachineInstrBuilder MIB =
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
.addReg(BaseReg, RegState::Kill)
.addImm(ThisVal));
.addImm(ThisVal)).setMIFlags(MIFlags);
if (HasCCOut)
AddDefaultCC(MIB);