}
bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+ Subtarget = &TM.getSubtarget<MipsSubtarget>();
+
// Initialize TargetLoweringObjectFile.
- if (Subtarget->allowMixed16_32())
- const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
+ const_cast<TargetLoweringObjectFile &>(getObjFileLowering())
.Initialize(OutContext, TM);
+
MipsFI = MF.getInfo<MipsFunctionInfo>();
if (Subtarget->inMips16Mode())
for (std::map<
#include "MipsGenMCPseudoLowering.inc"
+// Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM,
+// JALR, or JALR64 as appropriate for the target
+void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
+ const MachineInstr *MI) {
+ bool HasLinkReg = false;
+ MCInst TmpInst0;
+
+ if (Subtarget->hasMips64r6()) {
+ // MIPS64r6 should use (JALR64 ZERO_64, $rs)
+ TmpInst0.setOpcode(Mips::JALR64);
+ HasLinkReg = true;
+ } else if (Subtarget->hasMips32r6()) {
+ // MIPS32r6 should use (JALR ZERO, $rs)
+ TmpInst0.setOpcode(Mips::JALR);
+ HasLinkReg = true;
+ } else if (Subtarget->inMicroMipsMode())
+ // microMIPS should use (JR_MM $rs)
+ TmpInst0.setOpcode(Mips::JR_MM);
+ else {
+ // Everything else should use (JR $rs)
+ TmpInst0.setOpcode(Mips::JR);
+ }
+
+ MCOperand MCOp;
+
+ if (HasLinkReg) {
+ unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
+ TmpInst0.addOperand(MCOperand::CreateReg(ZeroReg));
+ }
+
+ lowerOperand(MI->getOperand(0), MCOp);
+ TmpInst0.addOperand(MCOp);
+
+ EmitToStreamer(OutStreamer, TmpInst0);
+}
+
void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MipsTargetStreamer &TS = getTargetStreamer();
TS.setCanHaveModuleDir(false);
+
if (MI->isDebugValue()) {
SmallString<128> Str;
raw_svector_ostream OS(Str);
if (emitPseudoExpansionLowering(OutStreamer, &*I))
continue;
+ if (I->getOpcode() == Mips::PseudoReturn ||
+ I->getOpcode() == Mips::PseudoReturn64 ||
+ I->getOpcode() == Mips::PseudoIndirectBranch ||
+ I->getOpcode() == Mips::PseudoIndirectBranch64) {
+ emitPseudoIndirectBranch(OutStreamer, &*I);
+ continue;
+ }
+
// The inMips16Mode() test is not permanent.
// Some instructions are marked as pseudo right now which
// would make the test fail for the wrong reason but
if (Mips::GPR32RegClass.contains(Reg))
break;
- unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg);
+ unsigned RegNum =
+ TM.getSubtargetImpl()->getRegisterInfo()->getEncodingValue(Reg);
if (Mips::AFGR64RegClass.contains(Reg)) {
FPUBitmask |= (3 << RegNum);
CSFPRegsSize += AFGR64RegSize;
// Set CPU Bitmask.
for (; i != e; ++i) {
unsigned Reg = CSI[i].getReg();
- unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg);
+ unsigned RegNum =
+ TM.getSubtargetImpl()->getRegisterInfo()->getEncodingValue(Reg);
CPUBitmask |= (1 << RegNum);
}
/// Frame Directive
void MipsAsmPrinter::emitFrameDirective() {
- const TargetRegisterInfo &RI = *TM.getRegisterInfo();
+ const TargetRegisterInfo &RI = *TM.getSubtargetImpl()->getRegisterInfo();
unsigned stackReg = RI.getFrameRegister(*MF);
unsigned returnReg = RI.getRARegister();
void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
raw_ostream &O) {
- const DataLayout *DL = TM.getDataLayout();
+ const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout();
const MachineOperand &MO = MI->getOperand(opNum);
bool closeP = false;
bool IsABICalls = true;
if (IsABICalls) {
getTargetStreamer().emitDirectiveAbiCalls();
- Reloc::Model RM = Subtarget->getRelocationModel();
+ Reloc::Model RM = TM.getRelocationModel();
// FIXME: This condition should be a lot more complicated that it is here.
// Ideally it should test for properties of the ABI and not the ABI
// itself.
OutContext.getELFSection(".gcc_compiled_long64", ELF::SHT_PROGBITS, 0,
SectionKind::getDataRel()));
}
+
getTargetStreamer().updateABIInfo(*Subtarget);
- unsigned FpAbiVal;
- if (Subtarget->isABI_N32() || Subtarget->isABI_N64())
- FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
- else if(Subtarget->isABI_O32()) {
- if (Subtarget->isFP64bit())
- FpAbiVal = Val_GNU_MIPS_ABI_FP_64;
- else if(Subtarget->isABI_FPXX())
- FpAbiVal = Val_GNU_MIPS_ABI_FP_XX;
- else
- FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
- }
- getTargetStreamer().emitDirectiveModule(FpAbiVal, Subtarget->isABI_O32());
+
+ // We should always emit a '.module fp=...' but binutils 2.24 does not accept
+ // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
+ // -mfp64) and omit it otherwise.
+ if (Subtarget->isABI_O32() && (Subtarget->isABI_FPXX() ||
+ Subtarget->isFP64bit()))
+ getTargetStreamer().emitDirectiveModuleFP();
+
+ // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
+ // accept it. We therefore emit it when it contradicts the default or an
+ // option has changed the default (i.e. FPXX) and omit it otherwise.
+ if (Subtarget->isABI_O32() && (!Subtarget->useOddSPReg() ||
+ Subtarget->isABI_FPXX()))
+ getTargetStreamer().emitDirectiveModuleOddSPReg(Subtarget->useOddSPReg(),
+ Subtarget->isABI_O32());
}
void MipsAsmPrinter::EmitJal(MCSymbol *Symbol) {