diff options
Diffstat (limited to 'lib/Target/Mips')
51 files changed, 750 insertions, 611 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 1040bf7..6401bc1 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" #include <memory> using namespace llvm; @@ -53,7 +54,13 @@ public: } unsigned getATRegNum() const { return ATReg; } - bool setATReg(unsigned Reg); + bool setATReg(unsigned Reg) { + if (Reg > 31) + return false; + + ATReg = Reg; + return true; + } bool isReorder() const { return Reorder; } void setReorder() { Reorder = true; } @@ -193,6 +200,9 @@ class MipsAsmParser : public MCTargetAsmParser { bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions); + void createNop(bool hasShortDelaySlot, SMLoc IDLoc, + SmallVectorImpl<MCInst> &Instructions); + bool reportParseError(Twine ErrorMsg); bool reportParseError(SMLoc Loc, Twine ErrorMsg); @@ -236,6 +246,8 @@ class MipsAsmParser : public MCTargetAsmParser { bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI, StringRef Directive); + bool parseInternalDirectiveReallowModule(); + MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); bool eatComma(StringRef ErrorStr); @@ -1365,22 +1377,11 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, } } + // If this instruction has a delay slot and .set reorder is active, + // emit a NOP after it. if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) { - // If this instruction has a delay slot and .set reorder is active, - // emit a NOP after it. Instructions.push_back(Inst); - MCInst NopInst; - if (hasShortDelaySlot(Inst.getOpcode())) { - NopInst.setOpcode(Mips::MOVE16_MM); - NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); - NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); - } else { - NopInst.setOpcode(Mips::SLL); - NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); - NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); - NopInst.addOperand(MCOperand::CreateImm(0)); - } - Instructions.push_back(NopInst); + createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions); return false; } @@ -1584,10 +1585,10 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, bool MipsAsmParser::needsExpansion(MCInst &Inst) { switch (Inst.getOpcode()) { - case Mips::LoadImm32Reg: - case Mips::LoadAddr32Imm: - case Mips::LoadAddr32Reg: - case Mips::LoadImm64Reg: + case Mips::LoadImm32: + case Mips::LoadImm64: + case Mips::LoadAddrImm32: + case Mips::LoadAddrReg32: case Mips::B_MM_Pseudo: case Mips::LWM_MM: case Mips::SWM_MM: @@ -1603,17 +1604,17 @@ bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) { switch (Inst.getOpcode()) { default: llvm_unreachable("unimplemented expansion"); - case Mips::LoadImm32Reg: + case Mips::LoadImm32: return expandLoadImm(Inst, IDLoc, Instructions); - case Mips::LoadImm64Reg: + case Mips::LoadImm64: if (!isGP64bit()) { Error(IDLoc, "instruction requires a 64-bit architecture"); return true; } return expandLoadImm(Inst, IDLoc, Instructions); - case Mips::LoadAddr32Imm: + case Mips::LoadAddrImm32: return expandLoadAddressImm(Inst, IDLoc, Instructions); - case Mips::LoadAddr32Reg: + case Mips::LoadAddrReg32: return expandLoadAddressReg(Inst, IDLoc, Instructions); case Mips::B_MM_Pseudo: return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions); @@ -1982,14 +1983,10 @@ bool MipsAsmParser::expandUncondBranchMMPseudo( } Instructions.push_back(Inst); - if (AssemblerOptions.back()->isReorder()) { - // If .set reorder is active, emit a NOP after the branch instruction. - MCInst NopInst; - NopInst.setOpcode(Mips::MOVE16_MM); - NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); - NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); - Instructions.push_back(NopInst); - } + // If .set reorder is active, emit a NOP after the branch instruction. + if (AssemblerOptions.back()->isReorder()) + createNop(true, IDLoc, Instructions); + return false; } @@ -2132,6 +2129,22 @@ MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, return false; } +void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc, + SmallVectorImpl<MCInst> &Instructions) { + MCInst NopInst; + if (hasShortDelaySlot) { + NopInst.setOpcode(Mips::MOVE16_MM); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + } else { + NopInst.setOpcode(Mips::SLL); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + NopInst.addOperand(MCOperand::CreateImm(0)); + } + Instructions.push_back(NopInst); +} + unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { // As described by the Mips32r2 spec, the registers Rd and Rs for // jalr.hb must be different. @@ -2370,14 +2383,6 @@ int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { return CC; } -bool MipsAssemblerOptions::setATReg(unsigned Reg) { - if (Reg > 31) - return false; - - ATReg = Reg; - return true; -} - int MipsAsmParser::getATReg(SMLoc Loc) { int AT = AssemblerOptions.back()->getATRegNum(); if (AT == 0) @@ -4429,9 +4434,25 @@ bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { if (IDVal == ".module") return parseDirectiveModule(); + if (IDVal == ".llvm_internal_mips_reallow_module_directive") + return parseInternalDirectiveReallowModule(); + return true; } +bool MipsAsmParser::parseInternalDirectiveReallowModule() { + // If this is not the end of the statement, report an error. + if (getLexer().isNot(AsmToken::EndOfStatement)) { + reportParseError("unexpected token, expected end of statement"); + return false; + } + + getTargetStreamer().reallowModuleDirective(); + + getParser().Lex(); // Eat EndOfStatement token. + return false; +} + extern "C" void LLVMInitializeMipsAsmParser() { RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h index dd0e54c..243b73d 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h @@ -32,10 +32,9 @@ class MipsAsmBackend : public MCAsmBackend { bool Is64Bit; // 32 or 64 bit words public: - MipsAsmBackend(const Target &T, Triple::OSType _OSType, bool _isLittle, - bool _is64Bit) - : MCAsmBackend(), OSType(_OSType), IsLittle(_isLittle), - Is64Bit(_is64Bit) {} + MipsAsmBackend(const Target &T, Triple::OSType OSType, bool IsLittle, + bool Is64Bit) + : MCAsmBackend(), OSType(OSType), IsLittle(IsLittle), Is64Bit(Is64Bit) {} MCObjectWriter *createObjectWriter(raw_ostream &OS) const override; diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index e14dc8d..a68bf16 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -38,9 +38,9 @@ namespace { MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, bool _isN64, bool IsLittleEndian) - : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS, - /*HasRelocationAddend*/ (_isN64) ? true : false, - /*IsN64*/ _isN64) {} + : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS, + /*HasRelocationAddend*/ _isN64, + /*IsN64*/ _isN64) {} MipsELFObjectWriter::~MipsELFObjectWriter() {} @@ -54,9 +54,11 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, switch (Kind) { default: llvm_unreachable("invalid fixup kind!"); + case Mips::fixup_Mips_32: case FK_Data_4: Type = ELF::R_MIPS_32; break; + case Mips::fixup_Mips_64: case FK_Data_8: Type = ELF::R_MIPS_64; break; @@ -262,12 +264,10 @@ MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD, } } -MCObjectWriter *llvm::createMipsELFObjectWriter(raw_ostream &OS, - uint8_t OSABI, +MCObjectWriter *llvm::createMipsELFObjectWriter(raw_ostream &OS, uint8_t OSABI, bool IsLittleEndian, bool Is64Bit) { - MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(Is64Bit, OSABI, - (Is64Bit) ? true : false, - IsLittleEndian); + MCELFObjectTargetWriter *MOTW = + new MipsELFObjectWriter(Is64Bit, OSABI, Is64Bit, IsLittleEndian); return createELFObjectWriter(MOTW, OS, IsLittleEndian); } diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp index 18c4a20..93f60df 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp @@ -69,11 +69,9 @@ void MipsELFStreamer::EmitMipsOptionRecords() { I->EmitMipsOptionRecord(); } -namespace llvm { -MCELFStreamer *createMipsELFStreamer(MCContext &Context, MCAsmBackend &MAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - const MCSubtargetInfo &STI, - bool RelaxAll) { - return new MipsELFStreamer(Context, MAB, OS, Emitter, STI); -} +MCELFStreamer *llvm::createMipsELFStreamer(MCContext &Context, + MCAsmBackend &MAB, raw_ostream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll) { + return new MipsELFStreamer(Context, MAB, OS, Emitter); } diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h index bc76d8a..6b834c6 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h +++ b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h @@ -34,7 +34,7 @@ class MipsELFStreamer : public MCELFStreamer { public: MipsELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, - MCCodeEmitter *Emitter, const MCSubtargetInfo &STI) + MCCodeEmitter *Emitter) : MCELFStreamer(Context, MAB, OS, Emitter) { RegInfoRecord = new MipsRegInfoRecord(this, Context); @@ -69,6 +69,6 @@ public: MCELFStreamer *createMipsELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *Emitter, - const MCSubtargetInfo &STI, bool RelaxAll); + bool RelaxAll); } // namespace llvm. #endif diff --git a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index fa8d6a6..e601963 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -18,7 +18,7 @@ namespace Mips { // one can have multiple fixup types for a given relocation and thus need // to be uniquely named. // - // This table *must* be in the save order of + // This table *must* be in the same order of // MCFixupKindInfo Infos[Mips::NumTargetFixupKinds] // in MipsAsmBackend.cpp. // diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 8208725..1c2f2da 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -35,14 +35,12 @@ namespace llvm { MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MCContext &Ctx) { return new MipsMCCodeEmitter(MCII, Ctx, false); } MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MCContext &Ctx) { return new MipsMCCodeEmitter(MCII, Ctx, true); } @@ -451,7 +449,7 @@ getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, } unsigned MipsMCCodeEmitter:: -getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, +getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { int64_t Res; @@ -500,6 +498,9 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { default: llvm_unreachable("Unknown fixup kind!"); break; + case MCSymbolRefExpr::VK_None: + FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. + break; case MCSymbolRefExpr::VK_Mips_GPOFF_HI : FixupKind = Mips::fixup_Mips_GPOFF_HI; break; diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h b/lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h index e756b47..e6b5be7 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h +++ b/lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h @@ -25,7 +25,6 @@ bool baseRegNeedsLoadStoreMask(unsigned Reg); MCELFStreamer *createMipsNaClELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, - const MCSubtargetInfo &STI, bool RelaxAll); } diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index 9b56067..6f3f37b 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -106,96 +106,73 @@ static MCInstPrinter *createMipsMCInstPrinter(const Target &T, return new MipsInstPrinter(MAI, MII, MRI); } -static MCStreamer *createMCStreamer(const Target &T, StringRef TT, - MCContext &Context, MCAsmBackend &MAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - const MCSubtargetInfo &STI, bool RelaxAll) { +static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, + MCAsmBackend &MAB, raw_ostream &OS, + MCCodeEmitter *Emitter, bool RelaxAll) { MCStreamer *S; - if (!Triple(TT).isOSNaCl()) - S = createMipsELFStreamer(Context, MAB, OS, Emitter, STI, RelaxAll); + if (!T.isOSNaCl()) + S = createMipsELFStreamer(Context, MAB, OS, Emitter, RelaxAll); else - S = createMipsNaClELFStreamer(Context, MAB, OS, Emitter, STI, RelaxAll); - new MipsTargetELFStreamer(*S, STI); + S = createMipsNaClELFStreamer(Context, MAB, OS, Emitter, RelaxAll); return S; } -static MCStreamer * -createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, - bool isVerboseAsm, bool useDwarfDirectory, - MCInstPrinter *InstPrint, MCCodeEmitter *CE, - MCAsmBackend *TAB, bool ShowInst) { - MCStreamer *S = llvm::createAsmStreamer( - Ctx, OS, isVerboseAsm, useDwarfDirectory, InstPrint, CE, TAB, ShowInst); - new MipsTargetAsmStreamer(*S, OS); - return S; +static MCTargetStreamer *createMipsAsmTargetStreamer(MCStreamer &S, + formatted_raw_ostream &OS, + MCInstPrinter *InstPrint, + bool isVerboseAsm) { + return new MipsTargetAsmStreamer(S, OS); } static MCTargetStreamer *createMipsNullTargetStreamer(MCStreamer &S) { return new MipsTargetStreamer(S); } +static MCTargetStreamer * +createMipsObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { + return new MipsTargetELFStreamer(S, STI); +} + extern "C" void LLVMInitializeMipsTargetMC() { - // Register the MC asm info. - RegisterMCAsmInfoFn X(TheMipsTarget, createMipsMCAsmInfo); - RegisterMCAsmInfoFn Y(TheMipselTarget, createMipsMCAsmInfo); - RegisterMCAsmInfoFn A(TheMips64Target, createMipsMCAsmInfo); - RegisterMCAsmInfoFn B(TheMips64elTarget, createMipsMCAsmInfo); - - // Register the MC codegen info. - TargetRegistry::RegisterMCCodeGenInfo(TheMipsTarget, - createMipsMCCodeGenInfo); - TargetRegistry::RegisterMCCodeGenInfo(TheMipselTarget, - createMipsMCCodeGenInfo); - TargetRegistry::RegisterMCCodeGenInfo(TheMips64Target, - createMipsMCCodeGenInfo); - TargetRegistry::RegisterMCCodeGenInfo(TheMips64elTarget, - createMipsMCCodeGenInfo); - - // Register the MC instruction info. - TargetRegistry::RegisterMCInstrInfo(TheMipsTarget, createMipsMCInstrInfo); - TargetRegistry::RegisterMCInstrInfo(TheMipselTarget, createMipsMCInstrInfo); - TargetRegistry::RegisterMCInstrInfo(TheMips64Target, createMipsMCInstrInfo); - TargetRegistry::RegisterMCInstrInfo(TheMips64elTarget, - createMipsMCInstrInfo); - - // Register the MC register info. - TargetRegistry::RegisterMCRegInfo(TheMipsTarget, createMipsMCRegisterInfo); - TargetRegistry::RegisterMCRegInfo(TheMipselTarget, createMipsMCRegisterInfo); - TargetRegistry::RegisterMCRegInfo(TheMips64Target, createMipsMCRegisterInfo); - TargetRegistry::RegisterMCRegInfo(TheMips64elTarget, - createMipsMCRegisterInfo); + for (Target *T : {&TheMipsTarget, &TheMipselTarget, &TheMips64Target, + &TheMips64elTarget}) { + // Register the MC asm info. + RegisterMCAsmInfoFn X(*T, createMipsMCAsmInfo); + + // Register the MC codegen info. + TargetRegistry::RegisterMCCodeGenInfo(*T, createMipsMCCodeGenInfo); + + // Register the MC instruction info. + TargetRegistry::RegisterMCInstrInfo(*T, createMipsMCInstrInfo); + + // Register the MC register info. + TargetRegistry::RegisterMCRegInfo(*T, createMipsMCRegisterInfo); + + // Register the elf streamer. + TargetRegistry::RegisterELFStreamer(*T, createMCStreamer); + + // Register the asm target streamer. + TargetRegistry::RegisterAsmTargetStreamer(*T, createMipsAsmTargetStreamer); + + TargetRegistry::RegisterNullTargetStreamer(*T, + createMipsNullTargetStreamer); + + // Register the MC subtarget info. + TargetRegistry::RegisterMCSubtargetInfo(*T, createMipsMCSubtargetInfo); + + // Register the MCInstPrinter. + TargetRegistry::RegisterMCInstPrinter(*T, createMipsMCInstPrinter); + + TargetRegistry::RegisterObjectTargetStreamer( + *T, createMipsObjectTargetStreamer); + } // Register the MC Code Emitter - TargetRegistry::RegisterMCCodeEmitter(TheMipsTarget, - createMipsMCCodeEmitterEB); - TargetRegistry::RegisterMCCodeEmitter(TheMipselTarget, - createMipsMCCodeEmitterEL); - TargetRegistry::RegisterMCCodeEmitter(TheMips64Target, - createMipsMCCodeEmitterEB); - TargetRegistry::RegisterMCCodeEmitter(TheMips64elTarget, - createMipsMCCodeEmitterEL); - - // Register the object streamer. - TargetRegistry::RegisterMCObjectStreamer(TheMipsTarget, createMCStreamer); - TargetRegistry::RegisterMCObjectStreamer(TheMipselTarget, createMCStreamer); - TargetRegistry::RegisterMCObjectStreamer(TheMips64Target, createMCStreamer); - TargetRegistry::RegisterMCObjectStreamer(TheMips64elTarget, - createMCStreamer); - - // Register the asm streamer. - TargetRegistry::RegisterAsmStreamer(TheMipsTarget, createMCAsmStreamer); - TargetRegistry::RegisterAsmStreamer(TheMipselTarget, createMCAsmStreamer); - TargetRegistry::RegisterAsmStreamer(TheMips64Target, createMCAsmStreamer); - TargetRegistry::RegisterAsmStreamer(TheMips64elTarget, createMCAsmStreamer); - - TargetRegistry::RegisterNullTargetStreamer(TheMipsTarget, - createMipsNullTargetStreamer); - TargetRegistry::RegisterNullTargetStreamer(TheMipselTarget, - createMipsNullTargetStreamer); - TargetRegistry::RegisterNullTargetStreamer(TheMips64Target, - createMipsNullTargetStreamer); - TargetRegistry::RegisterNullTargetStreamer(TheMips64elTarget, - createMipsNullTargetStreamer); + for (Target *T : {&TheMipsTarget, &TheMips64Target}) + TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEB); + + for (Target *T : {&TheMipselTarget, &TheMips64elTarget}) + TargetRegistry::RegisterMCCodeEmitter(*T, createMipsMCCodeEmitterEL); // Register the asm backend. TargetRegistry::RegisterMCAsmBackend(TheMipsTarget, @@ -207,23 +184,4 @@ extern "C" void LLVMInitializeMipsTargetMC() { TargetRegistry::RegisterMCAsmBackend(TheMips64elTarget, createMipsAsmBackendEL64); - // Register the MC subtarget info. - TargetRegistry::RegisterMCSubtargetInfo(TheMipsTarget, - createMipsMCSubtargetInfo); - TargetRegistry::RegisterMCSubtargetInfo(TheMipselTarget, - createMipsMCSubtargetInfo); - TargetRegistry::RegisterMCSubtargetInfo(TheMips64Target, - createMipsMCSubtargetInfo); - TargetRegistry::RegisterMCSubtargetInfo(TheMips64elTarget, - createMipsMCSubtargetInfo); - - // Register the MCInstPrinter. - TargetRegistry::RegisterMCInstPrinter(TheMipsTarget, - createMipsMCInstPrinter); - TargetRegistry::RegisterMCInstPrinter(TheMipselTarget, - createMipsMCInstPrinter); - TargetRegistry::RegisterMCInstPrinter(TheMips64Target, - createMipsMCInstPrinter); - TargetRegistry::RegisterMCInstPrinter(TheMips64elTarget, - createMipsMCInstPrinter); } diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h index 9528b4e..92f394a 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h +++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h @@ -35,11 +35,9 @@ extern Target TheMips64elTarget; MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MCContext &Ctx); MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MCContext &Ctx); MCAsmBackend *createMipsAsmBackendEB32(const Target &T, diff --git a/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp index 92b8455..1adfdf9 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsNaClELFStreamer.cpp @@ -37,8 +37,8 @@ const unsigned LoadStoreStackMaskReg = Mips::T7; class MipsNaClELFStreamer : public MipsELFStreamer { public: MipsNaClELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, - MCCodeEmitter *Emitter, const MCSubtargetInfo &STI) - : MipsELFStreamer(Context, TAB, OS, Emitter, STI), PendingCall(false) {} + MCCodeEmitter *Emitter) + : MipsELFStreamer(Context, TAB, OS, Emitter), PendingCall(false) {} ~MipsNaClELFStreamer() {} @@ -254,10 +254,8 @@ bool baseRegNeedsLoadStoreMask(unsigned Reg) { MCELFStreamer *createMipsNaClELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, - const MCSubtargetInfo &STI, bool RelaxAll) { - MipsNaClELFStreamer *S = new MipsNaClELFStreamer(Context, TAB, OS, Emitter, - STI); + MipsNaClELFStreamer *S = new MipsNaClELFStreamer(Context, TAB, OS, Emitter); if (RelaxAll) S->getAssembler().setRelaxAll(true); diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 64d7cab..5790a5c 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -62,7 +62,7 @@ void MipsTargetStreamer::emitFMask(unsigned FPUBitmask, int FPUTopSavedRegOff) { void MipsTargetStreamer::emitDirectiveSetArch(StringRef Arch) { forbidModuleDirective(); } -void MipsTargetStreamer::emitDirectiveSetMips0() {} +void MipsTargetStreamer::emitDirectiveSetMips0() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetMips1() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetMips2() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetMips3() { forbidModuleDirective(); } @@ -78,8 +78,8 @@ void MipsTargetStreamer::emitDirectiveSetMips64R2() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetMips64R3() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetMips64R5() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetMips64R6() { forbidModuleDirective(); } -void MipsTargetStreamer::emitDirectiveSetPop() {} -void MipsTargetStreamer::emitDirectiveSetPush() {} +void MipsTargetStreamer::emitDirectiveSetPop() { forbidModuleDirective(); } +void MipsTargetStreamer::emitDirectiveSetPush() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {} @@ -91,6 +91,10 @@ void MipsTargetStreamer::emitDirectiveModuleOddSPReg(bool Enabled, if (!Enabled && !IsO32ABI) report_fatal_error("+nooddspreg is only valid for O32"); } +void MipsTargetStreamer::emitDirectiveSetFp( + MipsABIFlagsSection::FpABIKind Value) { + forbidModuleDirective(); +} MipsTargetAsmStreamer::MipsTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) @@ -198,7 +202,10 @@ void MipsTargetAsmStreamer::emitDirectiveSetArch(StringRef Arch) { MipsTargetStreamer::emitDirectiveSetArch(Arch); } -void MipsTargetAsmStreamer::emitDirectiveSetMips0() { OS << "\t.set\tmips0\n"; } +void MipsTargetAsmStreamer::emitDirectiveSetMips0() { + OS << "\t.set\tmips0\n"; + MipsTargetStreamer::emitDirectiveSetMips0(); +} void MipsTargetAsmStreamer::emitDirectiveSetMips1() { OS << "\t.set\tmips1\n"; @@ -285,9 +292,15 @@ void MipsTargetAsmStreamer::emitDirectiveSetNoDsp() { MipsTargetStreamer::emitDirectiveSetNoDsp(); } -void MipsTargetAsmStreamer::emitDirectiveSetPop() { OS << "\t.set\tpop\n"; } +void MipsTargetAsmStreamer::emitDirectiveSetPop() { + OS << "\t.set\tpop\n"; + MipsTargetStreamer::emitDirectiveSetPop(); +} -void MipsTargetAsmStreamer::emitDirectiveSetPush() { OS << "\t.set\tpush\n"; } +void MipsTargetAsmStreamer::emitDirectiveSetPush() { + OS << "\t.set\tpush\n"; + MipsTargetStreamer::emitDirectiveSetPush(); +} // Print a 32 bit hex number with all numbers. static void printHex32(unsigned Value, raw_ostream &OS) { @@ -346,15 +359,13 @@ void MipsTargetAsmStreamer::emitDirectiveModuleFP( void MipsTargetAsmStreamer::emitDirectiveSetFp( MipsABIFlagsSection::FpABIKind Value) { + MipsTargetStreamer::emitDirectiveSetFp(Value); + StringRef ModuleValue; OS << "\t.set\tfp="; OS << ABIFlagsSection.getFpABIString(Value) << "\n"; } -void MipsTargetAsmStreamer::emitMipsAbiFlags() { - // No action required for text output. -} - void MipsTargetAsmStreamer::emitDirectiveModuleOddSPReg(bool Enabled, bool IsO32ABI) { MipsTargetStreamer::emitDirectiveModuleOddSPReg(Enabled, IsO32ABI); @@ -367,10 +378,7 @@ MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI) : MipsTargetStreamer(S), MicroMipsEnabled(false), STI(STI) { MCAssembler &MCA = getStreamer().getAssembler(); - Triple T(STI.getTargetTriple()); - Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_) - ? true - : false; + Pic = MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_; uint64_t Features = STI.getFeatureBits(); diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index e20df2f..2aab739 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -642,8 +642,10 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { LW_FM_MM<0xc>; /// Arithmetic Instructions (3-Operand, R-Type) - def ADDu_MM : MMRel, ArithLogicR<"addu", GPR32Opnd>, ADD_FM_MM<0, 0x150>; - def SUBu_MM : MMRel, ArithLogicR<"subu", GPR32Opnd>, ADD_FM_MM<0, 0x1d0>; + def ADDu_MM : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>, + ADD_FM_MM<0, 0x150>; + def SUBu_MM : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>, + ADD_FM_MM<0, 0x1d0>; def MUL_MM : MMRel, ArithLogicR<"mul", GPR32Opnd>, ADD_FM_MM<0, 0x210>; def ADD_MM : MMRel, ArithLogicR<"add", GPR32Opnd>, ADD_FM_MM<0, 0x110>; def SUB_MM : MMRel, ArithLogicR<"sub", GPR32Opnd>, ADD_FM_MM<0, 0x190>; @@ -883,6 +885,8 @@ def : MipsPat<(i32 immSExt16:$imm), (ADDiu_MM ZERO, immSExt16:$imm)>; def : MipsPat<(i32 immZExt16:$imm), (ORi_MM ZERO, immZExt16:$imm)>; +def : MipsPat<(not GPR32:$in), + (NOR_MM GPR32Opnd:$in, ZERO)>; def : MipsPat<(add GPRMM16:$src, immSExtAddiur2:$imm), (ADDIUR2_MM GPRMM16:$src, immSExtAddiur2:$imm)>; diff --git a/lib/Target/Mips/Mips.h b/lib/Target/Mips/Mips.h index cb09c1a..671d7a8 100644 --- a/lib/Target/Mips/Mips.h +++ b/lib/Target/Mips/Mips.h @@ -20,8 +20,13 @@ namespace llvm { class MipsTargetMachine; + class ModulePass; class FunctionPass; + ModulePass *createMipsOs16Pass(MipsTargetMachine &TM); + ModulePass *createMips16HardFloatPass(MipsTargetMachine &TM); + + FunctionPass *createMipsModuleISelDagPass(MipsTargetMachine &TM); FunctionPass *createMipsOptimizePICCallPass(MipsTargetMachine &TM); FunctionPass *createMipsDelaySlotFillerPass(MipsTargetMachine &TM); FunctionPass *createMipsLongBranchPass(MipsTargetMachine &TM); diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td index 01c548e..ca24741 100644 --- a/lib/Target/Mips/Mips.td +++ b/lib/Target/Mips/Mips.td @@ -58,22 +58,22 @@ def MipsInstrInfo : InstrInfo; //===----------------------------------------------------------------------===// def FeatureNoABICalls : SubtargetFeature<"noabicalls", "NoABICalls", "true", - "Disable SVR4-style position-independent code.">; + "Disable SVR4-style position-independent code">; def FeatureGP64Bit : SubtargetFeature<"gp64", "IsGP64bit", "true", - "General Purpose Registers are 64-bit wide.">; + "General Purpose Registers are 64-bit wide">; def FeatureFP64Bit : SubtargetFeature<"fp64", "IsFP64bit", "true", - "Support 64-bit FP registers.">; + "Support 64-bit FP registers">; def FeatureFPXX : SubtargetFeature<"fpxx", "IsFPXX", "true", - "Support for FPXX.">; + "Support for FPXX">; def FeatureNaN2008 : SubtargetFeature<"nan2008", "IsNaN2008bit", "true", - "IEEE 754-2008 NaN encoding.">; + "IEEE 754-2008 NaN encoding">; def FeatureSingleFloat : SubtargetFeature<"single-float", "IsSingleFloat", "true", "Only supports single precision float">; def FeatureNoOddSPReg : SubtargetFeature<"nooddspreg", "UseOddSPReg", "false", "Disable odd numbered single-precision " "registers">; def FeatureVFPU : SubtargetFeature<"vfpu", "HasVFPU", - "true", "Enable vector FPU instructions.">; + "true", "Enable vector FPU instructions">; def FeatureMips1 : SubtargetFeature<"mips1", "MipsArchVersion", "Mips1", "Mips I ISA Support [highly experimental]">; def FeatureMips2 : SubtargetFeature<"mips2", "MipsArchVersion", "Mips2", diff --git a/lib/Target/Mips/Mips16HardFloat.cpp b/lib/Target/Mips/Mips16HardFloat.cpp index 32dc90a..893fc7c 100644 --- a/lib/Target/Mips/Mips16HardFloat.cpp +++ b/lib/Target/Mips/Mips16HardFloat.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "Mips16HardFloat.h" +#include "MipsTargetMachine.h" #include "llvm/IR/Module.h" #include "llvm/IR/Value.h" #include "llvm/Support/Debug.h" @@ -19,38 +19,51 @@ #include <algorithm> #include <string> -#define DEBUG_TYPE "mips16-hard-float" +using namespace llvm; -static void inlineAsmOut - (LLVMContext &C, StringRef AsmString, BasicBlock *BB ) { - std::vector<llvm::Type *> AsmArgTypes; - std::vector<llvm::Value*> AsmArgs; - llvm::FunctionType *AsmFTy = - llvm::FunctionType::get(Type::getVoidTy(C), - AsmArgTypes, false); - llvm::InlineAsm *IA = - llvm::InlineAsm::get(AsmFTy, AsmString, "", true, - /* IsAlignStack */ false, - llvm::InlineAsm::AD_ATT); - CallInst::Create(IA, AsmArgs, "", BB); -} +#define DEBUG_TYPE "mips16-hard-float" namespace { + class Mips16HardFloat : public ModulePass { + public: + static char ID; -class InlineAsmHelper { - LLVMContext &C; - BasicBlock *BB; -public: - InlineAsmHelper(LLVMContext &C_, BasicBlock *BB_) : - C(C_), BB(BB_) { - } + Mips16HardFloat(MipsTargetMachine &TM_) : ModulePass(ID), TM(TM_) {} - void Out(StringRef AsmString) { - inlineAsmOut(C, AsmString, BB); - } + const char *getPassName() const override { + return "MIPS16 Hard Float Pass"; + } -}; + bool runOnModule(Module &M) override; + + protected: + const MipsTargetMachine &TM; + }; + + class InlineAsmHelper { + LLVMContext &C; + BasicBlock *BB; + public: + InlineAsmHelper(LLVMContext &C_, BasicBlock *BB_) : + C(C_), BB(BB_) { + } + + void Out(StringRef AsmString) { + std::vector<llvm::Type *> AsmArgTypes; + std::vector<llvm::Value*> AsmArgs; + + llvm::FunctionType *AsmFTy = llvm::FunctionType::get(Type::getVoidTy(C), + AsmArgTypes, false); + llvm::InlineAsm *IA = llvm::InlineAsm::get(AsmFTy, AsmString, "", true, + /* IsAlignStack */ false, + llvm::InlineAsm::AD_ATT); + CallInst::Create(IA, AsmArgs, "", BB); + } + }; + + char Mips16HardFloat::ID = 0; } + // // Return types that matter for hard float are: // float, double, complex float, and complex double @@ -154,11 +167,11 @@ static bool needsFPStubFromParams(Function &F) { if (F.arg_size() >=1) { Type *ArgType = F.getFunctionType()->getParamType(0); switch (ArgType->getTypeID()) { - case Type::FloatTyID: - case Type::DoubleTyID: - return true; - default: - break; + case Type::FloatTyID: + case Type::DoubleTyID: + return true; + default: + break; } } return false; @@ -182,10 +195,8 @@ static bool needsFPHelperFromSig(Function &F) { // We swap between FP and Integer registers to allow Mips16 and Mips32 to // interoperate // - -static void swapFPIntParams - (FPParamVariant PV, Module *M, InlineAsmHelper &IAH, - bool LE, bool ToFP) { +static void swapFPIntParams(FPParamVariant PV, Module *M, InlineAsmHelper &IAH, + bool LE, bool ToFP) { //LLVMContext &Context = M->getContext(); std::string MI = ToFP? "mtc1 ": "mfc1 "; switch (PV) { @@ -242,6 +253,7 @@ static void swapFPIntParams return; } } + // // Make sure that we know we already need a stub for this function. // Having called needsFPHelperFromSig @@ -297,8 +309,8 @@ static void assureFPCallStub(Function &F, Module *M, break; case CFRet: if (LE) { - IAH.Out("mfc1 $$2,$$f0"); - IAH.Out("mfc1 $$3,$$f2"); + IAH.Out("mfc1 $$2,$$f0"); + IAH.Out("mfc1 $$3,$$f2"); } else { IAH.Out("mfc1 $$3,$$f0"); IAH.Out("mfc1 $$3,$$f2"); @@ -331,28 +343,27 @@ static void assureFPCallStub(Function &F, Module *M, // // Functions that are llvm intrinsics and don't need helpers. // -static const char *IntrinsicInline[] = - {"fabs", - "fabsf", - "llvm.ceil.f32", "llvm.ceil.f64", - "llvm.copysign.f32", "llvm.copysign.f64", - "llvm.cos.f32", "llvm.cos.f64", - "llvm.exp.f32", "llvm.exp.f64", - "llvm.exp2.f32", "llvm.exp2.f64", - "llvm.fabs.f32", "llvm.fabs.f64", - "llvm.floor.f32", "llvm.floor.f64", - "llvm.fma.f32", "llvm.fma.f64", - "llvm.log.f32", "llvm.log.f64", - "llvm.log10.f32", "llvm.log10.f64", - "llvm.nearbyint.f32", "llvm.nearbyint.f64", - "llvm.pow.f32", "llvm.pow.f64", - "llvm.powi.f32", "llvm.powi.f64", - "llvm.rint.f32", "llvm.rint.f64", - "llvm.round.f32", "llvm.round.f64", - "llvm.sin.f32", "llvm.sin.f64", - "llvm.sqrt.f32", "llvm.sqrt.f64", - "llvm.trunc.f32", "llvm.trunc.f64", - }; +static const char *IntrinsicInline[] = { + "fabs", "fabsf", + "llvm.ceil.f32", "llvm.ceil.f64", + "llvm.copysign.f32", "llvm.copysign.f64", + "llvm.cos.f32", "llvm.cos.f64", + "llvm.exp.f32", "llvm.exp.f64", + "llvm.exp2.f32", "llvm.exp2.f64", + "llvm.fabs.f32", "llvm.fabs.f64", + "llvm.floor.f32", "llvm.floor.f64", + "llvm.fma.f32", "llvm.fma.f64", + "llvm.log.f32", "llvm.log.f64", + "llvm.log10.f32", "llvm.log10.f64", + "llvm.nearbyint.f32", "llvm.nearbyint.f64", + "llvm.pow.f32", "llvm.pow.f64", + "llvm.powi.f32", "llvm.powi.f64", + "llvm.rint.f32", "llvm.rint.f64", + "llvm.round.f32", "llvm.round.f64", + "llvm.sin.f32", "llvm.sin.f64", + "llvm.sqrt.f32", "llvm.sqrt.f64", + "llvm.trunc.f32", "llvm.trunc.f64", +}; static bool isIntrinsicInline(Function *F) { return std::binary_search(std::begin(IntrinsicInline), @@ -384,9 +395,10 @@ static bool fixupFPReturnAndCall(Function &F, Module *M, Type *T = RVal->getType(); FPReturnVariant RV = whichFPReturnVariant(T); if (RV == NoFPRet) continue; - static const char* Helper[NoFPRet] = - {"__mips16_ret_sf", "__mips16_ret_df", "__mips16_ret_sc", - "__mips16_ret_dc"}; + static const char* Helper[NoFPRet] = { + "__mips16_ret_sf", "__mips16_ret_df", "__mips16_ret_sc", + "__mips16_ret_dc" + }; const char *Name = Helper[RV]; AttributeSet A; Value *Params[] = {RVal}; @@ -406,33 +418,33 @@ static bool fixupFPReturnAndCall(Function &F, Module *M, Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T, nullptr)); CallInst::Create(F, Params, "", &Inst ); } else if (const CallInst *CI = dyn_cast<CallInst>(I)) { - const Value* V = CI->getCalledValue(); - const Type* T = nullptr; - if (V) T = V->getType(); - const PointerType *PFT=nullptr; - if (T) PFT = dyn_cast<PointerType>(T); - const FunctionType *FT=nullptr; - if (PFT) FT = dyn_cast<FunctionType>(PFT->getElementType()); - Function *F_ = CI->getCalledFunction(); - if (FT && needsFPReturnHelper(*FT) && - !(F_ && isIntrinsicInline(F_))) { + const Value* V = CI->getCalledValue(); + const Type* T = nullptr; + if (V) T = V->getType(); + const PointerType *PFT=nullptr; + if (T) PFT = dyn_cast<PointerType>(T); + const FunctionType *FT=nullptr; + if (PFT) FT = dyn_cast<FunctionType>(PFT->getElementType()); + Function *F_ = CI->getCalledFunction(); + if (FT && needsFPReturnHelper(*FT) && + !(F_ && isIntrinsicInline(F_))) { + Modified=true; + F.addFnAttr("saveS2"); + } + if (F_ && !isIntrinsicInline(F_)) { + // pic mode calls are handled by already defined + // helper functions + if (needsFPReturnHelper(*F_)) { Modified=true; F.addFnAttr("saveS2"); } - if (F_ && !isIntrinsicInline(F_)) { - // pic mode calls are handled by already defined - // helper functions - if (needsFPReturnHelper(*F_)) { + if (TM.getRelocationModel() != Reloc::PIC_ ) { + if (needsFPHelperFromSig(*F_)) { + assureFPCallStub(*F_, M, TM); Modified=true; - F.addFnAttr("saveS2"); - } - if (TM.getRelocationModel() != Reloc::PIC_ ) { - if (needsFPHelperFromSig(*F_)) { - assureFPCallStub(*F_, M, TM); - Modified=true; - } } } + } } } return Modified; @@ -489,7 +501,6 @@ static void removeUseSoftFloat(Function &F) { F.addAttributes(AttributeSet::FunctionIndex, A); } -namespace llvm { // // This pass only makes sense when the underlying chip has floating point but @@ -530,11 +541,7 @@ bool Mips16HardFloat::runOnModule(Module &M) { return Modified; } -char Mips16HardFloat::ID = 0; - -} -ModulePass *llvm::createMips16HardFloat(MipsTargetMachine &TM) { +ModulePass *llvm::createMips16HardFloatPass(MipsTargetMachine &TM) { return new Mips16HardFloat(TM); } - diff --git a/lib/Target/Mips/Mips16HardFloat.h b/lib/Target/Mips/Mips16HardFloat.h deleted file mode 100644 index 586cc25..0000000 --- a/lib/Target/Mips/Mips16HardFloat.h +++ /dev/null @@ -1,43 +0,0 @@ -//===---- Mips16HardFloat.h for Mips16 Hard Float --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a phase which implements part of the floating point -// interoperability between Mips16 and Mips32 code. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_MIPS_MIPS16HARDFLOAT_H -#define LLVM_LIB_TARGET_MIPS_MIPS16HARDFLOAT_H - -#include "MCTargetDesc/MipsMCTargetDesc.h" -#include "MipsTargetMachine.h" -#include "llvm/Pass.h" -#include "llvm/Target/TargetMachine.h" - -using namespace llvm; - -namespace llvm { - -class Mips16HardFloat : public ModulePass { -public: - static char ID; - - Mips16HardFloat(MipsTargetMachine &TM_) : ModulePass(ID), TM(TM_) {} - - const char *getPassName() const override { return "MIPS16 Hard Float Pass"; } - bool runOnModule(Module &M) override; - -protected: - const MipsTargetMachine &TM; -}; - -ModulePass *createMips16HardFloat(MipsTargetMachine &TM); - -} -#endif diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp index 976becc..00d4495 100644 --- a/lib/Target/Mips/Mips16InstrInfo.cpp +++ b/lib/Target/Mips/Mips16InstrInfo.cpp @@ -1,4 +1,3 @@ - //===-- Mips16InstrInfo.cpp - Mips16 Instruction Information --------------===// // // The LLVM Compiler Infrastructure @@ -25,6 +24,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" #include <cctype> using namespace llvm; @@ -32,7 +32,7 @@ using namespace llvm; #define DEBUG_TYPE "mips16-instrinfo" Mips16InstrInfo::Mips16InstrInfo(const MipsSubtarget &STI) - : MipsInstrInfo(STI, Mips::Bimm16), RI(STI) {} + : MipsInstrInfo(STI, Mips::Bimm16), RI() {} const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { return RI; diff --git a/lib/Target/Mips/Mips16InstrInfo.h b/lib/Target/Mips/Mips16InstrInfo.h index e7d0c07..f9b7387 100644 --- a/lib/Target/Mips/Mips16InstrInfo.h +++ b/lib/Target/Mips/Mips16InstrInfo.h @@ -18,7 +18,7 @@ #include "MipsInstrInfo.h" namespace llvm { - +class MipsSubtarget; class Mips16InstrInfo : public MipsInstrInfo { const Mips16RegisterInfo RI; diff --git a/lib/Target/Mips/Mips16RegisterInfo.cpp b/lib/Target/Mips/Mips16RegisterInfo.cpp index c45acc4..ebd51d7 100644 --- a/lib/Target/Mips/Mips16RegisterInfo.cpp +++ b/lib/Target/Mips/Mips16RegisterInfo.cpp @@ -41,8 +41,7 @@ using namespace llvm; #define DEBUG_TYPE "mips16-registerinfo" -Mips16RegisterInfo::Mips16RegisterInfo(const MipsSubtarget &ST) - : MipsRegisterInfo(ST) {} +Mips16RegisterInfo::Mips16RegisterInfo() : MipsRegisterInfo() {} bool Mips16RegisterInfo::requiresRegisterScavenging (const MachineFunction &MF) const { @@ -65,7 +64,7 @@ bool Mips16RegisterInfo::saveScavengerRegister const TargetRegisterClass *RC, unsigned Reg) const { DebugLoc DL; - const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); + const TargetInstrInfo &TII = *MBB.getParent()->getSubtarget().getInstrInfo(); TII.copyPhysReg(MBB, I, DL, Mips::T0, Reg, true); TII.copyPhysReg(MBB, UseMI, DL, Reg, Mips::T0, true); return true; @@ -106,7 +105,7 @@ void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II, if (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) FrameReg = Mips::SP; else { - const TargetFrameLowering *TFI = Subtarget.getFrameLowering(); + const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); if (TFI->hasFP(MF)) { FrameReg = Mips::S0; } @@ -140,7 +139,7 @@ void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II, DebugLoc DL = II->getDebugLoc(); unsigned NewImm; const Mips16InstrInfo &TII = - *static_cast<const Mips16InstrInfo *>(Subtarget.getInstrInfo()); + *static_cast<const Mips16InstrInfo *>(MF.getSubtarget().getInstrInfo()); FrameReg = TII.loadImmediate(FrameReg, Offset, MBB, II, DL, NewImm); Offset = SignExtend64<16>(NewImm); IsKill = true; diff --git a/lib/Target/Mips/Mips16RegisterInfo.h b/lib/Target/Mips/Mips16RegisterInfo.h index 3cdf836..d67a79b 100644 --- a/lib/Target/Mips/Mips16RegisterInfo.h +++ b/lib/Target/Mips/Mips16RegisterInfo.h @@ -21,7 +21,7 @@ class Mips16InstrInfo; class Mips16RegisterInfo : public MipsRegisterInfo { public: - Mips16RegisterInfo(const MipsSubtarget &Subtarget); + Mips16RegisterInfo(); bool requiresRegisterScavenging(const MachineFunction &MF) const override; diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index 776e473..b1cb7f7 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -604,7 +604,7 @@ def : MipsInstAlias<"syncws", (SYNC 0x5), 0>; // Assembler Pseudo Instructions //===----------------------------------------------------------------------===// -class LoadImm64<string instr_asm, Operand Od, RegisterOperand RO> : +class LoadImmediate64<string instr_asm, Operand Od, RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm64), !strconcat(instr_asm, "\t$rt, $imm64")> ; -def LoadImm64Reg : LoadImm64<"dli", imm64, GPR64Opnd>; +def LoadImm64 : LoadImmediate64<"dli", imm64, GPR64Opnd>; diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index c662e13..1eb3b2c 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -252,6 +252,7 @@ void MipsAsmPrinter::printSavedRegsBitmask() { // Set the CPU and FPU Bitmasks const MachineFrameInfo *MFI = MF->getFrameInfo(); + const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); // size of stack area to which FP callee-saved regs are saved. unsigned CPURegSize = Mips::GPR32RegClass.getSize(); @@ -267,8 +268,7 @@ void MipsAsmPrinter::printSavedRegsBitmask() { if (Mips::GPR32RegClass.contains(Reg)) break; - unsigned RegNum = - TM.getSubtargetImpl()->getRegisterInfo()->getEncodingValue(Reg); + unsigned RegNum = TRI->getEncodingValue(Reg); if (Mips::AFGR64RegClass.contains(Reg)) { FPUBitmask |= (3 << RegNum); CSFPRegsSize += AFGR64RegSize; @@ -283,8 +283,7 @@ void MipsAsmPrinter::printSavedRegsBitmask() { // Set CPU Bitmask. for (; i != e; ++i) { unsigned Reg = CSI[i].getReg(); - unsigned RegNum = - TM.getSubtargetImpl()->getRegisterInfo()->getEncodingValue(Reg); + unsigned RegNum = TRI->getEncodingValue(Reg); CPUBitmask |= (1 << RegNum); } @@ -309,7 +308,7 @@ void MipsAsmPrinter::printSavedRegsBitmask() { /// Frame Directive void MipsAsmPrinter::emitFrameDirective() { - const TargetRegisterInfo &RI = *TM.getSubtargetImpl()->getRegisterInfo(); + const TargetRegisterInfo &RI = *MF->getSubtarget().getRegisterInfo(); unsigned stackReg = RI.getFrameRegister(*MF); unsigned returnReg = RI.getRARegister(); @@ -438,7 +437,7 @@ bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock* // Print out an operand for an inline asm expression. bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, - unsigned AsmVariant,const char *ExtraCode, + unsigned AsmVariant, const char *ExtraCode, raw_ostream &O) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { @@ -540,18 +539,24 @@ bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, unsigned AsmVariant, const char *ExtraCode, raw_ostream &O) { - int Offset = 0; + assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands"); + const MachineOperand &BaseMO = MI->getOperand(OpNum); + const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1); + assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand."); + assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand."); + int Offset = OffsetMO.getImm(); + // Currently we are expecting either no ExtraCode or 'D' if (ExtraCode) { if (ExtraCode[0] == 'D') - Offset = 4; + Offset += 4; else return true; // Unknown modifier. + // FIXME: M = high order bits + // FIXME: L = low order bits } - const MachineOperand &MO = MI->getOperand(OpNum); - assert(MO.isReg() && "unexpected inline asm memory operand"); - O << Offset << "($" << MipsInstPrinter::getRegisterName(MO.getReg()) << ")"; + O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg()) << ")"; return false; } diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td index abee185..dcd88f2 100644 --- a/lib/Target/Mips/MipsCallingConv.td +++ b/lib/Target/Mips/MipsCallingConv.td @@ -123,7 +123,7 @@ def CC_MipsN_SoftFloat : CallingConv<[ ]>; def CC_MipsN : CallingConv<[ - CCIfType<[i8, i16, i32], + CCIfType<[i8, i16, i32, i64], CCIfSubtargetNot<"isLittle()", CCIfInReg<CCPromoteToUpperBitsInType<i64>>>>, diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp index ac03c0b..606964d 100644 --- a/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -140,7 +140,7 @@ namespace { /// memory instruction can be moved to a delay slot. class MemDefsUses : public InspectMemInstr { public: - MemDefsUses(const MachineFrameInfo *MFI); + MemDefsUses(const DataLayout &DL, const MachineFrameInfo *MFI); private: typedef PointerUnion<const Value *, const PseudoSourceValue *> ValueType; @@ -158,6 +158,7 @@ namespace { const MachineFrameInfo *MFI; SmallPtrSet<ValueType, 4> Uses, Defs; + const DataLayout &DL; /// Flags indicating whether loads or stores with no underlying objects have /// been seen. @@ -212,8 +213,8 @@ namespace { /// moved to the delay slot. Returns true on success. template<typename IterTy> bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, - RegDefsUses &RegDU, InspectMemInstr &IM, - IterTy &Filler, Iter Slot) const; + RegDefsUses &RegDU, InspectMemInstr &IM, Iter Slot, + IterTy &Filler) const; /// This function searches in the backward direction for an instruction that /// can be moved to the delay slot. Returns true on success. @@ -320,7 +321,8 @@ void RegDefsUses::setCallerSaved(const MachineInstr &MI) { CallerSavedRegs.reset(Mips::ZERO); CallerSavedRegs.reset(Mips::ZERO_64); - for (const MCPhysReg *R = TRI.getCalleeSavedRegs(); *R; ++R) + for (const MCPhysReg *R = TRI.getCalleeSavedRegs(MI.getParent()->getParent()); + *R; ++R) for (MCRegAliasIterator AI(*R, &TRI, true); AI.isValid(); ++AI) CallerSavedRegs.reset(*AI); @@ -427,9 +429,9 @@ bool LoadFromStackOrConst::hasHazard_(const MachineInstr &MI) { return true; } -MemDefsUses::MemDefsUses(const MachineFrameInfo *MFI_) - : InspectMemInstr(false), MFI(MFI_), SeenNoObjLoad(false), - SeenNoObjStore(false) {} +MemDefsUses::MemDefsUses(const DataLayout &DL, const MachineFrameInfo *MFI_) + : InspectMemInstr(false), MFI(MFI_), DL(DL), SeenNoObjLoad(false), + SeenNoObjStore(false) {} bool MemDefsUses::hasHazard_(const MachineInstr &MI) { bool HasHazard = false; @@ -482,7 +484,7 @@ getUnderlyingObjects(const MachineInstr &MI, const Value *V = (*MI.memoperands_begin())->getValue(); SmallVector<Value *, 4> Objs; - GetUnderlyingObjects(const_cast<Value *>(V), Objs); + GetUnderlyingObjects(const_cast<Value *>(V), Objs, DL); for (SmallVectorImpl<Value *>::iterator I = Objs.begin(), E = Objs.end(); I != E; ++I) { @@ -639,8 +641,8 @@ FunctionPass *llvm::createMipsDelaySlotFillerPass(MipsTargetMachine &tm) { template<typename IterTy> bool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, - RegDefsUses &RegDU, InspectMemInstr& IM, - IterTy &Filler, Iter Slot) const { + RegDefsUses &RegDU, InspectMemInstr& IM, Iter Slot, + IterTy &Filler) const { for (IterTy I = Begin; I != End; ++I) { // skip debug value if (I->isDebugValue()) @@ -688,13 +690,13 @@ bool Filler::searchBackward(MachineBasicBlock &MBB, Iter Slot) const { return false; RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo()); - MemDefsUses MemDU(MBB.getParent()->getFrameInfo()); + MemDefsUses MemDU(*TM.getDataLayout(), MBB.getParent()->getFrameInfo()); ReverseIter Filler; RegDU.init(*Slot); - if (!searchRange(MBB, ReverseIter(Slot), MBB.rend(), RegDU, MemDU, Filler, - Slot)) + if (!searchRange(MBB, ReverseIter(Slot), MBB.rend(), RegDU, MemDU, Slot, + Filler)) return false; MBB.splice(std::next(Slot), &MBB, std::next(Filler).base()); @@ -714,7 +716,7 @@ bool Filler::searchForward(MachineBasicBlock &MBB, Iter Slot) const { RegDU.setCallerSaved(*Slot); - if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Filler, Slot)) + if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) return false; MBB.splice(std::next(Slot), &MBB, Filler); @@ -754,11 +756,11 @@ bool Filler::searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const { IM.reset(new LoadFromStackOrConst()); } else { const MachineFrameInfo *MFI = MBB.getParent()->getFrameInfo(); - IM.reset(new MemDefsUses(MFI)); + IM.reset(new MemDefsUses(*TM.getDataLayout(), MFI)); } - if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Filler, - Slot)) + if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot, + Filler)) return false; insertDelayFiller(Filler, BrMap); diff --git a/lib/Target/Mips/MipsFastISel.cpp b/lib/Target/Mips/MipsFastISel.cpp index 7d69659..7de0081 100644 --- a/lib/Target/Mips/MipsFastISel.cpp +++ b/lib/Target/Mips/MipsFastISel.cpp @@ -89,6 +89,7 @@ class MipsFastISel final : public FastISel { private: // Selection routines. + bool selectLogicalOp(const Instruction *I); bool selectLoad(const Instruction *I); bool selectStore(const Instruction *I); bool selectBranch(const Instruction *I); @@ -102,6 +103,7 @@ private: // Utility helper routines. bool isTypeLegal(Type *Ty, MVT &VT); + bool isTypeSupported(Type *Ty, MVT &VT); bool isLoadTypeLegal(Type *Ty, MVT &VT); bool computeAddress(const Value *Obj, Address &Addr); bool computeCallAddress(const Value *V, Address &Addr); @@ -129,6 +131,9 @@ private: unsigned getRegEnsuringSimpleIntegerWidening(const Value *, bool IsUnsigned); + unsigned emitLogicalOp(unsigned ISDOpc, MVT RetVT, const Value *LHS, + const Value *RHS); + unsigned materializeFP(const ConstantFP *CFP, MVT VT); unsigned materializeGV(const GlobalValue *GV, MVT VT); unsigned materializeInt(const Constant *C, MVT VT); @@ -210,6 +215,43 @@ CCAssignFn *MipsFastISel::CCAssignFnForCall(CallingConv::ID CC) const { return CC_MipsO32; } +unsigned MipsFastISel::emitLogicalOp(unsigned ISDOpc, MVT RetVT, + const Value *LHS, const Value *RHS) { + // Canonicalize immediates to the RHS first. + if (isa<ConstantInt>(LHS) && !isa<ConstantInt>(RHS)) + std::swap(LHS, RHS); + + unsigned Opc; + if (ISDOpc == ISD::AND) { + Opc = Mips::AND; + } else if (ISDOpc == ISD::OR) { + Opc = Mips::OR; + } else if (ISDOpc == ISD::XOR) { + Opc = Mips::XOR; + } else + llvm_unreachable("unexpected opcode"); + + unsigned LHSReg = getRegForValue(LHS); + unsigned ResultReg = createResultReg(&Mips::GPR32RegClass); + if (!ResultReg) + return 0; + + unsigned RHSReg; + if (!LHSReg) + return 0; + + if (const auto *C = dyn_cast<ConstantInt>(RHS)) + RHSReg = materializeInt(C, MVT::i32); + else + RHSReg = getRegForValue(RHS); + + if (!RHSReg) + return 0; + + emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg); + return ResultReg; +} + unsigned MipsFastISel::materializeInt(const Constant *C, MVT VT) { if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1) return 0; @@ -421,6 +463,21 @@ bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) { return TLI.isTypeLegal(VT); } +bool MipsFastISel::isTypeSupported(Type *Ty, MVT &VT) { + if (Ty->isVectorTy()) + return false; + + if (isTypeLegal(Ty, VT)) + return true; + + // If this is a type than can be sign or zero-extended to a basic operation + // go ahead and accept it now. + if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16) + return true; + + return false; +} + bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) { if (isTypeLegal(Ty, VT)) return true; @@ -671,6 +728,33 @@ bool MipsFastISel::emitStore(MVT VT, unsigned SrcReg, Address &Addr, return false; } +bool MipsFastISel::selectLogicalOp(const Instruction *I) { + MVT VT; + if (!isTypeSupported(I->getType(), VT)) + return false; + + unsigned ResultReg; + switch (I->getOpcode()) { + default: + llvm_unreachable("Unexpected instruction."); + case Instruction::And: + ResultReg = emitLogicalOp(ISD::AND, VT, I->getOperand(0), I->getOperand(1)); + break; + case Instruction::Or: + ResultReg = emitLogicalOp(ISD::OR, VT, I->getOperand(0), I->getOperand(1)); + break; + case Instruction::Xor: + ResultReg = emitLogicalOp(ISD::XOR, VT, I->getOperand(0), I->getOperand(1)); + break; + } + + if (!ResultReg) + return false; + + updateValueMap(I, ResultReg); + return true; +} + bool MipsFastISel::selectLoad(const Instruction *I) { // Atomic loads need special handling. if (cast<LoadInst>(I)->isAtomic()) @@ -1083,7 +1167,7 @@ bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) { // Add a register mask with the call-preserved registers. // Proper defs for return values will be added by setPhysRegsDeadExcept(). - MIB.addRegMask(TRI.getCallPreservedMask(CC)); + MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC)); CLI.Call = MIB; @@ -1312,6 +1396,10 @@ bool MipsFastISel::fastSelectInstruction(const Instruction *I) { return selectLoad(I); case Instruction::Store: return selectStore(I); + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + return selectLogicalOp(I); case Instruction::Br: return selectBranch(I); case Instruction::Ret: @@ -1354,7 +1442,7 @@ unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(const Value *V, void MipsFastISel::simplifyAddress(Address &Addr) { if (!isInt<16>(Addr.getOffset())) { unsigned TempReg = - materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass); + materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass); unsigned DestReg = createResultReg(&Mips::GPR32RegClass); emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg()); Addr.setReg(DestReg); diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 21fc8ce..c78c329 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -230,9 +230,18 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) { } bool MipsDAGToDAGISel:: -SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, +SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) { - assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); - OutOps.push_back(Op); - return false; + // All memory constraints can at least accept raw pointers. + switch(ConstraintID) { + default: + llvm_unreachable("Unexpected asm memory constraint"); + case InlineAsm::Constraint_i: + case InlineAsm::Constraint_m: + case InlineAsm::Constraint_R: + case InlineAsm::Constraint_ZC: + OutOps.push_back(Op); + return false; + } + return true; } diff --git a/lib/Target/Mips/MipsISelDAGToDAG.h b/lib/Target/Mips/MipsISelDAGToDAG.h index 6b72877..aec731e 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/lib/Target/Mips/MipsISelDAGToDAG.h @@ -125,7 +125,7 @@ private: virtual void processFunctionAfterISel(MachineFunction &MF) = 0; bool SelectInlineAsmMemoryOperand(const SDValue &Op, - char ConstraintCode, + unsigned ConstraintID, std::vector<SDValue> &OutOps) override; }; } diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 9253b2e..e4bae03 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -617,6 +617,33 @@ static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); } +static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG, + TargetLowering::DAGCombinerInfo &DCI, + const MipsSubtarget &Subtarget) { + if (DCI.isBeforeLegalizeOps()) + return SDValue(); + + SDValue ValueIfTrue = N->getOperand(0), ValueIfFalse = N->getOperand(2); + + ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(ValueIfFalse); + if (!FalseC || FalseC->getZExtValue()) + return SDValue(); + + // Since RHS (False) is 0, we swap the order of the True/False operands + // (obviously also inverting the condition) so that we can + // take advantage of conditional moves using the $0 register. + // Example: + // return (a != 0) ? x : 0; + // load $reg, x + // movz $reg, $0, a + unsigned Opc = (N->getOpcode() == MipsISD::CMovFP_T) ? MipsISD::CMovFP_F : + MipsISD::CMovFP_T; + + SDValue FCC = N->getOperand(1), Glue = N->getOperand(3); + return DAG.getNode(Opc, SDLoc(N), ValueIfFalse.getValueType(), + ValueIfFalse, FCC, ValueIfTrue, Glue); +} + static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget) { @@ -750,6 +777,9 @@ SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) return performDivRemCombine(N, DAG, DCI, Subtarget); case ISD::SELECT: return performSELECTCombine(N, DAG, DCI, Subtarget); + case MipsISD::CMovFP_F: + case MipsISD::CMovFP_T: + return performCMovFPCombine(N, DAG, DCI, Subtarget); case ISD::AND: return performANDCombine(N, DAG, DCI, Subtarget); case ISD::OR: @@ -2451,7 +2481,8 @@ getOpndList(SmallVectorImpl<SDValue> &Ops, // Add a register mask operand representing the call-preserved registers. const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); - const uint32_t *Mask = TRI->getCallPreservedMask(CLI.CallConv); + const uint32_t *Mask = + TRI->getCallPreservedMask(CLI.DAG.getMachineFunction(), CLI.CallConv); assert(Mask && "Missing call preserved mask for calling convention"); if (Subtarget.inMips16HardFloat()) { if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(CLI.Callee)) { @@ -3001,6 +3032,15 @@ MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv, return CCInfo.CheckReturn(Outs, RetCC_Mips); } +bool +MipsTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const { + if (Subtarget.hasMips3() && Subtarget.abiUsesSoftFloat()) { + if (Type == MVT::i32) + return true; + } + return IsSigned; +} + SDValue MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, @@ -3133,6 +3173,10 @@ getConstraintType(const std::string &Constraint) const return C_Memory; } } + + if (Constraint == "ZC") + return C_Memory; + return TargetLowering::getConstraintType(Constraint); } diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 9f86a43..40b6661 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -475,6 +475,8 @@ namespace llvm { const SmallVectorImpl<SDValue> &OutVals, SDLoc dl, SelectionDAG &DAG) const override; + bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override; + // Inline asm support ConstraintType getConstraintType(const std::string &Constraint) const override; @@ -503,6 +505,15 @@ namespace llvm { std::vector<SDValue> &Ops, SelectionDAG &DAG) const override; + unsigned getInlineAsmMemConstraint( + const std::string &ConstraintCode) const override { + if (ConstraintCode == "R") + return InlineAsm::Constraint_R; + else if (ConstraintCode == "ZC") + return InlineAsm::Constraint_ZC; + return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); + } + bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override; bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index db149d4..7b2b289 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -29,7 +29,7 @@ #include "MipsGenInstrInfo.inc" namespace llvm { - +class MipsSubtarget; class MipsInstrInfo : public MipsGenInstrInfo { virtual void anchor(); protected: diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 04a16b3..c937d2b 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -1000,7 +1000,7 @@ class ExtBase<string opstr, RegisterOperand RO, Operand PosOpnd, SDPatternOperator Op = null_frag>: InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ext:$size), !strconcat(opstr, " $rt, $rs, $pos, $size"), - [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], NoItinerary, + [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size))], II_EXT, FrmR, opstr>, ISA_MIPS32R2; class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd, @@ -1008,7 +1008,7 @@ class InsBase<string opstr, RegisterOperand RO, Operand PosOpnd, InstSE<(outs RO:$rt), (ins RO:$rs, PosOpnd:$pos, size_ins:$size, RO:$src), !strconcat(opstr, " $rt, $rs, $pos, $size"), [(set RO:$rt, (Op RO:$rs, imm:$pos, imm:$size, RO:$src))], - NoItinerary, FrmR, opstr>, ISA_MIPS32R2 { + II_INS, FrmR, opstr>, ISA_MIPS32R2 { let Constraints = "$src = $rt"; } @@ -1140,12 +1140,13 @@ def XORi : MMRel, ArithLogicI<"xori", uimm16, GPR32Opnd, II_XORI, immZExt16, xor>, ADDI_FM<0xe>; def LUi : MMRel, LoadUpper<"lui", GPR32Opnd, uimm16>, LUI_FM; - +let AdditionalPredicates = [NotInMicroMips] in { /// Arithmetic Instructions (3-Operand, R-Type) def ADDu : MMRel, ArithLogicR<"addu", GPR32Opnd, 1, II_ADDU, add>, ADD_FM<0, 0x21>; def SUBu : MMRel, ArithLogicR<"subu", GPR32Opnd, 0, II_SUBU, sub>, ADD_FM<0, 0x23>; +} let Defs = [HI0, LO0] in def MUL : MMRel, ArithLogicR<"mul", GPR32Opnd, 1, II_MUL, mul>, ADD_FM<0x1c, 2>, ISA_MIPS32_NOT_32R6_64R6; @@ -1579,6 +1580,8 @@ def : MipsInstAlias<"sltu $rt, $rs, $imm", (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm16:$imm), 0>; def : MipsInstAlias<"xor $rs, $rt, $imm", (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; +def : MipsInstAlias<"xor $rs, $imm", + (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, uimm16:$imm), 0>; def : MipsInstAlias<"or $rs, $rt, $imm", (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, uimm16:$imm), 0>; def : MipsInstAlias<"or $rs, $imm", @@ -1639,20 +1642,21 @@ def : MipsInstAlias<"sync", // Assembler Pseudo Instructions //===----------------------------------------------------------------------===// -class LoadImm32<string instr_asm, Operand Od, RegisterOperand RO> : +class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadImm32Reg : LoadImm32<"li", uimm5, GPR32Opnd>; +def LoadImm32 : LoadImmediate32<"li", uimm5, GPR32Opnd>; -class LoadAddress<string instr_asm, Operand MemOpnd, RegisterOperand RO> : +class LoadAddressFromReg32<string instr_asm, Operand MemOpnd, + RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins MemOpnd:$addr), !strconcat(instr_asm, "\t$rt, $addr")> ; -def LoadAddr32Reg : LoadAddress<"la", mem, GPR32Opnd>; +def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>; -class LoadAddressImm<string instr_asm, Operand Od, RegisterOperand RO> : +class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadAddr32Imm : LoadAddressImm<"la", uimm5, GPR32Opnd>; +def LoadAddrImm32 : LoadAddressFromImm32<"la", uimm5, GPR32Opnd>; def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs), "jal\t$rd, $rs"> ; @@ -1761,9 +1765,11 @@ def : WrapperPat<tblockaddress, ADDiu, GPR32>; def : WrapperPat<tjumptable, ADDiu, GPR32>; def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>; +let AdditionalPredicates = [NotInMicroMips] in { // Mips does not have "not", so we expand our way def : MipsPat<(not GPR32:$in), (NOR GPR32Opnd:$in, ZERO)>; +} // extended loads def : MipsPat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>; diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp index 821392e..5258181 100644 --- a/lib/Target/Mips/MipsMCInstLower.cpp +++ b/lib/Target/Mips/MipsMCInstLower.cpp @@ -22,6 +22,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCStreamer.h" using namespace llvm; diff --git a/lib/Target/Mips/MipsMachineFunction.cpp b/lib/Target/Mips/MipsMachineFunction.cpp index 30b93dc..09e722d 100644 --- a/lib/Target/Mips/MipsMachineFunction.cpp +++ b/lib/Target/Mips/MipsMachineFunction.cpp @@ -79,14 +79,19 @@ unsigned MipsFunctionInfo::getGlobalBaseReg() { if (GlobalBaseReg) return GlobalBaseReg; + MipsSubtarget const &STI = + static_cast<const MipsSubtarget &>(MF.getSubtarget()); + const TargetRegisterClass *RC = - static_cast<const MipsSubtarget &>(MF.getSubtarget()).inMips16Mode() + STI.inMips16Mode() ? &Mips::CPU16RegsRegClass - : static_cast<const MipsTargetMachine &>(MF.getTarget()) - .getABI() - .IsN64() - ? &Mips::GPR64RegClass - : &Mips::GPR32RegClass; + : STI.inMicroMipsMode() + ? &Mips::GPRMM16RegClass + : static_cast<const MipsTargetMachine &>(MF.getTarget()) + .getABI() + .IsN64() + ? &Mips::GPR64RegClass + : &Mips::GPR32RegClass; return GlobalBaseReg = MF.getRegInfo().createVirtualRegister(RC); } diff --git a/lib/Target/Mips/MipsModuleISelDAGToDAG.cpp b/lib/Target/Mips/MipsModuleISelDAGToDAG.cpp index b011e8f..b18a673 100644 --- a/lib/Target/Mips/MipsModuleISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsModuleISelDAGToDAG.cpp @@ -8,15 +8,36 @@ // //===----------------------------------------------------------------------===// -#include "MipsISelDAGToDAG.h" -#include "MipsModuleISelDAGToDAG.h" -#include "llvm/Support/Casting.h" +#include "Mips.h" +#include "MipsTargetMachine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +using namespace llvm; + #define DEBUG_TYPE "mips-isel" -namespace llvm { +namespace { + class MipsModuleDAGToDAGISel : public MachineFunctionPass { + public: + static char ID; + + explicit MipsModuleDAGToDAGISel(MipsTargetMachine &TM_) + : MachineFunctionPass(ID), TM(TM_) {} + + // Pass Name + const char *getPassName() const override { + return "MIPS DAG->DAG Pattern Instruction Selection"; + } + + bool runOnMachineFunction(MachineFunction &MF) override; + + protected: + MipsTargetMachine &TM; + }; + + char MipsModuleDAGToDAGISel::ID = 0; +} bool MipsModuleDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { DEBUG(errs() << "In MipsModuleDAGToDAGISel::runMachineFunction\n"); @@ -24,13 +45,6 @@ bool MipsModuleDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { return false; } -char MipsModuleDAGToDAGISel::ID = 0; - -} - - -llvm::FunctionPass *llvm::createMipsModuleISelDag(MipsTargetMachine &TM) { +llvm::FunctionPass *llvm::createMipsModuleISelDagPass(MipsTargetMachine &TM) { return new MipsModuleDAGToDAGISel(TM); } - - diff --git a/lib/Target/Mips/MipsModuleISelDAGToDAG.h b/lib/Target/Mips/MipsModuleISelDAGToDAG.h deleted file mode 100644 index 85bae47..0000000 --- a/lib/Target/Mips/MipsModuleISelDAGToDAG.h +++ /dev/null @@ -1,58 +0,0 @@ -//===---- MipsModuleISelDAGToDAG.h - Change Subtarget --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a pass used to change the subtarget for the -// Mips Instruction selector. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_MIPS_MIPSMODULEISELDAGTODAG_H -#define LLVM_LIB_TARGET_MIPS_MIPSMODULEISELDAGTODAG_H - -#include "Mips.h" -#include "MipsSubtarget.h" -#include "MipsTargetMachine.h" -#include "llvm/CodeGen/SelectionDAGISel.h" - - -//===----------------------------------------------------------------------===// -// Instruction Selector Implementation -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// MipsModuleDAGToDAGISel - MIPS specific code to select MIPS machine -// instructions for SelectionDAG operations. -//===----------------------------------------------------------------------===// -namespace llvm { - -class MipsModuleDAGToDAGISel : public MachineFunctionPass { -public: - - static char ID; - - explicit MipsModuleDAGToDAGISel(MipsTargetMachine &TM_) - : MachineFunctionPass(ID), TM(TM_) {} - - // Pass Name - const char *getPassName() const override { - return "MIPS DAG->DAG Pattern Instruction Selection"; - } - - bool runOnMachineFunction(MachineFunction &MF) override; - -protected: - MipsTargetMachine &TM; -}; - -/// createMipsISelDag - This pass converts a legalized DAG into a -/// MIPS-specific DAG, ready for instruction scheduling. -FunctionPass *createMipsModuleISelDag(MipsTargetMachine &TM); -} - -#endif diff --git a/lib/Target/Mips/MipsOs16.cpp b/lib/Target/Mips/MipsOs16.cpp index 7aae964..b6cd791 100644 --- a/lib/Target/Mips/MipsOs16.cpp +++ b/lib/Target/Mips/MipsOs16.cpp @@ -11,14 +11,16 @@ // //===----------------------------------------------------------------------===// -#include "MipsOs16.h" +#include "llvm/IR/Instructions.h" +#include "Mips.h" #include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#define DEBUG_TYPE "mips-os16" +using namespace llvm; +#define DEBUG_TYPE "mips-os16" static cl::opt<std::string> Mips32FunctionMask( "mips32-function-mask", @@ -27,70 +29,83 @@ static cl::opt<std::string> Mips32FunctionMask( cl::Hidden); namespace { + class MipsOs16 : public ModulePass { + public: + static char ID; + + MipsOs16() : ModulePass(ID) {} + + const char *getPassName() const override { + return "MIPS Os16 Optimization"; + } + + bool runOnModule(Module &M) override; + }; + + char MipsOs16::ID = 0; +} - // Figure out if we need float point based on the function signature. - // We need to move variables in and/or out of floating point - // registers because of the ABI - // - bool needsFPFromSig(Function &F) { - Type* RetType = F.getReturnType(); - switch (RetType->getTypeID()) { +// Figure out if we need float point based on the function signature. +// We need to move variables in and/or out of floating point +// registers because of the ABI +// +static bool needsFPFromSig(Function &F) { + Type* RetType = F.getReturnType(); + switch (RetType->getTypeID()) { + case Type::FloatTyID: + case Type::DoubleTyID: + return true; + default: + ; + } + if (F.arg_size() >=1) { + Argument &Arg = F.getArgumentList().front(); + switch (Arg.getType()->getTypeID()) { case Type::FloatTyID: case Type::DoubleTyID: return true; default: ; } - if (F.arg_size() >=1) { - Argument &Arg = F.getArgumentList().front(); - switch (Arg.getType()->getTypeID()) { - case Type::FloatTyID: - case Type::DoubleTyID: - return true; - default: - ; - } - } - return false; } + return false; +} - // Figure out if the function will need floating point operations - // - bool needsFP(Function &F) { - if (needsFPFromSig(F)) - return true; - for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); +// Figure out if the function will need floating point operations +// +static bool needsFP(Function &F) { + if (needsFPFromSig(F)) + return true; + for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - const Instruction &Inst = *I; - switch (Inst.getOpcode()) { - case Instruction::FAdd: - case Instruction::FSub: - case Instruction::FMul: - case Instruction::FDiv: - case Instruction::FRem: - case Instruction::FPToUI: - case Instruction::FPToSI: - case Instruction::UIToFP: - case Instruction::SIToFP: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::FCmp: + const Instruction &Inst = *I; + switch (Inst.getOpcode()) { + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: + case Instruction::FRem: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::FCmp: + return true; + default: + ; + } + if (const CallInst *CI = dyn_cast<CallInst>(I)) { + DEBUG(dbgs() << "Working on call" << "\n"); + Function &F_ = *CI->getCalledFunction(); + if (needsFPFromSig(F_)) return true; - default: - ; - } - if (const CallInst *CI = dyn_cast<CallInst>(I)) { - DEBUG(dbgs() << "Working on call" << "\n"); - Function &F_ = *CI->getCalledFunction(); - if (needsFPFromSig(F_)) - return true; - } } - return false; - } + } + return false; } -namespace llvm { bool MipsOs16::runOnModule(Module &M) { @@ -136,12 +151,6 @@ bool MipsOs16::runOnModule(Module &M) { return modified; } -char MipsOs16::ID = 0; - -} - -ModulePass *llvm::createMipsOs16(MipsTargetMachine &TM) { +ModulePass *llvm::createMipsOs16Pass(MipsTargetMachine &TM) { return new MipsOs16; } - - diff --git a/lib/Target/Mips/MipsOs16.h b/lib/Target/Mips/MipsOs16.h deleted file mode 100644 index 77183ec..0000000 --- a/lib/Target/Mips/MipsOs16.h +++ /dev/null @@ -1,47 +0,0 @@ -//===---- MipsOs16.h for Mips Option -Os16 --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines an optimization phase for the MIPS target. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_MIPS_MIPSOS16_H -#define LLVM_LIB_TARGET_MIPS_MIPSOS16_H - -#include "MCTargetDesc/MipsMCTargetDesc.h" -#include "MipsTargetMachine.h" -#include "llvm/Pass.h" -#include "llvm/Target/TargetMachine.h" - -using namespace llvm; - -namespace llvm { - -class MipsOs16 : public ModulePass { - -public: - static char ID; - - MipsOs16() : ModulePass(ID) { - - } - - const char *getPassName() const override { - return "MIPS Os16 Optimization"; - } - - bool runOnModule(Module &M) override; - -}; - -ModulePass *createMipsOs16(MipsTargetMachine &TM); - -} - -#endif diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index 2110c03..0ea48b1 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -43,14 +43,14 @@ using namespace llvm; #define GET_REGINFO_TARGET_DESC #include "MipsGenRegisterInfo.inc" -MipsRegisterInfo::MipsRegisterInfo(const MipsSubtarget &ST) - : MipsGenRegisterInfo(Mips::RA), Subtarget(ST) {} +MipsRegisterInfo::MipsRegisterInfo() : MipsGenRegisterInfo(Mips::RA) {} unsigned MipsRegisterInfo::getPICCallReg() { return Mips::T9; } const TargetRegisterClass * MipsRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind) const { + const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>(); return Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass; } @@ -63,7 +63,7 @@ MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, case Mips::GPR32RegClassID: case Mips::GPR64RegClassID: case Mips::DSPRRegClassID: { - const TargetFrameLowering *TFI = Subtarget.getFrameLowering(); + const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); return 28 - TFI->hasFP(MF); } case Mips::FGR32RegClassID: @@ -82,6 +82,7 @@ MipsRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, /// Mips Callee Saved Registers const MCPhysReg * MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { + const MipsSubtarget &Subtarget = MF->getSubtarget<MipsSubtarget>(); if (Subtarget.isSingleFloat()) return CSR_SingleFloatOnly_SaveList; @@ -100,8 +101,10 @@ MipsRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { return CSR_O32_SaveList; } -const uint32_t* -MipsRegisterInfo::getCallPreservedMask(CallingConv::ID) const { +const uint32_t * +MipsRegisterInfo::getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID) const { + const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>(); if (Subtarget.isSingleFloat()) return CSR_SingleFloatOnly_RegMask; @@ -135,6 +138,7 @@ getReservedRegs(const MachineFunction &MF) const { }; BitVector Reserved(getNumRegs()); + const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>(); typedef TargetRegisterClass::const_iterator RegIter; for (unsigned I = 0; I < array_lengthof(ReservedGPR32); ++I) @@ -257,6 +261,7 @@ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned MipsRegisterInfo:: getFrameRegister(const MachineFunction &MF) const { + const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>(); const TargetFrameLowering *TFI = Subtarget.getFrameLowering(); bool IsN64 = static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64(); diff --git a/lib/Target/Mips/MipsRegisterInfo.h b/lib/Target/Mips/MipsRegisterInfo.h index 9ec4a38..031b93e 100644 --- a/lib/Target/Mips/MipsRegisterInfo.h +++ b/lib/Target/Mips/MipsRegisterInfo.h @@ -21,15 +21,9 @@ #include "MipsGenRegisterInfo.inc" namespace llvm { -class MipsSubtarget; -class Type; - class MipsRegisterInfo : public MipsGenRegisterInfo { -protected: - const MipsSubtarget &Subtarget; - public: - MipsRegisterInfo(const MipsSubtarget &Subtarget); + MipsRegisterInfo(); /// getRegisterNumbering - Given the enum value for some register, e.g. /// Mips::RA, return the number that it corresponds to (e.g. 31). @@ -47,9 +41,9 @@ public: unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override; - const MCPhysReg * - getCalleeSavedRegs(const MachineFunction *MF = nullptr) const override; - const uint32_t *getCallPreservedMask(CallingConv::ID) const override; + const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; + const uint32_t *getCallPreservedMask(const MachineFunction &MF, + CallingConv::ID) const override; static const uint32_t *getMips16RetHelperMask(); BitVector getReservedRegs(const MachineFunction &MF) const override; diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 0761ded..a598c3f 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -258,8 +258,12 @@ SDNode *MipsSEDAGToDAGISel::selectAddESubE(unsigned MOp, SDValue InFlag, CurDAG->getTargetConstant(Mips::sub_32, VT)); } - SDNode *AddCarry = CurDAG->getMachineNode(ADDuOp, DL, VT, - SDValue(Carry, 0), RHS); + // Generate a second addition only if we know that RHS is not a + // constant-zero node. + SDNode *AddCarry = Carry; + ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS); + if (!C || C->getZExtValue()) + AddCarry = CurDAG->getMachineNode(ADDuOp, DL, VT, SDValue(Carry, 0), RHS); return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS, SDValue(AddCarry, 0)); @@ -378,6 +382,17 @@ bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, selectAddrDefault(Addr, Base, Offset); } +bool MipsSEDAGToDAGISel::selectAddrRegImm9(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + if (selectAddrFrameIndex(Addr, Base, Offset)) + return true; + + if (selectAddrFrameIndexOffset(Addr, Base, Offset, 9)) + return true; + + return false; +} + bool MipsSEDAGToDAGISel::selectAddrRegImm10(SDValue Addr, SDValue &Base, SDValue &Offset) const { if (selectAddrFrameIndex(Addr, Base, Offset)) @@ -401,6 +416,17 @@ bool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base, return false; } +bool MipsSEDAGToDAGISel::selectAddrRegImm16(SDValue Addr, SDValue &Base, + SDValue &Offset) const { + if (selectAddrFrameIndex(Addr, Base, Offset)) + return true; + + if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16)) + return true; + + return false; +} + bool MipsSEDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base, SDValue &Offset) const { return selectAddrRegImm12(Addr, Base, Offset) || @@ -912,6 +938,60 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { return std::make_pair(false, nullptr); } +bool MipsSEDAGToDAGISel:: +SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, + std::vector<SDValue> &OutOps) { + SDValue Base, Offset; + + switch(ConstraintID) { + default: + llvm_unreachable("Unexpected asm memory constraint"); + // All memory constraints can at least accept raw pointers. + case InlineAsm::Constraint_i: + case InlineAsm::Constraint_R: + OutOps.push_back(Op); + OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32)); + return false; + case InlineAsm::Constraint_m: + if (selectAddrRegImm16(Op, Base, Offset)) { + OutOps.push_back(Base); + OutOps.push_back(Offset); + return false; + } + OutOps.push_back(Op); + OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32)); + return false; + case InlineAsm::Constraint_ZC: + // ZC matches whatever the pref, ll, and sc instructions can handle for the + // given subtarget. + if (Subtarget->inMicroMipsMode()) { + // On microMIPS, they can handle 12-bit offsets. + if (selectAddrRegImm12(Op, Base, Offset)) { + OutOps.push_back(Base); + OutOps.push_back(Offset); + return false; + } + } else if (Subtarget->hasMips32r6()) { + // On MIPS32r6/MIPS64r6, they can only handle 9-bit offsets. + if (selectAddrRegImm9(Op, Base, Offset)) { + OutOps.push_back(Base); + OutOps.push_back(Offset); + return false; + } + } else if (selectAddrRegImm16(Op, Base, Offset)) { + // Prior to MIPS32r6/MIPS64r6, they can handle 16-bit offsets. + OutOps.push_back(Base); + OutOps.push_back(Offset); + return false; + } + // In all cases, 0-bit offsets are acceptable. + OutOps.push_back(Op); + OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32)); + return false; + } + return true; +} + FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM) { return new MipsSEDAGToDAGISel(TM); } diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.h b/lib/Target/Mips/MipsSEISelDAGToDAG.h index 2d24eb4..a11fcf4 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -56,12 +56,18 @@ private: bool selectIntAddr(SDValue Addr, SDValue &Base, SDValue &Offset) const override; + bool selectAddrRegImm9(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + bool selectAddrRegImm10(SDValue Addr, SDValue &Base, SDValue &Offset) const; bool selectAddrRegImm12(SDValue Addr, SDValue &Base, SDValue &Offset) const; + bool selectAddrRegImm16(SDValue Addr, SDValue &Base, + SDValue &Offset) const; + bool selectIntAddrMM(SDValue Addr, SDValue &Base, SDValue &Offset) const override; @@ -111,6 +117,10 @@ private: // Insert instructions to initialize the global base register in the // first MBB of the function. void initGlobalBaseReg(MachineFunction &MF); + + bool SelectInlineAsmMemoryOperand(const SDValue &Op, + unsigned ConstraintID, + std::vector<SDValue> &OutOps) override; }; FunctionPass *createMipsSEISelDag(MipsTargetMachine &TM); diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp index 74f291f..b992579 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -27,7 +27,7 @@ using namespace llvm; MipsSEInstrInfo::MipsSEInstrInfo(const MipsSubtarget &STI) : MipsInstrInfo(STI, STI.getRelocationModel() == Reloc::PIC_ ? Mips::B : Mips::J), - RI(STI) {} + RI() {} const MipsRegisterInfo &MipsSEInstrInfo::getRegisterInfo() const { return RI; diff --git a/lib/Target/Mips/MipsSERegisterInfo.cpp b/lib/Target/Mips/MipsSERegisterInfo.cpp index 55c6638..b89207e 100644 --- a/lib/Target/Mips/MipsSERegisterInfo.cpp +++ b/lib/Target/Mips/MipsSERegisterInfo.cpp @@ -18,6 +18,7 @@ #include "MipsMachineFunction.h" #include "MipsSEInstrInfo.h" #include "MipsSubtarget.h" +#include "MipsTargetMachine.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -41,8 +42,7 @@ using namespace llvm; #define DEBUG_TYPE "mips-reg-info" -MipsSERegisterInfo::MipsSERegisterInfo(const MipsSubtarget &ST) - : MipsRegisterInfo(ST) {} +MipsSERegisterInfo::MipsSERegisterInfo() : MipsRegisterInfo() {} bool MipsSERegisterInfo:: requiresRegisterScavenging(const MachineFunction &MF) const { @@ -110,6 +110,8 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, MachineFunction &MF = *MI.getParent()->getParent(); MachineFrameInfo *MFI = MF.getFrameInfo(); MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); + bool isN64 = + static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64(); const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); int MinCSFI = 0; @@ -132,7 +134,7 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, unsigned FrameReg; if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI) - FrameReg = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP; + FrameReg = isN64 ? Mips::SP_64 : Mips::SP; else FrameReg = getFrameRegister(MF); @@ -165,9 +167,9 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, // (where n < 16) and doesn't, but does fit into 16-bits then use an ADDiu MachineBasicBlock &MBB = *MI.getParent(); DebugLoc DL = II->getDebugLoc(); - unsigned ADDiu = Subtarget.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; + unsigned ADDiu = isN64 ? Mips::DADDiu : Mips::ADDiu; const TargetRegisterClass *RC = - Subtarget.isABI_N64() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass; + isN64 ? &Mips::GPR64RegClass : &Mips::GPR32RegClass; MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo(); unsigned Reg = RegInfo.createVirtualRegister(RC); const MipsSEInstrInfo &TII = @@ -183,7 +185,7 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, // instructions. MachineBasicBlock &MBB = *MI.getParent(); DebugLoc DL = II->getDebugLoc(); - unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu; + unsigned ADDu = isN64 ? Mips::DADDu : Mips::ADDu; unsigned NewImm = 0; const MipsSEInstrInfo &TII = *static_cast<const MipsSEInstrInfo *>( diff --git a/lib/Target/Mips/MipsSERegisterInfo.h b/lib/Target/Mips/MipsSERegisterInfo.h index 6b70d07..ebae190 100644 --- a/lib/Target/Mips/MipsSERegisterInfo.h +++ b/lib/Target/Mips/MipsSERegisterInfo.h @@ -22,7 +22,7 @@ class MipsSEInstrInfo; class MipsSERegisterInfo : public MipsRegisterInfo { public: - MipsSERegisterInfo(const MipsSubtarget &Subtarget); + MipsSERegisterInfo(); bool requiresRegisterScavenging(const MachineFunction &MF) const override; diff --git a/lib/Target/Mips/MipsSchedule.td b/lib/Target/Mips/MipsSchedule.td index ea98199..54b5d28 100644 --- a/lib/Target/Mips/MipsSchedule.td +++ b/lib/Target/Mips/MipsSchedule.td @@ -65,7 +65,9 @@ def II_DSRL32 : InstrItinClass; def II_DSRLV : InstrItinClass; def II_DSUBU : InstrItinClass; def II_DSUB : InstrItinClass; +def II_EXT : InstrItinClass; // Any EXT instruction def II_FLOOR : InstrItinClass; +def II_INS : InstrItinClass; // Any INS instruction def II_LB : InstrItinClass; def II_LBU : InstrItinClass; def II_LD : InstrItinClass; @@ -198,6 +200,8 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [ InstrItinData<II_DSUB , [InstrStage<1, [ALU]>]>, InstrItinData<II_DROTR , [InstrStage<1, [ALU]>]>, InstrItinData<II_DROTRV , [InstrStage<1, [ALU]>]>, + InstrItinData<II_EXT , [InstrStage<1, [ALU]>]>, + InstrItinData<II_INS , [InstrStage<1, [ALU]>]>, InstrItinData<II_LUI , [InstrStage<1, [ALU]>]>, InstrItinData<II_MOVF , [InstrStage<1, [ALU]>]>, InstrItinData<II_MOVN , [InstrStage<1, [ALU]>]>, diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp index 86c8931..79f6617 100644 --- a/lib/Target/Mips/MipsTargetMachine.cpp +++ b/lib/Target/Mips/MipsTargetMachine.cpp @@ -14,14 +14,11 @@ #include "MipsTargetMachine.h" #include "Mips.h" #include "Mips16FrameLowering.h" -#include "Mips16HardFloat.h" #include "Mips16ISelDAGToDAG.h" #include "Mips16ISelLowering.h" #include "Mips16InstrInfo.h" #include "MipsFrameLowering.h" #include "MipsInstrInfo.h" -#include "MipsModuleISelDAGToDAG.h" -#include "MipsOs16.h" #include "MipsSEFrameLowering.h" #include "MipsSEISelDAGToDAG.h" #include "MipsSEISelLowering.h" @@ -34,6 +31,7 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" + using namespace llvm; #define DEBUG_TYPE "mips" @@ -46,8 +44,12 @@ extern "C" void LLVMInitializeMipsTarget() { RegisterTargetMachine<MipselTargetMachine> B(TheMips64elTarget); } -static std::string computeDataLayout(bool isLittle, MipsABIInfo &ABI) { +static std::string computeDataLayout(StringRef TT, StringRef CPU, + const TargetOptions &Options, + bool isLittle) { std::string Ret = ""; + MipsABIInfo ABI = + MipsABIInfo::computeTargetABI(Triple(TT), CPU, Options.MCOptions); // There are both little and big endian mips. if (isLittle) @@ -86,11 +88,11 @@ MipsTargetMachine::MipsTargetMachine(const Target &T, StringRef TT, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL, bool isLittle) - : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), + : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT, + CPU, FS, Options, RM, CM, OL), isLittle(isLittle), TLOF(make_unique<MipsTargetObjectFile>()), ABI(MipsABIInfo::computeTargetABI(Triple(TT), CPU, Options.MCOptions)), - DL(computeDataLayout(isLittle, ABI)), Subtarget(nullptr), - DefaultSubtarget(TT, CPU, FS, isLittle, *this), + Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this), NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", isLittle, *this), Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16", @@ -209,14 +211,14 @@ void MipsPassConfig::addIRPasses() { TargetPassConfig::addIRPasses(); addPass(createAtomicExpandPass(&getMipsTargetMachine())); if (getMipsSubtarget().os16()) - addPass(createMipsOs16(getMipsTargetMachine())); + addPass(createMipsOs16Pass(getMipsTargetMachine())); if (getMipsSubtarget().inMips16HardFloat()) - addPass(createMips16HardFloat(getMipsTargetMachine())); + addPass(createMips16HardFloatPass(getMipsTargetMachine())); } // Install an instruction selector pass using // the ISelDag to gen Mips code. bool MipsPassConfig::addInstSelector() { - addPass(createMipsModuleISelDag(getMipsTargetMachine())); + addPass(createMipsModuleISelDagPass(getMipsTargetMachine())); addPass(createMips16ISelDag(getMipsTargetMachine())); addPass(createMipsSEISelDag(getMipsTargetMachine())); return false; diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h index afd0cea..5427d6a 100644 --- a/lib/Target/Mips/MipsTargetMachine.h +++ b/lib/Target/Mips/MipsTargetMachine.h @@ -31,7 +31,6 @@ class MipsTargetMachine : public LLVMTargetMachine { std::unique_ptr<TargetLoweringObjectFile> TLOF; // Selected ABI MipsABIInfo ABI; - const DataLayout DL; // Calculates type size & alignment MipsSubtarget *Subtarget; MipsSubtarget DefaultSubtarget; MipsSubtarget NoMips16Subtarget; @@ -47,8 +46,7 @@ public: TargetIRAnalysis getTargetIRAnalysis() override; - const DataLayout *getDataLayout() const override { return &DL; } - const MipsSubtarget *getSubtargetImpl() const override { + const MipsSubtarget *getSubtargetImpl() const { if (Subtarget) return Subtarget; return &DefaultSubtarget; diff --git a/lib/Target/Mips/MipsTargetObjectFile.cpp b/lib/Target/Mips/MipsTargetObjectFile.cpp index c07693e..723b63b 100644 --- a/lib/Target/Mips/MipsTargetObjectFile.cpp +++ b/lib/Target/Mips/MipsTargetObjectFile.cpp @@ -9,6 +9,7 @@ #include "MipsTargetObjectFile.h" #include "MipsSubtarget.h" +#include "MipsTargetMachine.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/GlobalVariable.h" @@ -44,7 +45,7 @@ void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); - this->TM = &TM; + this->TM = &static_cast<const MipsTargetMachine &>(TM); } // A address must be loaded from a small section if its size is less than the @@ -84,7 +85,8 @@ IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM, bool MipsTargetObjectFile:: IsGlobalInSmallSectionImpl(const GlobalValue *GV, const TargetMachine &TM) const { - const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); + const MipsSubtarget &Subtarget = + *static_cast<const MipsTargetMachine &>(TM).getSubtargetImpl(); // Return if small section is not available. if (!Subtarget.useSmallSection()) @@ -127,9 +129,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, /// Return true if this constant should be placed into small data section. bool MipsTargetObjectFile:: IsConstantInSmallSection(const Constant *CN, const TargetMachine &TM) const { - return ( - TM.getSubtarget<MipsSubtarget>().useSmallSection() && LocalSData && - IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(CN->getType()))); + return (static_cast<const MipsTargetMachine &>(TM) + .getSubtargetImpl() + ->useSmallSection() && + LocalSData && IsInSmallSection(TM.getDataLayout()->getTypeAllocSize( + CN->getType()))); } const MCSection *MipsTargetObjectFile:: diff --git a/lib/Target/Mips/MipsTargetObjectFile.h b/lib/Target/Mips/MipsTargetObjectFile.h index 3a2b298..45ed9d0 100644 --- a/lib/Target/Mips/MipsTargetObjectFile.h +++ b/lib/Target/Mips/MipsTargetObjectFile.h @@ -13,11 +13,11 @@ #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" namespace llvm { - +class MipsTargetMachine; class MipsTargetObjectFile : public TargetLoweringObjectFileELF { const MCSection *SmallDataSection; const MCSection *SmallBSSSection; - const TargetMachine *TM; + const MipsTargetMachine *TM; public: void Initialize(MCContext &Ctx, const TargetMachine &TM) override; diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h index b3b8296..1ff041d 100644 --- a/lib/Target/Mips/MipsTargetStreamer.h +++ b/lib/Target/Mips/MipsTargetStreamer.h @@ -92,9 +92,9 @@ public: } virtual void emitDirectiveModuleOddSPReg(bool Enabled, bool IsO32ABI); - virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value){}; - virtual void emitMipsAbiFlags(){}; + virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value); void forbidModuleDirective() { ModuleDirectiveAllowed = false; } + void reallowModuleDirective() { ModuleDirectiveAllowed = true; } bool isModuleDirectiveAllowed() { return ModuleDirectiveAllowed; } // This method enables template classes to set internal abi flags @@ -197,7 +197,6 @@ public: bool Is32BitABI) override; void emitDirectiveModuleOddSPReg(bool Enabled, bool IsO32ABI) override; void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override; - void emitMipsAbiFlags() override; }; // This part is for ELF object output @@ -240,7 +239,7 @@ public: // ABI Flags void emitDirectiveModuleOddSPReg(bool Enabled, bool IsO32ABI) override; - void emitMipsAbiFlags() override; + void emitMipsAbiFlags(); }; } #endif |