forked from OSchip/llvm-project
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:
parent
961013686e
commit
e7410dd0d5
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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!");
|
||||
|
||||
|
|
|
@ -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 "";
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 -
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue