diff options
| author | Stephen Hines <srhines@google.com> | 2013-06-12 13:32:42 -0700 |
|---|---|---|
| committer | Stephen Hines <srhines@google.com> | 2013-06-12 13:32:42 -0700 |
| commit | 1878f9a7874b1ff569d745c0269f49d3daf7203d (patch) | |
| tree | 19a8dbaaedf6a056c617e87596b32d3f452af137 /lib/Target/Mips | |
| parent | 7a57f27b857ec4b243d83d392a399f02fc196c0a (diff) | |
| parent | 100fbdd06be7590b23c4707a98cd605bdb519498 (diff) | |
| download | external_llvm-1878f9a7874b1ff569d745c0269f49d3daf7203d.zip external_llvm-1878f9a7874b1ff569d745c0269f49d3daf7203d.tar.gz external_llvm-1878f9a7874b1ff569d745c0269f49d3daf7203d.tar.bz2 | |
Merge commit '100fbdd06be7590b23c4707a98cd605bdb519498' into merge_20130612
Diffstat (limited to 'lib/Target/Mips')
56 files changed, 1799 insertions, 599 deletions
diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 0795cb9..d1d69d8 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -20,6 +20,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Support/TargetRegistry.h" +#include "llvm/ADT/APInt.h" using namespace llvm; @@ -1290,8 +1291,16 @@ bool MipsAsmParser::searchSymbolAlias( const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); const StringRef DefSymbol = Ref->getSymbol().getName(); if (DefSymbol.startswith("$")) { - // Lookup for the register with the corresponding name. - int RegNum = matchRegisterName(DefSymbol.substr(1), isMips64()); + int RegNum = -1; + APInt IntVal(32, -1); + if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) + RegNum = matchRegisterByNumber(IntVal.getZExtValue(), + isMips64() + ? Mips::CPU64RegsRegClassID + : Mips::CPURegsRegClassID); + else + // Lookup for the register with corresponding name + RegNum = matchRegisterName(DefSymbol.substr(1), isMips64()); if (RegNum > -1) { Parser.Lex(); MipsOperand *op = MipsOperand::CreateReg(RegNum, S, @@ -1305,7 +1314,7 @@ bool MipsAsmParser::searchSymbolAlias( Parser.Lex(); const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); MipsOperand *op = MipsOperand::CreateImm(Const, S, - Parser.getTok().getLoc()); + Parser.getTok().getLoc()); Operands.push_back(op); return true; } @@ -1451,7 +1460,7 @@ MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { return VK; } - +// Converts condition string to immediate operand value. static int ConvertCcString(StringRef CondString) { int CC = StringSwitch<unsigned>(CondString) .Case(".f", 0) @@ -1741,8 +1750,22 @@ bool MipsAsmParser::parseSetAssignment() { return reportParseError("unexpected token in .set directive"); Lex(); // Eat comma - if (Parser.parseExpression(Value)) - reportParseError("expected valid expression after comma"); + if (getLexer().is(AsmToken::Dollar)) { + MCSymbol *Symbol; + SMLoc DollarLoc = getLexer().getLoc(); + // Consume the dollar sign, and check for a following identifier. + Parser.Lex(); + // We have a '$' followed by something, make sure they are adjacent. + if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) + return true; + StringRef Res = StringRef(DollarLoc.getPointer(), + getTok().getEndLoc().getPointer() - DollarLoc.getPointer()); + Symbol = getContext().GetOrCreateSymbol(Res); + Parser.Lex(); + Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, + getContext()); + } else if (Parser.parseExpression(Value)) + return reportParseError("expected valid expression after comma"); // Check if the Name already exists as a symbol. MCSymbol *Sym = getContext().LookupSymbol(Name); diff --git a/lib/Target/Mips/CMakeLists.txt b/lib/Target/Mips/CMakeLists.txt index 78a9f70..834a998 100644 --- a/lib/Target/Mips/CMakeLists.txt +++ b/lib/Target/Mips/CMakeLists.txt @@ -15,6 +15,7 @@ add_public_tablegen_target(MipsCommonTableGen) add_llvm_target(MipsCodeGen Mips16FrameLowering.cpp + Mips16HardFloat.cpp Mips16InstrInfo.cpp Mips16ISelDAGToDAG.cpp Mips16ISelLowering.cpp @@ -34,6 +35,7 @@ add_llvm_target(MipsCodeGen MipsMachineFunction.cpp MipsModuleISelDAGToDAG.cpp MipsOs16.cpp + MipsOptimizeMathLibCalls.cpp MipsRegisterInfo.cpp MipsSEFrameLowering.cpp MipsSEInstrInfo.cpp diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index 0dba33a..4af6703 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -252,7 +252,7 @@ static DecodeStatus readInstruction32(const MemoryObject ®ion, uint8_t Bytes[4]; // We want to read exactly 4 Bytes of data. - if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) { + if (region.readBytes(address, 4, Bytes) == -1) { size = 0; return MCDisassembler::Fail; } diff --git a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt index 4212c94..1f08789 100644 --- a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt @@ -1,6 +1,5 @@ add_llvm_library(LLVMMipsDesc MipsAsmBackend.cpp - MipsDirectObjLower.cpp MipsMCAsmInfo.cpp MipsMCCodeEmitter.cpp MipsMCTargetDesc.cpp diff --git a/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.cpp b/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.cpp deleted file mode 100644 index 15c4282..0000000 --- a/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.cpp +++ /dev/null @@ -1,81 +0,0 @@ -//===-- MipsDirectObjLower.cpp - Mips LLVM direct object lowering -----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains code to lower Mips MCInst records that are normally -// left to the assembler to lower such as large shifts. -// -//===----------------------------------------------------------------------===// -#include "MipsInstrInfo.h" -#include "MCTargetDesc/MipsDirectObjLower.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCStreamer.h" - -using namespace llvm; - -// If the D<shift> instruction has a shift amount that is greater -// than 31 (checked in calling routine), lower it to a D<shift>32 instruction -void Mips::LowerLargeShift(MCInst& Inst) { - - assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); - assert(Inst.getOperand(2).isImm()); - - int64_t Shift = Inst.getOperand(2).getImm(); - if (Shift <= 31) - return; // Do nothing - Shift -= 32; - - // saminus32 - Inst.getOperand(2).setImm(Shift); - - switch (Inst.getOpcode()) { - default: - // Calling function is not synchronized - llvm_unreachable("Unexpected shift instruction"); - case Mips::DSLL: - Inst.setOpcode(Mips::DSLL32); - return; - case Mips::DSRL: - Inst.setOpcode(Mips::DSRL32); - return; - case Mips::DSRA: - Inst.setOpcode(Mips::DSRA32); - return; - } -} - -// Pick a DEXT or DINS instruction variant based on the pos and size operands -void Mips::LowerDextDins(MCInst& InstIn) { - int Opcode = InstIn.getOpcode(); - - if (Opcode == Mips::DEXT) - assert(InstIn.getNumOperands() == 4 && - "Invalid no. of machine operands for DEXT!"); - else // Only DEXT and DINS are possible - assert(InstIn.getNumOperands() == 5 && - "Invalid no. of machine operands for DINS!"); - - assert(InstIn.getOperand(2).isImm()); - int64_t pos = InstIn.getOperand(2).getImm(); - assert(InstIn.getOperand(3).isImm()); - int64_t size = InstIn.getOperand(3).getImm(); - - if (size <= 32) { - if (pos < 32) // DEXT/DINS, do nothing - return; - // DEXTU/DINSU - InstIn.getOperand(2).setImm(pos - 32); - InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU); - return; - } - // DEXTM/DINSM - assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32"); - InstIn.getOperand(3).setImm(size - 32); - InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM); - return; -} diff --git a/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.h b/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.h deleted file mode 100644 index 8813cc9..0000000 --- a/lib/Target/Mips/MCTargetDesc/MipsDirectObjLower.h +++ /dev/null @@ -1,28 +0,0 @@ -//===-- MipsDirectObjLower.h - Mips LLVM direct object lowering *- C++ -*--===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef MIPSDIRECTOBJLOWER_H -#define MIPSDIRECTOBJLOWER_H -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Compiler.h" - -namespace llvm { - class MCInst; - class MCStreamer; - - namespace Mips { - /// MipsDirectObjLower - This name space is used to lower MCInstr in cases - // where the assembler usually finishes the lowering - // such as large shifts. - void LowerLargeShift(MCInst &Inst); - void LowerDextDins(MCInst &Inst); - } -} - -#endif diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp index 5d4b32d..33f6f96 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp @@ -18,7 +18,7 @@ using namespace llvm; void MipsMCAsmInfo::anchor() { } -MipsMCAsmInfo::MipsMCAsmInfo(const Target &T, StringRef TT) { +MipsMCAsmInfo::MipsMCAsmInfo(StringRef TT) { Triple TheTriple(TT); if ((TheTriple.getArch() == Triple::mips) || (TheTriple.getArch() == Triple::mips64)) diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h index e1d8789..772234e 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h +++ b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h @@ -18,12 +18,11 @@ namespace llvm { class StringRef; - class Target; class MipsMCAsmInfo : public MCAsmInfo { virtual void anchor(); public: - explicit MipsMCAsmInfo(const Target &T, StringRef TT); + explicit MipsMCAsmInfo(StringRef TT); }; } // namespace llvm diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 9460731..a464dfe 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -13,7 +13,6 @@ // #define DEBUG_TYPE "mccodeemitter" #include "MCTargetDesc/MipsBaseInfo.h" -#include "MCTargetDesc/MipsDirectObjLower.h" #include "MCTargetDesc/MipsFixupKinds.h" #include "MCTargetDesc/MipsMCTargetDesc.h" #include "llvm/ADT/APFloat.h" @@ -114,6 +113,69 @@ MCCodeEmitter *llvm::createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, return new MipsMCCodeEmitter(MCII, Ctx, STI, true); } + +// If the D<shift> instruction has a shift amount that is greater +// than 31 (checked in calling routine), lower it to a D<shift>32 instruction +static void LowerLargeShift(MCInst& Inst) { + + assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); + assert(Inst.getOperand(2).isImm()); + + int64_t Shift = Inst.getOperand(2).getImm(); + if (Shift <= 31) + return; // Do nothing + Shift -= 32; + + // saminus32 + Inst.getOperand(2).setImm(Shift); + + switch (Inst.getOpcode()) { + default: + // Calling function is not synchronized + llvm_unreachable("Unexpected shift instruction"); + case Mips::DSLL: + Inst.setOpcode(Mips::DSLL32); + return; + case Mips::DSRL: + Inst.setOpcode(Mips::DSRL32); + return; + case Mips::DSRA: + Inst.setOpcode(Mips::DSRA32); + return; + } +} + +// Pick a DEXT or DINS instruction variant based on the pos and size operands +static void LowerDextDins(MCInst& InstIn) { + int Opcode = InstIn.getOpcode(); + + if (Opcode == Mips::DEXT) + assert(InstIn.getNumOperands() == 4 && + "Invalid no. of machine operands for DEXT!"); + else // Only DEXT and DINS are possible + assert(InstIn.getNumOperands() == 5 && + "Invalid no. of machine operands for DINS!"); + + assert(InstIn.getOperand(2).isImm()); + int64_t pos = InstIn.getOperand(2).getImm(); + assert(InstIn.getOperand(3).isImm()); + int64_t size = InstIn.getOperand(3).getImm(); + + if (size <= 32) { + if (pos < 32) // DEXT/DINS, do nothing + return; + // DEXTU/DINSU + InstIn.getOperand(2).setImm(pos - 32); + InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU); + return; + } + // DEXTM/DINSM + assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32"); + InstIn.getOperand(3).setImm(size - 32); + InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM); + return; +} + /// EncodeInstruction - Emit the instruction. /// Size the instruction (currently only 4 bytes void MipsMCCodeEmitter:: @@ -131,12 +193,12 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, case Mips::DSLL: case Mips::DSRL: case Mips::DSRA: - Mips::LowerLargeShift(TmpInst); + LowerLargeShift(TmpInst); break; // Double extract instruction is chosen by pos and size operands case Mips::DEXT: case Mips::DINS: - Mips::LowerDextDins(TmpInst); + LowerDextDins(TmpInst); } uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups); diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index be83b54..837fabe 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -93,12 +93,12 @@ static MCSubtargetInfo *createMipsMCSubtargetInfo(StringRef TT, StringRef CPU, return X; } -static MCAsmInfo *createMipsMCAsmInfo(const Target &T, StringRef TT) { - MCAsmInfo *MAI = new MipsMCAsmInfo(T, TT); +static MCAsmInfo *createMipsMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { + MCAsmInfo *MAI = new MipsMCAsmInfo(TT); - MachineLocation Dst(MachineLocation::VirtualFP); - MachineLocation Src(Mips::SP, 0); - MAI->addInitialFrameState(0, Dst, Src); + unsigned SP = MRI.getDwarfRegNum(Mips::SP, true); + MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(0, SP, 0); + MAI->addInitialFrameState(Inst); return MAI; } diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 74cdccd..7a42719 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -8,11 +8,13 @@ let isCodeGenOnly = 1 in { SLTI_FM_MM<0x24>; def SLTiu_MM : MMRel, SetCC_I<"sltiu", setult, simm16, immSExt16, CPURegs>, SLTI_FM_MM<0x2c>; - def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, and>, + def ANDi_MM : MMRel, ArithLogicI<"andi", uimm16, CPURegsOpnd, immZExt16, + and>, ADDI_FM_MM<0x34>; def ORi_MM : MMRel, ArithLogicI<"ori", uimm16, CPURegsOpnd, immZExt16, or>, ADDI_FM_MM<0x14>; - def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, xor>, + def XORi_MM : MMRel, ArithLogicI<"xori", uimm16, CPURegsOpnd, immZExt16, + xor>, ADDI_FM_MM<0x1c>; def LUi_MM : MMRel, LoadUpper<"lui", CPURegs, uimm16>, LUI_FM_MM; diff --git a/lib/Target/Mips/Mips.h b/lib/Target/Mips/Mips.h index 8c65bb4..b88c0d2 100644 --- a/lib/Target/Mips/Mips.h +++ b/lib/Target/Mips/Mips.h @@ -28,7 +28,7 @@ namespace llvm { FunctionPass *createMipsJITCodeEmitterPass(MipsTargetMachine &TM, JITCodeEmitter &JCE); FunctionPass *createMipsConstantIslandPass(MipsTargetMachine &tm); - + FunctionPass *createMipsOptimizeMathLibCalls(MipsTargetMachine &TM); } // end namespace llvm; #endif diff --git a/lib/Target/Mips/Mips16FrameLowering.cpp b/lib/Target/Mips/Mips16FrameLowering.cpp index 1bb6fe4..e180c49 100644 --- a/lib/Target/Mips/Mips16FrameLowering.cpp +++ b/lib/Target/Mips/Mips16FrameLowering.cpp @@ -40,7 +40,7 @@ void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { if (StackSize == 0 && !MFI->adjustsStack()) return; MachineModuleInfo &MMI = MF.getMMI(); - std::vector<MachineMove> &Moves = MMI.getFrameMoves(); + const MCRegisterInfo &MRI = MMI.getContext().getRegisterInfo(); MachineLocation DstML, SrcML; // Adjust stack. @@ -50,24 +50,20 @@ void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); - DstML = MachineLocation(MachineLocation::VirtualFP); - SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); - Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); + MMI.addFrameInst( + MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize)); MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); - DstML = MachineLocation(MachineLocation::VirtualFP, -8); - SrcML = MachineLocation(Mips::S1); - Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); + unsigned S1 = MRI.getDwarfRegNum(Mips::S1, true); + MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S1, -8)); - DstML = MachineLocation(MachineLocation::VirtualFP, -12); - SrcML = MachineLocation(Mips::S0); - Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); + unsigned S0 = MRI.getDwarfRegNum(Mips::S0, true); + MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, S0, -12)); - DstML = MachineLocation(MachineLocation::VirtualFP, -4); - SrcML = MachineLocation(Mips::RA); - Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); + unsigned RA = MRI.getDwarfRegNum(Mips::RA, true); + MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, RA, -4)); if (hasFP(MF)) BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) diff --git a/lib/Target/Mips/Mips16HardFloat.cpp b/lib/Target/Mips/Mips16HardFloat.cpp new file mode 100644 index 0000000..45dd5d7 --- /dev/null +++ b/lib/Target/Mips/Mips16HardFloat.cpp @@ -0,0 +1,458 @@ +//===---- Mips16HardFloat.cpp 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 pass needed for Mips16 Hard Float +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "mips16-hard-float" +#include "Mips16HardFloat.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include <string> + +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); +} + +namespace { + +class InlineAsmHelper { + LLVMContext &C; + BasicBlock *BB; +public: + InlineAsmHelper(LLVMContext &C_, BasicBlock *BB_) : + C(C_), BB(BB_) { + } + + void Out(StringRef AsmString) { + inlineAsmOut(C, AsmString, BB); + } + +}; +} +// +// Return types that matter for hard float are: +// float, double, complex float, and complex double +// +enum FPReturnVariant { + FRet, DRet, CFRet, CDRet, NoFPRet +}; + +// +// Determine which FP return type this function has +// +static FPReturnVariant whichFPReturnVariant(Type *T) { + switch (T->getTypeID()) { + case Type::FloatTyID: + return FRet; + case Type::DoubleTyID: + return DRet; + case Type::StructTyID: + if (T->getStructNumElements() != 2) + break; + if ((T->getContainedType(0)->isFloatTy()) && + (T->getContainedType(1)->isFloatTy())) + return CFRet; + if ((T->getContainedType(0)->isDoubleTy()) && + (T->getContainedType(1)->isDoubleTy())) + return CDRet; + break; + default: + break; + } + return NoFPRet; +} + +// +// Parameter type that matter are float, (float, float), (float, double), +// double, (double, double), (double, float) +// +enum FPParamVariant { + FSig, FFSig, FDSig, + DSig, DDSig, DFSig, NoSig +}; + +// which floating point parameter signature variant we are dealing with +// +typedef Type::TypeID TypeID; +const Type::TypeID FloatTyID = Type::FloatTyID; +const Type::TypeID DoubleTyID = Type::DoubleTyID; + +static FPParamVariant whichFPParamVariantNeeded(Function &F) { + switch (F.arg_size()) { + case 0: + return NoSig; + case 1:{ + TypeID ArgTypeID = F.getFunctionType()->getParamType(0)->getTypeID(); + switch (ArgTypeID) { + case FloatTyID: + return FSig; + case DoubleTyID: + return DSig; + default: + return NoSig; + } + } + default: { + TypeID ArgTypeID0 = F.getFunctionType()->getParamType(0)->getTypeID(); + TypeID ArgTypeID1 = F.getFunctionType()->getParamType(1)->getTypeID(); + switch(ArgTypeID0) { + case FloatTyID: { + switch (ArgTypeID1) { + case FloatTyID: + return FFSig; + case DoubleTyID: + return FDSig; + default: + return FSig; + } + } + case DoubleTyID: { + switch (ArgTypeID1) { + case FloatTyID: + return DFSig; + case DoubleTyID: + return DDSig; + default: + return DSig; + } + } + default: + return NoSig; + } + } + } + llvm_unreachable("can't get here"); +} + +// Figure out if we need float point based on the function parameters. +// We need to move variables in and/or out of floating point +// registers because of the ABI +// +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; + } + } + return false; +} + +static bool needsFPReturnHelper(Function &F) { + Type* RetType = F.getReturnType(); + return whichFPReturnVariant(RetType) != NoFPRet; +} + +static bool needsFPHelperFromSig(Function &F) { + return needsFPStubFromParams(F) || needsFPReturnHelper(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) { + //LLVMContext &Context = M->getContext(); + std::string MI = ToFP? "mtc1 ": "mfc1 "; + switch (PV) { + case FSig: + IAH.Out(MI + "$$4,$$f12"); + break; + case FFSig: + IAH.Out(MI +"$$4,$$f12"); + IAH.Out(MI + "$$5,$$f14"); + break; + case FDSig: + IAH.Out(MI + "$$4,$$f12"); + if (LE) { + IAH.Out(MI + "$$6,$$f14"); + IAH.Out(MI + "$$7,$$f15"); + } else { + IAH.Out(MI + "$$7,$$f14"); + IAH.Out(MI + "$$6,$$f15"); + } + break; + case DSig: + if (LE) { + IAH.Out(MI + "$$4,$$f12"); + IAH.Out(MI + "$$5,$$f13"); + } else { + IAH.Out(MI + "$$5,$$f12"); + IAH.Out(MI + "$$4,$$f13"); + } + break; + case DDSig: + if (LE) { + IAH.Out(MI + "$$4,$$f12"); + IAH.Out(MI + "$$5,$$f13"); + IAH.Out(MI + "$$6,$$f14"); + IAH.Out(MI + "$$7,$$f15"); + } else { + IAH.Out(MI + "$$5,$$f12"); + IAH.Out(MI + "$$4,$$f13"); + IAH.Out(MI + "$$7,$$f14"); + IAH.Out(MI + "$$6,$$f15"); + } + break; + case DFSig: + if (LE) { + IAH.Out(MI + "$$4,$$f12"); + IAH.Out(MI + "$$5,$$f13"); + } else { + IAH.Out(MI + "$$5,$$f12"); + IAH.Out(MI + "$$4,$$f13"); + } + IAH.Out(MI + "$$6,$$f14"); + break; + case NoSig: + return; + } +} +// +// Make sure that we know we already need a stub for this function. +// Having called needsFPHelperFromSig +// +static void assureFPCallStub(Function &F, Module *M, + const MipsSubtarget &Subtarget){ + // for now we only need them for static relocation + if (Subtarget.getRelocationModel() == Reloc::PIC_) + return; + LLVMContext &Context = M->getContext(); + bool LE = Subtarget.isLittle(); + std::string Name = F.getName(); + std::string SectionName = ".mips16.call.fp." + Name; + std::string StubName = "__call_stub_" + Name; + // + // see if we already have the stub + // + Function *FStub = M->getFunction(StubName); + if (FStub && !FStub->isDeclaration()) return; + FStub = Function::Create(F.getFunctionType(), + Function::InternalLinkage, StubName, M); + FStub->addFnAttr("mips16_fp_stub"); + FStub->addFnAttr(llvm::Attribute::Naked); + FStub->addFnAttr(llvm::Attribute::NoUnwind); + FStub->addFnAttr("nomips16"); + FStub->setSection(SectionName); + BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub); + InlineAsmHelper IAH(Context, BB); + FPReturnVariant RV = whichFPReturnVariant(FStub->getReturnType()); + FPParamVariant PV = whichFPParamVariantNeeded(F); + swapFPIntParams(PV, M, IAH, LE, true); + if (RV != NoFPRet) { + IAH.Out("move $$18, $$31"); + IAH.Out("jal " + Name); + } else { + IAH.Out("lui $$25,%hi(" + Name + ")"); + IAH.Out("addiu $$25,$$25,%lo(" + Name + ")" ); + } + switch (RV) { + case FRet: + IAH.Out("mfc1 $$2,$$f0"); + break; + case DRet: + if (LE) { + IAH.Out("mfc1 $$2,$$f0"); + IAH.Out("mfc1 $$3,$$f1"); + } else { + IAH.Out("mfc1 $$3,$$f0"); + IAH.Out("mfc1 $$2,$$f1"); + } + break; + case CFRet: + if (LE) { + IAH.Out("mfc1 $$2,$$f0"); + IAH.Out("mfc1 $$3,$$f2"); + } else { + IAH.Out("mfc1 $$3,$$f0"); + IAH.Out("mfc1 $$3,$$f2"); + } + break; + case CDRet: + if (LE) { + IAH.Out("mfc1 $$4,$$f2"); + IAH.Out("mfc1 $$5,$$f3"); + IAH.Out("mfc1 $$2,$$f0"); + IAH.Out("mfc1 $$3,$$f1"); + + } else { + IAH.Out("mfc1 $$5,$$f2"); + IAH.Out("mfc1 $$4,$$f3"); + IAH.Out("mfc1 $$3,$$f0"); + IAH.Out("mfc1 $$2,$$f1"); + } + break; + case NoFPRet: + break; + } + if (RV != NoFPRet) + IAH.Out("jr $$18"); + else + IAH.Out("jr $$25"); + new UnreachableInst(Context, BB); +} + +// +// Returns of float, double and complex need to be handled with a helper +// function. +// +static bool fixupFPReturnAndCall + (Function &F, Module *M, const MipsSubtarget &Subtarget) { + bool Modified = false; + LLVMContext &C = M->getContext(); + Type *MyVoid = Type::getVoidTy(C); + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); + I != E; ++I) { + Instruction &Inst = *I; + if (const ReturnInst *RI = dyn_cast<ReturnInst>(I)) { + Value *RVal = RI->getReturnValue(); + if (!RVal) continue; + // + // If there is a return value and it needs a helper function, + // figure out which one and add a call before the actual + // return to this helper. The purpose of the helper is to move + // floating point values from their soft float return mapping to + // where they would have been mapped to in floating point registers. + // + 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"}; + const char *Name = Helper[RV]; + AttributeSet A; + Value *Params[] = {RVal}; + Modified = true; + // + // These helper functions have a different calling ABI so + // this __Mips16RetHelper indicates that so that later + // during call setup, the proper call lowering to the helper + // functions will take place. + // + A = A.addAttribute(C, AttributeSet::FunctionIndex, + "__Mips16RetHelper"); + A = A.addAttribute(C, AttributeSet::FunctionIndex, + Attribute::ReadNone); + Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T, NULL)); + CallInst::Create(F, Params, "", &Inst ); + } else if (const CallInst *CI = dyn_cast<CallInst>(I)) { + // pic mode calls are handled by already defined + // helper functions + if (Subtarget.getRelocationModel() != Reloc::PIC_ ) { + Function *F_ = CI->getCalledFunction(); + if (F_ && needsFPHelperFromSig(*F_)) { + assureFPCallStub(*F_, M, Subtarget); + Modified=true; + } + } + } + } + return Modified; +} + +static void createFPFnStub(Function *F, Module *M, FPParamVariant PV, + const MipsSubtarget &Subtarget ) { + bool PicMode = Subtarget.getRelocationModel() == Reloc::PIC_; + bool LE = Subtarget.isLittle(); + LLVMContext &Context = M->getContext(); + std::string Name = F->getName(); + std::string SectionName = ".mips16.fn." + Name; + std::string StubName = "__fn_stub_" + Name; + std::string LocalName = "__fn_local_" + Name; + Function *FStub = Function::Create + (F->getFunctionType(), + Function::ExternalLinkage, StubName, M); + FStub->addFnAttr("mips16_fp_stub"); + FStub->addFnAttr(llvm::Attribute::Naked); + FStub->addFnAttr(llvm::Attribute::NoUnwind); + FStub->addFnAttr("nomips16"); + FStub->setSection(SectionName); + BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub); + InlineAsmHelper IAH(Context, BB); + IAH.Out(" .set macro"); + if (PicMode) { + IAH.Out(".set noreorder"); + IAH.Out(".cpload $$2"); + IAH.Out(".set reorder"); + IAH.Out(".reloc 0,R_MIPS_NONE," + Name); + IAH.Out("la $$25," + LocalName); + } + else + IAH.Out("la $$25, " + Name); + swapFPIntParams(PV, M, IAH, LE, false); + IAH.Out("jr $$25"); + IAH.Out(LocalName + " = " + Name); + new UnreachableInst(FStub->getContext(), BB); +} + +namespace llvm { + +// +// This pass only makes sense when the underlying chip has floating point but +// we are compiling as mips16. +// For all mips16 functions (that are not stubs we have already generated), or +// declared via attributes as nomips16, we must: +// 1) fixup all returns of float, double, single and double complex +// by calling a helper function before the actual return. +// 2) generate helper functions (stubs) that can be called by mips32 functions +// that will move parameters passed normally passed in floating point +// registers the soft float equivalents. +// 3) in the case of static relocation, generate helper functions so that +// mips16 functions can call extern functions of unknown type (mips16 or +// mips32). +// 4) TBD. For pic, calls to extern functions of unknown type are handled by +// predefined helper functions in libc but this work is currently done +// during call lowering but it should be moved here in the future. +// +bool Mips16HardFloat::runOnModule(Module &M) { + DEBUG(errs() << "Run on Module Mips16HardFloat\n"); + bool Modified = false; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { + if (F->isDeclaration() || F->hasFnAttribute("mips16_fp_stub") || + F->hasFnAttribute("nomips16")) continue; + Modified |= fixupFPReturnAndCall(*F, &M, Subtarget); + FPParamVariant V = whichFPParamVariantNeeded(*F); + if (V != NoSig) { + Modified = true; + createFPFnStub(F, &M, V, Subtarget); + } + } + return Modified; +} + +char Mips16HardFloat::ID = 0; + +} + +ModulePass *llvm::createMips16HardFloat(MipsTargetMachine &TM) { + return new Mips16HardFloat(TM); +} + diff --git a/lib/Target/Mips/Mips16HardFloat.h b/lib/Target/Mips/Mips16HardFloat.h new file mode 100644 index 0000000..b7f712a --- /dev/null +++ b/lib/Target/Mips/Mips16HardFloat.h @@ -0,0 +1,54 @@ +//===---- 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. +// +//===----------------------------------------------------------------------===// + +#include "MCTargetDesc/MipsMCTargetDesc.h" +#include "MipsTargetMachine.h" +#include "llvm/Pass.h" +#include "llvm/Target/TargetMachine.h" + + +#ifndef MIPS16HARDFLOAT_H +#define MIPS16HARDFLOAT_H + +using namespace llvm; + +namespace llvm { + +class Mips16HardFloat : public ModulePass { + +public: + static char ID; + + Mips16HardFloat(MipsTargetMachine &TM_) : ModulePass(ID), + TM(TM_), Subtarget(TM.getSubtarget<MipsSubtarget>()) { + } + + virtual const char *getPassName() const { + return "MIPS16 Hard Float Pass"; + } + + virtual bool runOnModule(Module &M); + +protected: + /// Keep a pointer to the MipsSubtarget around so that we can make the right + /// decision when generating code for different targets. + const TargetMachine &TM; + const MipsSubtarget &Subtarget; + +}; + +ModulePass *createMips16HardFloat(MipsTargetMachine &TM); + +} +#endif diff --git a/lib/Target/Mips/Mips16ISelDAGToDAG.cpp b/lib/Target/Mips/Mips16ISelDAGToDAG.cpp index c1c635c..f70abda 100644 --- a/lib/Target/Mips/Mips16ISelDAGToDAG.cpp +++ b/lib/Target/Mips/Mips16ISelDAGToDAG.cpp @@ -42,7 +42,7 @@ bool Mips16DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { } /// Select multiply instructions. std::pair<SDNode*, SDNode*> -Mips16DAGToDAGISel::selectMULT(SDNode *N, unsigned Opc, DebugLoc DL, EVT Ty, +Mips16DAGToDAGISel::selectMULT(SDNode *N, unsigned Opc, SDLoc DL, EVT Ty, bool HasLo, bool HasHi) { SDNode *Lo = 0, *Hi = 0; SDNode *Mul = CurDAG->getMachineNode(Opc, DL, MVT::Glue, N->getOperand(0), @@ -118,11 +118,11 @@ void Mips16DAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { SDValue Mips16DAGToDAGISel::getMips16SPAliasReg() { unsigned Mips16SPAliasReg = MF->getInfo<MipsFunctionInfo>()->getMips16SPAliasReg(); - return CurDAG->getRegister(Mips16SPAliasReg, TLI.getPointerTy()); + return CurDAG->getRegister(Mips16SPAliasReg, TLI->getPointerTy()); } void Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) { - SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, TLI.getPointerTy()); + SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, TLI->getPointerTy()); if (Parent) { switch (Parent->getOpcode()) { case ISD::LOAD: { @@ -149,7 +149,7 @@ void Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) { } } } - AliasReg = CurDAG->getRegister(Mips::SP, TLI.getPointerTy()); + AliasReg = CurDAG->getRegister(Mips::SP, TLI->getPointerTy()); return; } @@ -235,7 +235,7 @@ bool Mips16DAGToDAGISel::selectAddr16( /// expanded, promoted and normal instructions std::pair<bool, SDNode*> Mips16DAGToDAGISel::selectNode(SDNode *Node) { unsigned Opcode = Node->getOpcode(); - DebugLoc DL = Node->getDebugLoc(); + SDLoc DL(Node); /// // Instruction Selection not handled by the auto-generated diff --git a/lib/Target/Mips/Mips16ISelDAGToDAG.h b/lib/Target/Mips/Mips16ISelDAGToDAG.h index f05f9b7..49dc6e5 100644 --- a/lib/Target/Mips/Mips16ISelDAGToDAG.h +++ b/lib/Target/Mips/Mips16ISelDAGToDAG.h @@ -23,7 +23,7 @@ public: explicit Mips16DAGToDAGISel(MipsTargetMachine &TM) : MipsDAGToDAGISel(TM) {} private: - std::pair<SDNode*, SDNode*> selectMULT(SDNode *N, unsigned Opc, DebugLoc DL, + std::pair<SDNode*, SDNode*> selectMULT(SDNode *N, unsigned Opc, SDLoc DL, EVT Ty, bool HasLo, bool HasHi); SDValue getMips16SPAliasReg(); diff --git a/lib/Target/Mips/Mips16ISelLowering.cpp b/lib/Target/Mips/Mips16ISelLowering.cpp index f63318f..d8dd88c 100644 --- a/lib/Target/Mips/Mips16ISelLowering.cpp +++ b/lib/Target/Mips/Mips16ISelLowering.cpp @@ -13,6 +13,7 @@ #define DEBUG_TYPE "mips-lower" #include "Mips16ISelLowering.h" #include "MipsRegisterInfo.h" +#include "MipsTargetMachine.h" #include "MCTargetDesc/MipsBaseInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Support/CommandLine.h" @@ -21,11 +22,6 @@ using namespace llvm; -static cl::opt<bool> -Mips16HardFloat("mips16-hard-float", cl::NotHidden, - cl::desc("MIPS: mips16 hard float enable."), - cl::init(false)); - static cl::opt<bool> DontExpandCondPseudos16( "mips16-dont-expand-cond-pseudo", cl::init(false), @@ -50,9 +46,13 @@ Mips16TargetLowering::Mips16TargetLowering(MipsTargetMachine &TM) // Set up the register classes addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass); - if (Mips16HardFloat) + if (Subtarget->inMips16HardFloat()) { setMips16HardFloatLibCalls(); - + NoHelperNeeded.insert("__mips16_ret_sf"); + NoHelperNeeded.insert("__mips16_ret_df"); + NoHelperNeeded.insert("__mips16_ret_sc"); + NoHelperNeeded.insert("__mips16_ret_dc"); + } setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand); setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Expand); setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Expand); @@ -131,17 +131,17 @@ Mips16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, // altogether. return emitFEXT_T8I816_ins(Mips::BtnezX16, Mips::SltuRxRy16, MI, BB); case Mips::BteqzT8CmpiX16: return emitFEXT_T8I8I16_ins( - Mips::BteqzX16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, MI, BB); + Mips::BteqzX16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB); case Mips::BteqzT8SltiX16: return emitFEXT_T8I8I16_ins( - Mips::BteqzX16, Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB); + Mips::BteqzX16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB); case Mips::BteqzT8SltiuX16: return emitFEXT_T8I8I16_ins( - Mips::BteqzX16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB); + Mips::BteqzX16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB); case Mips::BtnezT8CmpiX16: return emitFEXT_T8I8I16_ins( - Mips::BtnezX16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, MI, BB); + Mips::BtnezX16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB); case Mips::BtnezT8SltiX16: return emitFEXT_T8I8I16_ins( - Mips::BtnezX16, Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB); + Mips::BtnezX16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB); case Mips::BtnezT8SltiuX16: return emitFEXT_T8I8I16_ins( - Mips::BtnezX16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB); + Mips::BtnezX16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB); break; case Mips::SltCCRxRy16: return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB); @@ -374,7 +374,8 @@ getOpndList(SmallVectorImpl<SDValue> &Ops, const char* Mips16HelperFunction = 0; bool NeedMips16Helper = false; - if (getTargetMachine().Options.UseSoftFloat && Mips16HardFloat) { + if (getTargetMachine().Options.UseSoftFloat && + Subtarget->inMips16HardFloat()) { // // currently we don't have symbols tagged with the mips16 or mips32 // qualifier so we will assume that we don't know what kind it is. @@ -386,6 +387,13 @@ getOpndList(SmallVectorImpl<SDValue> &Ops, LookupHelper = false; } } + else if (GlobalAddressSDNode *G = + dyn_cast<GlobalAddressSDNode>(CLI.Callee)) { + if (NoHelperNeeded.find(G->getGlobal()->getName().data()) != + NoHelperNeeded.end()) { + LookupHelper = false; + } + } if (LookupHelper) Mips16HelperFunction = getMips16HelperFunction(CLI.RetTy, CLI.Args, NeedMips16Helper); @@ -621,7 +629,7 @@ MachineBasicBlock } MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins( - unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, + unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned, MachineInstr *MI, MachineBasicBlock *BB) const { if (DontExpandCondPseudos16) return BB; @@ -632,7 +640,8 @@ MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins( unsigned CmpOpc; if (isUInt<8>(imm)) CmpOpc = CmpiOpc; - else if (isUInt<16>(imm)) + else if ((!ImmSigned && isUInt<16>(imm)) || + (ImmSigned && isInt<16>(imm))) CmpOpc = CmpiXOpc; else llvm_unreachable("immediate field not usable"); diff --git a/lib/Target/Mips/Mips16ISelLowering.h b/lib/Target/Mips/Mips16ISelLowering.h index b23e2a1..d3c7028 100644 --- a/lib/Target/Mips/Mips16ISelLowering.h +++ b/lib/Target/Mips/Mips16ISelLowering.h @@ -64,7 +64,7 @@ namespace llvm { MachineBasicBlock *BB) const; MachineBasicBlock *emitFEXT_T8I8I16_ins( - unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, + unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned, MachineInstr *MI, MachineBasicBlock *BB) const; MachineBasicBlock *emitFEXT_CCRX16_ins( diff --git a/lib/Target/Mips/Mips16InstrFormats.td b/lib/Target/Mips/Mips16InstrFormats.td index 4ff62ef..1e49934 100644 --- a/lib/Target/Mips/Mips16InstrFormats.td +++ b/lib/Target/Mips/Mips16InstrFormats.td @@ -61,7 +61,7 @@ class MipsInst16<dag outs, dag ins, string asmstr, list<dag> pattern, // Top 5 bits are the 'opcode' field let Inst{15-11} = Opcode; - + let Size=2; field bits<16> SoftFail = 0; } @@ -74,7 +74,7 @@ class MipsInst16_32<dag outs, dag ins, string asmstr, list<dag> pattern, MipsInst16_Base<outs, ins, asmstr, pattern, itin> { field bits<32> Inst; - + let Size=4; field bits<32> SoftFail = 0; } diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp index 17dd2c0..c2a496c 100644 --- a/lib/Target/Mips/Mips16InstrInfo.cpp +++ b/lib/Target/Mips/Mips16InstrInfo.cpp @@ -37,7 +37,7 @@ static cl::opt<bool> NeverUseSaveRestore( Mips16InstrInfo::Mips16InstrInfo(MipsTargetMachine &tm) : MipsInstrInfo(tm, Mips::BimmX16), - RI(*tm.getSubtargetImpl(), *this) {} + RI(*tm.getSubtargetImpl()) {} const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { return RI; @@ -145,7 +145,7 @@ bool Mips16InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { /// GetOppositeBranchOpc - Return the inverse of the specified /// opcode, e.g. turning BEQ to BNE. -unsigned Mips16InstrInfo::GetOppositeBranchOpc(unsigned Opc) const { +unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc) const { switch (Opc) { default: llvm_unreachable("Illegal opcode!"); case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16; @@ -380,7 +380,7 @@ Mips16InstrInfo::loadImmediate(unsigned FrameReg, return Reg; } -unsigned Mips16InstrInfo::GetAnalyzableBrOpc(unsigned Opc) const { +unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const { return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 || Opc == Mips::BteqzT8CmpX16 || Opc == Mips::BteqzT8CmpiX16 || diff --git a/lib/Target/Mips/Mips16InstrInfo.h b/lib/Target/Mips/Mips16InstrInfo.h index a77a904..a3bd31e 100644 --- a/lib/Target/Mips/Mips16InstrInfo.h +++ b/lib/Target/Mips/Mips16InstrInfo.h @@ -64,7 +64,7 @@ public: virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const; - virtual unsigned GetOppositeBranchOpc(unsigned Opc) const; + virtual unsigned getOppositeBranchOpc(unsigned Opc) const; // Adjust SP by FrameSize bytes. Save RA, S0, S1 void makeFrame(unsigned SP, int64_t FrameSize, MachineBasicBlock &MBB, @@ -102,7 +102,7 @@ public: (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const; private: - virtual unsigned GetAnalyzableBrOpc(unsigned Opc) const; + virtual unsigned getAnalyzableBrOpc(unsigned Opc) const; void ExpandRetRA16(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned Opc) const; diff --git a/lib/Target/Mips/Mips16RegisterInfo.cpp b/lib/Target/Mips/Mips16RegisterInfo.cpp index 7ad18f2..018f56c 100644 --- a/lib/Target/Mips/Mips16RegisterInfo.cpp +++ b/lib/Target/Mips/Mips16RegisterInfo.cpp @@ -41,17 +41,16 @@ using namespace llvm; -Mips16RegisterInfo::Mips16RegisterInfo(const MipsSubtarget &ST, - const Mips16InstrInfo &I) - : MipsRegisterInfo(ST), TII(I) {} +Mips16RegisterInfo::Mips16RegisterInfo(const MipsSubtarget &ST) + : MipsRegisterInfo(ST) {} bool Mips16RegisterInfo::requiresRegisterScavenging (const MachineFunction &MF) const { - return true; + return false; } bool Mips16RegisterInfo::requiresFrameIndexScavenging (const MachineFunction &MF) const { - return true; + return false; } bool Mips16RegisterInfo::useFPForScavengingIndex @@ -66,6 +65,7 @@ bool Mips16RegisterInfo::saveScavengerRegister const TargetRegisterClass *RC, unsigned Reg) const { DebugLoc DL; + const TargetInstrInfo &TII = *MBB.getParent()->getTarget().getInstrInfo(); TII.copyPhysReg(MBB, I, DL, Mips::T0, Reg, true); TII.copyPhysReg(MBB, UseMI, DL, Reg, Mips::T0, true); return true; @@ -139,6 +139,9 @@ void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II, MachineBasicBlock &MBB = *MI.getParent(); DebugLoc DL = II->getDebugLoc(); unsigned NewImm; + const Mips16InstrInfo &TII = + *static_cast<const Mips16InstrInfo*>( + MBB.getParent()->getTarget().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 2b3d2b1..13e82a3 100644 --- a/lib/Target/Mips/Mips16RegisterInfo.h +++ b/lib/Target/Mips/Mips16RegisterInfo.h @@ -20,10 +20,8 @@ namespace llvm { class Mips16InstrInfo; class Mips16RegisterInfo : public MipsRegisterInfo { - const Mips16InstrInfo &TII; public: - Mips16RegisterInfo(const MipsSubtarget &Subtarget, - const Mips16InstrInfo &TII); + Mips16RegisterInfo(const MipsSubtarget &Subtarget); bool requiresRegisterScavenging(const MachineFunction &MF) const; diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index fc533fb..df717fe 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -167,12 +167,12 @@ let Predicates = [IsN64, HasStdEnc], isCodeGenOnly = 1 in { /// Jump and Branch Instructions def JR64 : IndirectBranch<CPU64Regs>, MTLO_FM<8>; -def BEQ64 : CBranch<"beq", seteq, CPU64Regs>, BEQ_FM<4>; -def BNE64 : CBranch<"bne", setne, CPU64Regs>, BEQ_FM<5>; -def BGEZ64 : CBranchZero<"bgez", setge, CPU64Regs>, BGEZ_FM<1, 1>; -def BGTZ64 : CBranchZero<"bgtz", setgt, CPU64Regs>, BGEZ_FM<7, 0>; -def BLEZ64 : CBranchZero<"blez", setle, CPU64Regs>, BGEZ_FM<6, 0>; -def BLTZ64 : CBranchZero<"bltz", setlt, CPU64Regs>, BGEZ_FM<1, 0>; +def BEQ64 : CBranch<"beq", seteq, CPU64RegsOpnd>, BEQ_FM<4>; +def BNE64 : CBranch<"bne", setne, CPU64RegsOpnd>, BEQ_FM<5>; +def BGEZ64 : CBranchZero<"bgez", setge, CPU64RegsOpnd>, BGEZ_FM<1, 1>; +def BGTZ64 : CBranchZero<"bgtz", setgt, CPU64RegsOpnd>, BGEZ_FM<7, 0>; +def BLEZ64 : CBranchZero<"blez", setle, CPU64RegsOpnd>, BGEZ_FM<6, 0>; +def BLTZ64 : CBranchZero<"bltz", setlt, CPU64RegsOpnd>, BGEZ_FM<1, 0>; } let DecoderNamespace = "Mips64" in def JALR64 : JumpLinkReg<"jalr", CPU64Regs>, JALR_FM; @@ -192,9 +192,9 @@ def PseudoDMULTu : MultDivPseudo<DMULTu, ACRegs128, CPU64RegsOpnd, MipsMultu, def DSDIV : Div<"ddiv", IIIdiv, CPU64RegsOpnd, [HI64, LO64]>, MULT_FM<0, 0x1e>; def DUDIV : Div<"ddivu", IIIdiv, CPU64RegsOpnd, [HI64, LO64]>, MULT_FM<0, 0x1f>; def PseudoDSDIV : MultDivPseudo<DSDIV, ACRegs128, CPU64RegsOpnd, MipsDivRem, - IIIdiv, 0>; + IIIdiv, 0, 1, 1>; def PseudoDUDIV : MultDivPseudo<DUDIV, ACRegs128, CPU64RegsOpnd, MipsDivRemU, - IIIdiv, 0>; + IIIdiv, 0, 1, 1>; def MTHI64 : MoveToLOHI<"mthi", CPU64Regs, [HI64]>, MTLO_FM<0x11>; def MTLO64 : MoveToLOHI<"mtlo", CPU64Regs, [LO64]>, MTLO_FM<0x13>; @@ -294,6 +294,11 @@ def : WrapperPat<tglobaltlsaddr, DADDiu, CPU64Regs>; defm : BrcondPats<CPU64Regs, BEQ64, BNE64, SLT64, SLTu64, SLTi64, SLTiu64, ZERO_64>; +def : MipsPat<(brcond (i32 (setlt i64:$lhs, 1)), bb:$dst), + (BLEZ64 i64:$lhs, bb:$dst)>; +def : MipsPat<(brcond (i32 (setgt i64:$lhs, -1)), bb:$dst), + (BGEZ64 i64:$lhs, bb:$dst)>; + // setcc patterns defm : SeteqPats<CPU64Regs, SLTiu64, XOR64, SLTu64, ZERO_64>; defm : SetlePats<CPU64Regs, SLT64, SLTu64>; @@ -361,8 +366,14 @@ def : InstAlias<"dadd $rs, $rt, $imm", def : InstAlias<"or $rs, $rt, $imm", (ORi64 CPU64RegsOpnd:$rs, CPU64RegsOpnd:$rt, uimm16_64:$imm), 1>, Requires<[HasMips64]>; -/// Move between CPU and coprocessor registers +def : InstAlias<"bnez $rs,$offset", + (BNE64 CPU64RegsOpnd:$rs, ZERO_64, brtarget:$offset), 1>, + Requires<[HasMips64]>; +def : InstAlias<"beqz $rs,$offset", + (BEQ64 CPU64RegsOpnd:$rs, ZERO_64, brtarget:$offset), 1>, + Requires<[HasMips64]>; +/// Move between CPU and coprocessor registers let DecoderNamespace = "Mips64" in { def DMFC0_3OP64 : MFC3OP<(outs CPU64RegsOpnd:$rt), (ins CPU64RegsOpnd:$rd, uimm16:$sel), diff --git a/lib/Target/Mips/MipsAnalyzeImmediate.cpp b/lib/Target/Mips/MipsAnalyzeImmediate.cpp index 99b163e..31a9b7d 100644 --- a/lib/Target/Mips/MipsAnalyzeImmediate.cpp +++ b/lib/Target/Mips/MipsAnalyzeImmediate.cpp @@ -40,7 +40,7 @@ void MipsAnalyzeImmediate::GetInstSeqLsORi(uint64_t Imm, unsigned RemSize, void MipsAnalyzeImmediate::GetInstSeqLsSLL(uint64_t Imm, unsigned RemSize, InstSeqLs &SeqLs) { - unsigned Shamt = CountTrailingZeros_64(Imm); + unsigned Shamt = countTrailingZeros(Imm); GetInstSeqLs(Imm >> Shamt, RemSize - Shamt, SeqLs); AddInstr(SeqLs, Inst(SLL, Shamt)); } diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index f4f71cb..6e4feda 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -249,12 +249,18 @@ void MipsAsmPrinter::EmitFunctionEntryLabel() { void MipsAsmPrinter::EmitFunctionBodyStart() { MCInstLowering.Initialize(Mang, &MF->getContext()); - emitFrameDirective(); + bool IsNakedFunction = + MF->getFunction()-> + getAttributes().hasAttribute(AttributeSet::FunctionIndex, + Attribute::Naked); + if (!IsNakedFunction) + emitFrameDirective(); if (OutStreamer.hasRawTextSupport()) { SmallString<128> Str; raw_svector_ostream OS(Str); - printSavedRegsBitmask(OS); + if (!IsNakedFunction) + printSavedRegsBitmask(OS); OutStreamer.EmitRawText(OS.str()); if (!Subtarget->inMips16Mode()) { OutStreamer.EmitRawText(StringRef("\t.set\tnoreorder")); diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td index 462def7..ac40b11 100644 --- a/lib/Target/Mips/MipsCallingConv.td +++ b/lib/Target/Mips/MipsCallingConv.td @@ -196,6 +196,13 @@ def CC_Mips_FastCC : CallingConv<[ CCDelegateTo<CC_MipsN_FastCC> ]>; +//== + +def CC_Mips16RetHelper : CallingConv<[ + // Integer arguments are passed in integer registers. + CCIfType<[i32], CCAssignToReg<[V0, V1, A0, A1]>> +]>; + //===----------------------------------------------------------------------===// // Mips Calling Convention Dispatch //===----------------------------------------------------------------------===// @@ -223,3 +230,6 @@ def CSR_N32 : CalleeSavedRegs<(add D31_64, D29_64, D27_64, D25_64, D24_64, def CSR_N64 : CalleeSavedRegs<(add (sequence "D%u_64", 31, 24), RA_64, FP_64, GP_64, (sequence "S%u_64", 7, 0))>; + +def CSR_Mips16RetHelper : + CalleeSavedRegs<(add V0, V1, (sequence "A%u", 3, 0), S0, S1)>; diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp index 3fc402b..813037e 100644 --- a/lib/Target/Mips/MipsCodeEmitter.cpp +++ b/lib/Target/Mips/MipsCodeEmitter.cpp @@ -65,8 +65,7 @@ class MipsCodeEmitter : public MachineFunctionPass { public: MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) - : MachineFunctionPass(ID), JTI(0), - II((const MipsInstrInfo *) tm.getInstrInfo()), TD(tm.getDataLayout()), + : MachineFunctionPass(ID), JTI(0), II(0), TD(0), TM(tm), MCE(mce), MCPEs(0), MJTEs(0), IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} diff --git a/lib/Target/Mips/MipsConstantIslandPass.cpp b/lib/Target/Mips/MipsConstantIslandPass.cpp index 1951324..bda0167 100644 --- a/lib/Target/Mips/MipsConstantIslandPass.cpp +++ b/lib/Target/Mips/MipsConstantIslandPass.cpp @@ -50,7 +50,6 @@ namespace { static char ID; MipsConstantIslands(TargetMachine &tm) : MachineFunctionPass(ID), TM(tm), - TII(static_cast<const MipsInstrInfo*>(tm.getInstrInfo())), IsPIC(TM.getRelocationModel() == Reloc::PIC_), ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()) {} @@ -61,13 +60,9 @@ namespace { bool runOnMachineFunction(MachineFunction &F); private: - - const TargetMachine &TM; - const MipsInstrInfo *TII; bool IsPIC; unsigned ABI; - }; char MipsConstantIslands::ID = 0; diff --git a/lib/Target/Mips/MipsDSPInstrInfo.td b/lib/Target/Mips/MipsDSPInstrInfo.td index 710b40d..c12878a 100644 --- a/lib/Target/Mips/MipsDSPInstrInfo.td +++ b/lib/Target/Mips/MipsDSPInstrInfo.td @@ -83,16 +83,12 @@ def MipsSETCC_DSP : MipsDSPBase<"SETCC_DSP", SDTSetCC>; def MipsSELECT_CC_DSP : MipsDSPBase<"SELECT_CC_DSP", SDTSelectCC>; // Flags. -class UseAC { - list<Register> Uses = [AC0]; +class Uses<list<Register> Regs> { + list<Register> Uses = Regs; } -class UseDSPCtrl { - list<Register> Uses = [DSPCtrl]; -} - -class ClearDefs { - list<Register> Defs = []; +class Defs<list<Register> Regs> { + list<Register> Defs = Regs; } // Instruction encoding. @@ -267,7 +263,6 @@ class ADDU_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt"); list<dag> Pattern = [(set RCD:$rd, (OpNode RCS:$rs, RCT:$rt))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class RADDU_W_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -278,7 +273,6 @@ class RADDU_W_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rd, $rs"); list<dag> Pattern = [(set RCD:$rd, (OpNode RCS:$rs))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class CMP_EQ_QB_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -289,7 +283,6 @@ class CMP_EQ_QB_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rs, $rt"); list<dag> Pattern = [(OpNode RCS:$rs, RCT:$rt)]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class CMP_EQ_QB_R3_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -300,7 +293,6 @@ class CMP_EQ_QB_R3_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt"); list<dag> Pattern = [(set RCD:$rd, (OpNode RCS:$rs, RCT:$rt))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class PRECR_SRA_PH_W_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -311,7 +303,6 @@ class PRECR_SRA_PH_W_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rt, $rs, $sa"); list<dag> Pattern = [(set RCT:$rt, (OpNode RCS:$src, RCS:$rs, immZExt5:$sa))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; string Constraints = "$src = $rt"; } @@ -323,7 +314,6 @@ class ABSQ_S_PH_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rd, $rt"); list<dag> Pattern = [(set RCD:$rd, (OpNode RCT:$rt))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class REPL_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -333,7 +323,6 @@ class REPL_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rd, $imm"); list<dag> Pattern = [(set RC:$rd, (OpNode immPat:$imm))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class SHLL_QB_R3_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -343,7 +332,6 @@ class SHLL_QB_R3_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rd, $rt, $rs_sa"); list<dag> Pattern = [(set RC:$rd, (OpNode RC:$rt, CPURegs:$rs_sa))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class SHLL_QB_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -354,7 +342,6 @@ class SHLL_QB_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rd, $rt, $rs_sa"); list<dag> Pattern = [(set RC:$rd, (OpNode RC:$rt, ImmPat:$rs_sa))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; bit hasSideEffects = 1; } @@ -366,7 +353,6 @@ class LX_DESC_BASE<string instr_asm, SDPatternOperator OpNode, list<dag> Pattern = [(set CPURegs:$rd, (OpNode CPURegs:$base, CPURegs:$index))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; bit mayLoad = 1; } @@ -378,7 +364,6 @@ class ADDUH_QB_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt"); list<dag> Pattern = [(set RCD:$rd, (OpNode RCS:$rs, RCT:$rt))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class APPEND_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -389,7 +374,6 @@ class APPEND_DESC_BASE<string instr_asm, SDPatternOperator OpNode, list<dag> Pattern = [(set CPURegs:$rt, (OpNode CPURegs:$src, CPURegs:$rs, ImmOp:$sa))]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; string Constraints = "$src = $rt"; } @@ -399,7 +383,6 @@ class EXTR_W_TY1_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode, dag InOperandList = (ins ACRegsDSP:$ac, CPURegs:$shift_rs); string AsmString = !strconcat(instr_asm, "\t$rt, $ac, $shift_rs"); InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class EXTR_W_TY1_R1_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -408,7 +391,6 @@ class EXTR_W_TY1_R1_DESC_BASE<string instr_asm, SDPatternOperator OpNode, dag InOperandList = (ins ACRegsDSP:$ac, uimm16:$shift_rs); string AsmString = !strconcat(instr_asm, "\t$rt, $ac, $shift_rs"); InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class SHILO_R1_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { @@ -417,7 +399,6 @@ class SHILO_R1_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { string AsmString = !strconcat(instr_asm, "\t$ac, $shift"); list<dag> Pattern = [(set ACRegsDSP:$ac, (OpNode immSExt6:$shift, ACRegsDSP:$acin))]; - list<Register> Defs = [DSPCtrl]; string Constraints = "$acin = $ac"; } @@ -427,7 +408,6 @@ class SHILO_R2_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { string AsmString = !strconcat(instr_asm, "\t$ac, $rs"); list<dag> Pattern = [(set ACRegsDSP:$ac, (OpNode CPURegs:$rs, ACRegsDSP:$acin))]; - list<Register> Defs = [DSPCtrl]; string Constraints = "$acin = $ac"; } @@ -437,7 +417,6 @@ class MTHLIP_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { string AsmString = !strconcat(instr_asm, "\t$rs, $ac"); list<dag> Pattern = [(set ACRegsDSP:$ac, (OpNode CPURegs:$rs, ACRegsDSP:$acin))]; - list<Register> Uses = [DSPCtrl]; string Constraints = "$acin = $ac"; } @@ -448,7 +427,6 @@ class RDDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rd, $mask"); list<dag> Pattern = [(set CPURegs:$rd, (OpNode immZExt10:$mask))]; InstrItinClass Itinerary = itin; - list<Register> Uses = [DSPCtrl]; } class WRDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -458,7 +436,6 @@ class WRDSP_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rs, $mask"); list<dag> Pattern = [(OpNode CPURegs:$rs, immZExt10:$mask)]; InstrItinClass Itinerary = itin; - list<Register> Defs = [DSPCtrl]; } class DPA_W_PH_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { @@ -467,7 +444,6 @@ class DPA_W_PH_DESC_BASE<string instr_asm, SDPatternOperator OpNode> { string AsmString = !strconcat(instr_asm, "\t$ac, $rs, $rt"); list<dag> Pattern = [(set ACRegsDSP:$ac, (OpNode CPURegs:$rs, CPURegs:$rt, ACRegsDSP:$acin))]; - list<Register> Defs = [DSPCtrl]; string Constraints = "$acin = $ac"; } @@ -510,7 +486,6 @@ class MTHI_DESC_BASE<string instr_asm, RegisterClass RC, InstrItinClass itin> { class BPOSGE32_PSEUDO_DESC_BASE<SDPatternOperator OpNode, InstrItinClass itin> : MipsPseudo<(outs CPURegs:$dst), (ins), [(set CPURegs:$dst, (OpNode))]> { - list<Register> Uses = [DSPCtrl]; bit usesCustomInserter = 1; } @@ -519,7 +494,6 @@ class BPOSGE32_DESC_BASE<string instr_asm, InstrItinClass itin> { dag InOperandList = (ins brtarget:$offset); string AsmString = !strconcat(instr_asm, "\t$offset"); InstrItinClass Itinerary = itin; - list<Register> Uses = [DSPCtrl]; bit isBranch = 1; bit isTerminator = 1; bit hasDelaySlot = 1; @@ -532,7 +506,6 @@ class INSV_DESC_BASE<string instr_asm, SDPatternOperator OpNode, string AsmString = !strconcat(instr_asm, "\t$rt, $rs"); list<dag> Pattern = [(set CPURegs:$rt, (OpNode CPURegs:$src, CPURegs:$rs))]; InstrItinClass Itinerary = itin; - list<Register> Uses = [DSPCtrl]; string Constraints = "$src = $rt"; } @@ -542,177 +515,182 @@ class INSV_DESC_BASE<string instr_asm, SDPatternOperator OpNode, // Addition/subtraction class ADDU_QB_DESC : ADDU_QB_DESC_BASE<"addu.qb", null_frag, NoItinerary, - DSPRegs, DSPRegs>, IsCommutable; + DSPRegs, DSPRegs>, IsCommutable, + Defs<[DSPOutFlag20]>; class ADDU_S_QB_DESC : ADDU_QB_DESC_BASE<"addu_s.qb", int_mips_addu_s_qb, NoItinerary, DSPRegs, DSPRegs>, - IsCommutable; + IsCommutable, Defs<[DSPOutFlag20]>; class SUBU_QB_DESC : ADDU_QB_DESC_BASE<"subu.qb", null_frag, NoItinerary, - DSPRegs, DSPRegs>; + DSPRegs, DSPRegs>, + Defs<[DSPOutFlag20]>; class SUBU_S_QB_DESC : ADDU_QB_DESC_BASE<"subu_s.qb", int_mips_subu_s_qb, - NoItinerary, DSPRegs, DSPRegs>; + NoItinerary, DSPRegs, DSPRegs>, + Defs<[DSPOutFlag20]>; class ADDQ_PH_DESC : ADDU_QB_DESC_BASE<"addq.ph", null_frag, NoItinerary, - DSPRegs, DSPRegs>, IsCommutable; + DSPRegs, DSPRegs>, IsCommutable, + Defs<[DSPOutFlag20]>; class ADDQ_S_PH_DESC : ADDU_QB_DESC_BASE<"addq_s.ph", int_mips_addq_s_ph, NoItinerary, DSPRegs, DSPRegs>, - IsCommutable; + IsCommutable, Defs<[DSPOutFlag20]>; class SUBQ_PH_DESC : ADDU_QB_DESC_BASE<"subq.ph", null_frag, NoItinerary, - DSPRegs, DSPRegs>; + DSPRegs, DSPRegs>, + Defs<[DSPOutFlag20]>; class SUBQ_S_PH_DESC : ADDU_QB_DESC_BASE<"subq_s.ph", int_mips_subq_s_ph, - NoItinerary, DSPRegs, DSPRegs>; + NoItinerary, DSPRegs, DSPRegs>, + Defs<[DSPOutFlag20]>; class ADDQ_S_W_DESC : ADDU_QB_DESC_BASE<"addq_s.w", int_mips_addq_s_w, NoItinerary, CPURegs, CPURegs>, - IsCommutable; + IsCommutable, Defs<[DSPOutFlag20]>; class SUBQ_S_W_DESC : ADDU_QB_DESC_BASE<"subq_s.w", int_mips_subq_s_w, - NoItinerary, CPURegs, CPURegs>; + NoItinerary, CPURegs, CPURegs>, + Defs<[DSPOutFlag20]>; class ADDSC_DESC : ADDU_QB_DESC_BASE<"addsc", null_frag, NoItinerary, - CPURegs, CPURegs>, IsCommutable; + CPURegs, CPURegs>, IsCommutable, + Defs<[DSPCarry]>; class ADDWC_DESC : ADDU_QB_DESC_BASE<"addwc", null_frag, NoItinerary, CPURegs, CPURegs>, - IsCommutable, UseDSPCtrl; + IsCommutable, Uses<[DSPCarry]>, Defs<[DSPOutFlag20]>; class MODSUB_DESC : ADDU_QB_DESC_BASE<"modsub", int_mips_modsub, NoItinerary, - CPURegs, CPURegs>, ClearDefs; + CPURegs, CPURegs>; class RADDU_W_QB_DESC : RADDU_W_QB_DESC_BASE<"raddu.w.qb", int_mips_raddu_w_qb, - NoItinerary, CPURegs, DSPRegs>, - ClearDefs; + NoItinerary, CPURegs, DSPRegs>; // Absolute value class ABSQ_S_PH_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.ph", int_mips_absq_s_ph, - NoItinerary, DSPRegs>; + NoItinerary, DSPRegs>, + Defs<[DSPOutFlag20]>; class ABSQ_S_W_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.w", int_mips_absq_s_w, - NoItinerary, CPURegs>; + NoItinerary, CPURegs>, + Defs<[DSPOutFlag20]>; // Precision reduce/expand class PRECRQ_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq.qb.ph", int_mips_precrq_qb_ph, - NoItinerary, DSPRegs, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs, DSPRegs>; class PRECRQ_PH_W_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq.ph.w", int_mips_precrq_ph_w, - NoItinerary, DSPRegs, CPURegs>, - ClearDefs; + NoItinerary, DSPRegs, CPURegs>; class PRECRQ_RS_PH_W_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrq_rs.ph.w", int_mips_precrq_rs_ph_w, NoItinerary, DSPRegs, - CPURegs>; + CPURegs>, + Defs<[DSPOutFlag22]>; class PRECRQU_S_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precrqu_s.qb.ph", int_mips_precrqu_s_qb_ph, NoItinerary, DSPRegs, - DSPRegs>; + DSPRegs>, + Defs<[DSPOutFlag22]>; class PRECEQ_W_PHL_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceq.w.phl", int_mips_preceq_w_phl, - NoItinerary, CPURegs, DSPRegs>, - ClearDefs; + NoItinerary, CPURegs, DSPRegs>; class PRECEQ_W_PHR_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceq.w.phr", int_mips_preceq_w_phr, - NoItinerary, CPURegs, DSPRegs>, - ClearDefs; + NoItinerary, CPURegs, DSPRegs>; class PRECEQU_PH_QBL_DESC : ABSQ_S_PH_R2_DESC_BASE<"precequ.ph.qbl", int_mips_precequ_ph_qbl, - NoItinerary, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs>; class PRECEQU_PH_QBR_DESC : ABSQ_S_PH_R2_DESC_BASE<"precequ.ph.qbr", int_mips_precequ_ph_qbr, - NoItinerary, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs>; class PRECEQU_PH_QBLA_DESC : ABSQ_S_PH_R2_DESC_BASE<"precequ.ph.qbla", int_mips_precequ_ph_qbla, - NoItinerary, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs>; class PRECEQU_PH_QBRA_DESC : ABSQ_S_PH_R2_DESC_BASE<"precequ.ph.qbra", int_mips_precequ_ph_qbra, - NoItinerary, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs>; class PRECEU_PH_QBL_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceu.ph.qbl", int_mips_preceu_ph_qbl, - NoItinerary, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs>; class PRECEU_PH_QBR_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceu.ph.qbr", int_mips_preceu_ph_qbr, - NoItinerary, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs>; class PRECEU_PH_QBLA_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceu.ph.qbla", int_mips_preceu_ph_qbla, - NoItinerary, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs>; class PRECEU_PH_QBRA_DESC : ABSQ_S_PH_R2_DESC_BASE<"preceu.ph.qbra", int_mips_preceu_ph_qbra, - NoItinerary, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs>; // Shift class SHLL_QB_DESC : SHLL_QB_R2_DESC_BASE<"shll.qb", null_frag, immZExt3, - NoItinerary, DSPRegs>; + NoItinerary, DSPRegs>, + Defs<[DSPOutFlag22]>; class SHLLV_QB_DESC : SHLL_QB_R3_DESC_BASE<"shllv.qb", int_mips_shll_qb, - NoItinerary, DSPRegs>; + NoItinerary, DSPRegs>, + Defs<[DSPOutFlag22]>; class SHRL_QB_DESC : SHLL_QB_R2_DESC_BASE<"shrl.qb", null_frag, immZExt3, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SHRLV_QB_DESC : SHLL_QB_R3_DESC_BASE<"shrlv.qb", int_mips_shrl_qb, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SHLL_PH_DESC : SHLL_QB_R2_DESC_BASE<"shll.ph", null_frag, immZExt4, - NoItinerary, DSPRegs>; + NoItinerary, DSPRegs>, + Defs<[DSPOutFlag22]>; class SHLLV_PH_DESC : SHLL_QB_R3_DESC_BASE<"shllv.ph", int_mips_shll_ph, - NoItinerary, DSPRegs>; + NoItinerary, DSPRegs>, + Defs<[DSPOutFlag22]>; class SHLL_S_PH_DESC : SHLL_QB_R2_DESC_BASE<"shll_s.ph", int_mips_shll_s_ph, - immZExt4, NoItinerary, DSPRegs>; + immZExt4, NoItinerary, DSPRegs>, + Defs<[DSPOutFlag22]>; class SHLLV_S_PH_DESC : SHLL_QB_R3_DESC_BASE<"shllv_s.ph", int_mips_shll_s_ph, - NoItinerary, DSPRegs>; + NoItinerary, DSPRegs>, + Defs<[DSPOutFlag22]>; class SHRA_PH_DESC : SHLL_QB_R2_DESC_BASE<"shra.ph", null_frag, immZExt4, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SHRAV_PH_DESC : SHLL_QB_R3_DESC_BASE<"shrav.ph", int_mips_shra_ph, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SHRA_R_PH_DESC : SHLL_QB_R2_DESC_BASE<"shra_r.ph", int_mips_shra_r_ph, - immZExt4, NoItinerary, DSPRegs>, - ClearDefs; + immZExt4, NoItinerary, DSPRegs>; class SHRAV_R_PH_DESC : SHLL_QB_R3_DESC_BASE<"shrav_r.ph", int_mips_shra_r_ph, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SHLL_S_W_DESC : SHLL_QB_R2_DESC_BASE<"shll_s.w", int_mips_shll_s_w, - immZExt5, NoItinerary, CPURegs>; + immZExt5, NoItinerary, CPURegs>, + Defs<[DSPOutFlag22]>; class SHLLV_S_W_DESC : SHLL_QB_R3_DESC_BASE<"shllv_s.w", int_mips_shll_s_w, - NoItinerary, CPURegs>; + NoItinerary, CPURegs>, + Defs<[DSPOutFlag22]>; class SHRA_R_W_DESC : SHLL_QB_R2_DESC_BASE<"shra_r.w", int_mips_shra_r_w, - immZExt5, NoItinerary, CPURegs>, - ClearDefs; + immZExt5, NoItinerary, CPURegs>; class SHRAV_R_W_DESC : SHLL_QB_R3_DESC_BASE<"shrav_r.w", int_mips_shra_r_w, NoItinerary, CPURegs>; @@ -720,36 +698,43 @@ class SHRAV_R_W_DESC : SHLL_QB_R3_DESC_BASE<"shrav_r.w", int_mips_shra_r_w, // Multiplication class MULEU_S_PH_QBL_DESC : ADDU_QB_DESC_BASE<"muleu_s.ph.qbl", int_mips_muleu_s_ph_qbl, - NoItinerary, DSPRegs, DSPRegs>; + NoItinerary, DSPRegs, DSPRegs>, + Defs<[DSPOutFlag21]>; class MULEU_S_PH_QBR_DESC : ADDU_QB_DESC_BASE<"muleu_s.ph.qbr", int_mips_muleu_s_ph_qbr, - NoItinerary, DSPRegs, DSPRegs>; + NoItinerary, DSPRegs, DSPRegs>, + Defs<[DSPOutFlag21]>; class MULEQ_S_W_PHL_DESC : ADDU_QB_DESC_BASE<"muleq_s.w.phl", int_mips_muleq_s_w_phl, NoItinerary, CPURegs, DSPRegs>, - IsCommutable; + IsCommutable, Defs<[DSPOutFlag21]>; class MULEQ_S_W_PHR_DESC : ADDU_QB_DESC_BASE<"muleq_s.w.phr", int_mips_muleq_s_w_phr, NoItinerary, CPURegs, DSPRegs>, - IsCommutable; + IsCommutable, Defs<[DSPOutFlag21]>; class MULQ_RS_PH_DESC : ADDU_QB_DESC_BASE<"mulq_rs.ph", int_mips_mulq_rs_ph, NoItinerary, DSPRegs, DSPRegs>, - IsCommutable; + IsCommutable, Defs<[DSPOutFlag21]>; class MULSAQ_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"mulsaq_s.w.ph", - MipsMULSAQ_S_W_PH>; + MipsMULSAQ_S_W_PH>, + Defs<[DSPOutFlag16_19]>; -class MAQ_S_W_PHL_DESC : DPA_W_PH_DESC_BASE<"maq_s.w.phl", MipsMAQ_S_W_PHL>; +class MAQ_S_W_PHL_DESC : DPA_W_PH_DESC_BASE<"maq_s.w.phl", MipsMAQ_S_W_PHL>, + Defs<[DSPOutFlag16_19]>; -class MAQ_S_W_PHR_DESC : DPA_W_PH_DESC_BASE<"maq_s.w.phr", MipsMAQ_S_W_PHR>; +class MAQ_S_W_PHR_DESC : DPA_W_PH_DESC_BASE<"maq_s.w.phr", MipsMAQ_S_W_PHR>, + Defs<[DSPOutFlag16_19]>; -class MAQ_SA_W_PHL_DESC : DPA_W_PH_DESC_BASE<"maq_sa.w.phl", MipsMAQ_SA_W_PHL>; +class MAQ_SA_W_PHL_DESC : DPA_W_PH_DESC_BASE<"maq_sa.w.phl", MipsMAQ_SA_W_PHL>, + Defs<[DSPOutFlag16_19]>; -class MAQ_SA_W_PHR_DESC : DPA_W_PH_DESC_BASE<"maq_sa.w.phr", MipsMAQ_SA_W_PHR>; +class MAQ_SA_W_PHR_DESC : DPA_W_PH_DESC_BASE<"maq_sa.w.phr", MipsMAQ_SA_W_PHR>, + Defs<[DSPOutFlag16_19]>; // Move from/to hi/lo. class MFHI_DESC : MFHI_DESC_BASE<"mfhi", HIRegsDSP, NoItinerary>; @@ -766,13 +751,17 @@ class DPSU_H_QBL_DESC : DPA_W_PH_DESC_BASE<"dpsu.h.qbl", MipsDPSU_H_QBL>; class DPSU_H_QBR_DESC : DPA_W_PH_DESC_BASE<"dpsu.h.qbr", MipsDPSU_H_QBR>; -class DPAQ_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpaq_s.w.ph", MipsDPAQ_S_W_PH>; +class DPAQ_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpaq_s.w.ph", MipsDPAQ_S_W_PH>, + Defs<[DSPOutFlag16_19]>; -class DPSQ_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsq_s.w.ph", MipsDPSQ_S_W_PH>; +class DPSQ_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsq_s.w.ph", MipsDPSQ_S_W_PH>, + Defs<[DSPOutFlag16_19]>; -class DPAQ_SA_L_W_DESC : DPA_W_PH_DESC_BASE<"dpaq_sa.l.w", MipsDPAQ_SA_L_W>; +class DPAQ_SA_L_W_DESC : DPA_W_PH_DESC_BASE<"dpaq_sa.l.w", MipsDPAQ_SA_L_W>, + Defs<[DSPOutFlag16_19]>; -class DPSQ_SA_L_W_DESC : DPA_W_PH_DESC_BASE<"dpsq_sa.l.w", MipsDPSQ_SA_L_W>; +class DPSQ_SA_L_W_DESC : DPA_W_PH_DESC_BASE<"dpsq_sa.l.w", MipsDPSQ_SA_L_W>, + Defs<[DSPOutFlag16_19]>; class MULT_DSP_DESC : MULT_DESC_BASE<"mult", MipsMult, NoItinerary>; class MULTU_DSP_DESC : MULT_DESC_BASE<"multu", MipsMultu, NoItinerary>; @@ -784,15 +773,16 @@ class MSUBU_DSP_DESC : MADD_DESC_BASE<"msubu", MipsMSubu, NoItinerary>; // Comparison class CMPU_EQ_QB_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmpu.eq.qb", int_mips_cmpu_eq_qb, NoItinerary, - DSPRegs>, IsCommutable; + DSPRegs>, + IsCommutable, Defs<[DSPCCond]>; class CMPU_LT_QB_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmpu.lt.qb", int_mips_cmpu_lt_qb, NoItinerary, - DSPRegs>; + DSPRegs>, Defs<[DSPCCond]>; class CMPU_LE_QB_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmpu.le.qb", int_mips_cmpu_le_qb, NoItinerary, - DSPRegs>; + DSPRegs>, Defs<[DSPCCond]>; class CMPGU_EQ_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgu.eq.qb", int_mips_cmpgu_eq_qb, @@ -809,208 +799,227 @@ class CMPGU_LE_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgu.le.qb", class CMP_EQ_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.eq.ph", int_mips_cmp_eq_ph, NoItinerary, DSPRegs>, - IsCommutable; + IsCommutable, Defs<[DSPCCond]>; class CMP_LT_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.lt.ph", int_mips_cmp_lt_ph, - NoItinerary, DSPRegs>; + NoItinerary, DSPRegs>, + Defs<[DSPCCond]>; class CMP_LE_PH_DESC : CMP_EQ_QB_R2_DESC_BASE<"cmp.le.ph", int_mips_cmp_le_ph, - NoItinerary, DSPRegs>; + NoItinerary, DSPRegs>, + Defs<[DSPCCond]>; // Misc class BITREV_DESC : ABSQ_S_PH_R2_DESC_BASE<"bitrev", int_mips_bitrev, - NoItinerary, CPURegs>, ClearDefs; + NoItinerary, CPURegs>; class PACKRL_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"packrl.ph", int_mips_packrl_ph, - NoItinerary, DSPRegs, DSPRegs>, - ClearDefs; + NoItinerary, DSPRegs, DSPRegs>; class REPL_QB_DESC : REPL_DESC_BASE<"repl.qb", int_mips_repl_qb, immZExt8, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class REPL_PH_DESC : REPL_DESC_BASE<"repl.ph", int_mips_repl_ph, immZExt10, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class REPLV_QB_DESC : ABSQ_S_PH_R2_DESC_BASE<"replv.qb", int_mips_repl_qb, - NoItinerary, DSPRegs, CPURegs>, - ClearDefs; + NoItinerary, DSPRegs, CPURegs>; class REPLV_PH_DESC : ABSQ_S_PH_R2_DESC_BASE<"replv.ph", int_mips_repl_ph, - NoItinerary, DSPRegs, CPURegs>, - ClearDefs; + NoItinerary, DSPRegs, CPURegs>; class PICK_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"pick.qb", int_mips_pick_qb, NoItinerary, DSPRegs, DSPRegs>, - ClearDefs, UseDSPCtrl; + Uses<[DSPCCond]>; class PICK_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"pick.ph", int_mips_pick_ph, NoItinerary, DSPRegs, DSPRegs>, - ClearDefs, UseDSPCtrl; + Uses<[DSPCCond]>; -class LWX_DESC : LX_DESC_BASE<"lwx", int_mips_lwx, NoItinerary>, ClearDefs; +class LWX_DESC : LX_DESC_BASE<"lwx", int_mips_lwx, NoItinerary>; -class LHX_DESC : LX_DESC_BASE<"lhx", int_mips_lhx, NoItinerary>, ClearDefs; +class LHX_DESC : LX_DESC_BASE<"lhx", int_mips_lhx, NoItinerary>; -class LBUX_DESC : LX_DESC_BASE<"lbux", int_mips_lbux, NoItinerary>, ClearDefs; +class LBUX_DESC : LX_DESC_BASE<"lbux", int_mips_lbux, NoItinerary>; class BPOSGE32_DESC : BPOSGE32_DESC_BASE<"bposge32", NoItinerary>; // Extr -class EXTP_DESC : EXTR_W_TY1_R1_DESC_BASE<"extp", MipsEXTP, NoItinerary>; +class EXTP_DESC : EXTR_W_TY1_R1_DESC_BASE<"extp", MipsEXTP, NoItinerary>, + Uses<[DSPPos]>, Defs<[DSPEFI]>; -class EXTPV_DESC : EXTR_W_TY1_R2_DESC_BASE<"extpv", MipsEXTP, NoItinerary>; +class EXTPV_DESC : EXTR_W_TY1_R2_DESC_BASE<"extpv", MipsEXTP, NoItinerary>, + Uses<[DSPPos]>, Defs<[DSPEFI]>; -class EXTPDP_DESC : EXTR_W_TY1_R1_DESC_BASE<"extpdp", MipsEXTPDP, NoItinerary>; +class EXTPDP_DESC : EXTR_W_TY1_R1_DESC_BASE<"extpdp", MipsEXTPDP, NoItinerary>, + Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>; class EXTPDPV_DESC : EXTR_W_TY1_R2_DESC_BASE<"extpdpv", MipsEXTPDP, - NoItinerary>; + NoItinerary>, + Uses<[DSPPos]>, Defs<[DSPPos, DSPEFI]>; -class EXTR_W_DESC : EXTR_W_TY1_R1_DESC_BASE<"extr.w", MipsEXTR_W, NoItinerary>; +class EXTR_W_DESC : EXTR_W_TY1_R1_DESC_BASE<"extr.w", MipsEXTR_W, NoItinerary>, + Defs<[DSPOutFlag23]>; class EXTRV_W_DESC : EXTR_W_TY1_R2_DESC_BASE<"extrv.w", MipsEXTR_W, - NoItinerary>; + NoItinerary>, Defs<[DSPOutFlag23]>; class EXTR_R_W_DESC : EXTR_W_TY1_R1_DESC_BASE<"extr_r.w", MipsEXTR_R_W, - NoItinerary>; + NoItinerary>, + Defs<[DSPOutFlag23]>; class EXTRV_R_W_DESC : EXTR_W_TY1_R2_DESC_BASE<"extrv_r.w", MipsEXTR_R_W, - NoItinerary>; + NoItinerary>, + Defs<[DSPOutFlag23]>; class EXTR_RS_W_DESC : EXTR_W_TY1_R1_DESC_BASE<"extr_rs.w", MipsEXTR_RS_W, - NoItinerary>; + NoItinerary>, + Defs<[DSPOutFlag23]>; class EXTRV_RS_W_DESC : EXTR_W_TY1_R2_DESC_BASE<"extrv_rs.w", MipsEXTR_RS_W, - NoItinerary>; + NoItinerary>, + Defs<[DSPOutFlag23]>; class EXTR_S_H_DESC : EXTR_W_TY1_R1_DESC_BASE<"extr_s.h", MipsEXTR_S_H, - NoItinerary>; + NoItinerary>, + Defs<[DSPOutFlag23]>; class EXTRV_S_H_DESC : EXTR_W_TY1_R2_DESC_BASE<"extrv_s.h", MipsEXTR_S_H, - NoItinerary>; + NoItinerary>, + Defs<[DSPOutFlag23]>; class SHILO_DESC : SHILO_R1_DESC_BASE<"shilo", MipsSHILO>; class SHILOV_DESC : SHILO_R2_DESC_BASE<"shilov", MipsSHILO>; -class MTHLIP_DESC : MTHLIP_DESC_BASE<"mthlip", MipsMTHLIP>; +class MTHLIP_DESC : MTHLIP_DESC_BASE<"mthlip", MipsMTHLIP>, Defs<[DSPPos]>; class RDDSP_DESC : RDDSP_DESC_BASE<"rddsp", int_mips_rddsp, NoItinerary>; class WRDSP_DESC : WRDSP_DESC_BASE<"wrdsp", int_mips_wrdsp, NoItinerary>; -class INSV_DESC : INSV_DESC_BASE<"insv", int_mips_insv, NoItinerary>; +class INSV_DESC : INSV_DESC_BASE<"insv", int_mips_insv, NoItinerary>, + Uses<[DSPPos, DSPSCount]>; //===----------------------------------------------------------------------===// // MIPS DSP Rev 2 // Addition/subtraction class ADDU_PH_DESC : ADDU_QB_DESC_BASE<"addu.ph", int_mips_addu_ph, NoItinerary, - DSPRegs, DSPRegs>, IsCommutable; + DSPRegs, DSPRegs>, IsCommutable, + Defs<[DSPOutFlag20]>; class ADDU_S_PH_DESC : ADDU_QB_DESC_BASE<"addu_s.ph", int_mips_addu_s_ph, NoItinerary, DSPRegs, DSPRegs>, - IsCommutable; + IsCommutable, Defs<[DSPOutFlag20]>; class SUBU_PH_DESC : ADDU_QB_DESC_BASE<"subu.ph", int_mips_subu_ph, NoItinerary, - DSPRegs, DSPRegs>; + DSPRegs, DSPRegs>, + Defs<[DSPOutFlag20]>; class SUBU_S_PH_DESC : ADDU_QB_DESC_BASE<"subu_s.ph", int_mips_subu_s_ph, - NoItinerary, DSPRegs, DSPRegs>; + NoItinerary, DSPRegs, DSPRegs>, + Defs<[DSPOutFlag20]>; class ADDUH_QB_DESC : ADDUH_QB_DESC_BASE<"adduh.qb", int_mips_adduh_qb, - NoItinerary, DSPRegs>, - ClearDefs, IsCommutable; + NoItinerary, DSPRegs>, IsCommutable; class ADDUH_R_QB_DESC : ADDUH_QB_DESC_BASE<"adduh_r.qb", int_mips_adduh_r_qb, - NoItinerary, DSPRegs>, - ClearDefs, IsCommutable; + NoItinerary, DSPRegs>, IsCommutable; class SUBUH_QB_DESC : ADDUH_QB_DESC_BASE<"subuh.qb", int_mips_subuh_qb, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SUBUH_R_QB_DESC : ADDUH_QB_DESC_BASE<"subuh_r.qb", int_mips_subuh_r_qb, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class ADDQH_PH_DESC : ADDUH_QB_DESC_BASE<"addqh.ph", int_mips_addqh_ph, - NoItinerary, DSPRegs>, - ClearDefs, IsCommutable; + NoItinerary, DSPRegs>, IsCommutable; class ADDQH_R_PH_DESC : ADDUH_QB_DESC_BASE<"addqh_r.ph", int_mips_addqh_r_ph, - NoItinerary, DSPRegs>, - ClearDefs, IsCommutable; + NoItinerary, DSPRegs>, IsCommutable; class SUBQH_PH_DESC : ADDUH_QB_DESC_BASE<"subqh.ph", int_mips_subqh_ph, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SUBQH_R_PH_DESC : ADDUH_QB_DESC_BASE<"subqh_r.ph", int_mips_subqh_r_ph, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class ADDQH_W_DESC : ADDUH_QB_DESC_BASE<"addqh.w", int_mips_addqh_w, - NoItinerary, CPURegs>, - ClearDefs, IsCommutable; + NoItinerary, CPURegs>, IsCommutable; class ADDQH_R_W_DESC : ADDUH_QB_DESC_BASE<"addqh_r.w", int_mips_addqh_r_w, - NoItinerary, CPURegs>, - ClearDefs, IsCommutable; + NoItinerary, CPURegs>, IsCommutable; class SUBQH_W_DESC : ADDUH_QB_DESC_BASE<"subqh.w", int_mips_subqh_w, - NoItinerary, CPURegs>, ClearDefs; + NoItinerary, CPURegs>; class SUBQH_R_W_DESC : ADDUH_QB_DESC_BASE<"subqh_r.w", int_mips_subqh_r_w, - NoItinerary, CPURegs>, ClearDefs; + NoItinerary, CPURegs>; // Comparison class CMPGDU_EQ_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.eq.qb", int_mips_cmpgdu_eq_qb, NoItinerary, CPURegs, DSPRegs>, - IsCommutable; + IsCommutable, Defs<[DSPCCond]>; class CMPGDU_LT_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.lt.qb", int_mips_cmpgdu_lt_qb, - NoItinerary, CPURegs, DSPRegs>; + NoItinerary, CPURegs, DSPRegs>, + Defs<[DSPCCond]>; class CMPGDU_LE_QB_DESC : CMP_EQ_QB_R3_DESC_BASE<"cmpgdu.le.qb", int_mips_cmpgdu_le_qb, - NoItinerary, CPURegs, DSPRegs>; + NoItinerary, CPURegs, DSPRegs>, + Defs<[DSPCCond]>; // Absolute class ABSQ_S_QB_DESC : ABSQ_S_PH_R2_DESC_BASE<"absq_s.qb", int_mips_absq_s_qb, - NoItinerary, DSPRegs>; + NoItinerary, DSPRegs>, + Defs<[DSPOutFlag20]>; // Multiplication class MUL_PH_DESC : ADDUH_QB_DESC_BASE<"mul.ph", null_frag, NoItinerary, - DSPRegs>, IsCommutable; + DSPRegs>, IsCommutable, + Defs<[DSPOutFlag21]>; class MUL_S_PH_DESC : ADDUH_QB_DESC_BASE<"mul_s.ph", int_mips_mul_s_ph, - NoItinerary, DSPRegs>, IsCommutable; + NoItinerary, DSPRegs>, IsCommutable, + Defs<[DSPOutFlag21]>; class MULQ_S_W_DESC : ADDUH_QB_DESC_BASE<"mulq_s.w", int_mips_mulq_s_w, - NoItinerary, CPURegs>, IsCommutable; + NoItinerary, CPURegs>, IsCommutable, + Defs<[DSPOutFlag21]>; class MULQ_RS_W_DESC : ADDUH_QB_DESC_BASE<"mulq_rs.w", int_mips_mulq_rs_w, - NoItinerary, CPURegs>, IsCommutable; + NoItinerary, CPURegs>, IsCommutable, + Defs<[DSPOutFlag21]>; class MULQ_S_PH_DESC : ADDU_QB_DESC_BASE<"mulq_s.ph", int_mips_mulq_s_ph, NoItinerary, DSPRegs, DSPRegs>, - IsCommutable; + IsCommutable, Defs<[DSPOutFlag21]>; // Dot product with accumulate/subtract class DPA_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpa.w.ph", MipsDPA_W_PH>; class DPS_W_PH_DESC : DPA_W_PH_DESC_BASE<"dps.w.ph", MipsDPS_W_PH>; -class DPAQX_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpaqx_s.w.ph", MipsDPAQX_S_W_PH>; +class DPAQX_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpaqx_s.w.ph", MipsDPAQX_S_W_PH>, + Defs<[DSPOutFlag16_19]>; class DPAQX_SA_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpaqx_sa.w.ph", - MipsDPAQX_SA_W_PH>; + MipsDPAQX_SA_W_PH>, + Defs<[DSPOutFlag16_19]>; class DPAX_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpax.w.ph", MipsDPAX_W_PH>; class DPSX_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsx.w.ph", MipsDPSX_W_PH>; -class DPSQX_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsqx_s.w.ph", MipsDPSQX_S_W_PH>; +class DPSQX_S_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsqx_s.w.ph", MipsDPSQX_S_W_PH>, + Defs<[DSPOutFlag16_19]>; class DPSQX_SA_W_PH_DESC : DPA_W_PH_DESC_BASE<"dpsqx_sa.w.ph", - MipsDPSQX_SA_W_PH>; + MipsDPSQX_SA_W_PH>, + Defs<[DSPOutFlag16_19]>; class MULSA_W_PH_DESC : DPA_W_PH_DESC_BASE<"mulsa.w.ph", MipsMULSA_W_PH>; @@ -1022,45 +1031,45 @@ class PRECR_QB_PH_DESC : CMP_EQ_QB_R3_DESC_BASE<"precr.qb.ph", class PRECR_SRA_PH_W_DESC : PRECR_SRA_PH_W_DESC_BASE<"precr_sra.ph.w", int_mips_precr_sra_ph_w, NoItinerary, DSPRegs, - CPURegs>, ClearDefs; + CPURegs>; class PRECR_SRA_R_PH_W_DESC : PRECR_SRA_PH_W_DESC_BASE<"precr_sra_r.ph.w", int_mips_precr_sra_r_ph_w, NoItinerary, DSPRegs, - CPURegs>, ClearDefs; + CPURegs>; // Shift class SHRA_QB_DESC : SHLL_QB_R2_DESC_BASE<"shra.qb", null_frag, immZExt3, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SHRAV_QB_DESC : SHLL_QB_R3_DESC_BASE<"shrav.qb", int_mips_shra_qb, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SHRA_R_QB_DESC : SHLL_QB_R2_DESC_BASE<"shra_r.qb", int_mips_shra_r_qb, - immZExt3, NoItinerary, DSPRegs>, - ClearDefs; + immZExt3, NoItinerary, DSPRegs>; class SHRAV_R_QB_DESC : SHLL_QB_R3_DESC_BASE<"shrav_r.qb", int_mips_shra_r_qb, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SHRL_PH_DESC : SHLL_QB_R2_DESC_BASE<"shrl.ph", null_frag, immZExt4, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; class SHRLV_PH_DESC : SHLL_QB_R3_DESC_BASE<"shrlv.ph", int_mips_shrl_ph, - NoItinerary, DSPRegs>, ClearDefs; + NoItinerary, DSPRegs>; // Misc class APPEND_DESC : APPEND_DESC_BASE<"append", int_mips_append, immZExt5, - NoItinerary>, ClearDefs; + NoItinerary>; class BALIGN_DESC : APPEND_DESC_BASE<"balign", int_mips_balign, immZExt2, - NoItinerary>, ClearDefs; + NoItinerary>; class PREPEND_DESC : APPEND_DESC_BASE<"prepend", int_mips_prepend, immZExt5, - NoItinerary>, ClearDefs; + NoItinerary>; // Pseudos. -def BPOSGE32_PSEUDO : BPOSGE32_PSEUDO_DESC_BASE<int_mips_bposge32, NoItinerary>; +def BPOSGE32_PSEUDO : BPOSGE32_PSEUDO_DESC_BASE<int_mips_bposge32, + NoItinerary>, Uses<[DSPPos]>; // Instruction defs. // MIPS DSP Rev 1 @@ -1231,10 +1240,14 @@ def PREPEND : PREPEND_ENC, PREPEND_DESC; } // Pseudos. -/// Pseudo instructions for loading and storing accumulator registers. let isPseudo = 1 in { + // Pseudo instructions for loading and storing accumulator registers. defm LOAD_AC_DSP : LoadM<"load_ac_dsp", ACRegsDSP>; defm STORE_AC_DSP : StoreM<"store_ac_dsp", ACRegsDSP>; + + // Pseudos for loading and storing ccond field of DSP control register. + defm LOAD_CCOND_DSP : LoadM<"load_ccond_dsp", DSPCC>; + defm STORE_CCOND_DSP : StoreM<"store_ccond_dsp", DSPCC>; } // Pseudo CMP and PICK instructions. diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp index d07a595..928a43d 100644 --- a/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -177,7 +177,7 @@ namespace { class Filler : public MachineFunctionPass { public: Filler(TargetMachine &tm) - : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { } + : MachineFunctionPass(ID), TM(tm) { } virtual const char *getPassName() const { return "Mips Delay Slot Filler"; @@ -243,7 +243,6 @@ namespace { bool terminateSearch(const MachineInstr &Candidate) const; TargetMachine &TM; - const TargetInstrInfo *TII; static char ID; }; @@ -514,6 +513,8 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { } // Bundle the NOP to the instruction with the delay slot. + const MipsInstrInfo *TII = + static_cast<const MipsInstrInfo*>(TM.getInstrInfo()); BuildMI(MBB, llvm::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); MIBundleBuilder(MBB, I, llvm::next(llvm::next(I))); } diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 968e536..a1de174 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -57,7 +57,7 @@ bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { /// GOT address into a register. SDNode *MipsDAGToDAGISel::getGlobalBaseReg() { unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg(); - return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode(); + return CurDAG->getRegister(GlobalBaseReg, TLI->getPointerTy()).getNode(); } /// ComplexPattern used on MipsInstrInfo diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 4d76181..6351073 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -43,6 +43,11 @@ static cl::opt<bool> LargeGOT("mxgot", cl::Hidden, cl::desc("MIPS: Enable GOT larger than 64k."), cl::init(false)); +static cl::opt<bool> +NoZeroDivCheck("mno-check-zero-division", cl::Hidden, + cl::desc("MIPS: Don't trap on integer division by zero."), + cl::init(false)); + static const uint16_t O32IntRegs[4] = { Mips::A0, Mips::A1, Mips::A2, Mips::A3 }; @@ -65,7 +70,7 @@ static bool isShiftedMask(uint64_t I, uint64_t &Pos, uint64_t &Size) { return false; Size = CountPopulation_64(I); - Pos = CountTrailingZeros_64(I); + Pos = countTrailingZeros(I); return true; } @@ -78,7 +83,7 @@ static SDValue getTargetNode(SDValue Op, SelectionDAG &DAG, unsigned Flag) { EVT Ty = Op.getValueType(); if (GlobalAddressSDNode *N = dyn_cast<GlobalAddressSDNode>(Op)) - return DAG.getTargetGlobalAddress(N->getGlobal(), Op.getDebugLoc(), Ty, 0, + return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(Op), Ty, 0, Flag); if (ExternalSymbolSDNode *N = dyn_cast<ExternalSymbolSDNode>(Op)) return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag); @@ -95,7 +100,7 @@ static SDValue getTargetNode(SDValue Op, SelectionDAG &DAG, unsigned Flag) { } static SDValue getAddrNonPIC(SDValue Op, SelectionDAG &DAG) { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getValueType(); SDValue Hi = getTargetNode(Op, DAG, MipsII::MO_ABS_HI); SDValue Lo = getTargetNode(Op, DAG, MipsII::MO_ABS_LO); @@ -106,7 +111,7 @@ static SDValue getAddrNonPIC(SDValue Op, SelectionDAG &DAG) { SDValue MipsTargetLowering::getAddrLocal(SDValue Op, SelectionDAG &DAG, bool HasMips64) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getValueType(); unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT; SDValue GOT = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty), @@ -121,7 +126,7 @@ SDValue MipsTargetLowering::getAddrLocal(SDValue Op, SelectionDAG &DAG, SDValue MipsTargetLowering::getAddrGlobal(SDValue Op, SelectionDAG &DAG, unsigned Flag) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getValueType(); SDValue Tgt = DAG.getNode(MipsISD::Wrapper, DL, Ty, getGlobalReg(DAG, Ty), getTargetNode(Op, DAG, Flag)); @@ -132,7 +137,7 @@ SDValue MipsTargetLowering::getAddrGlobal(SDValue Op, SelectionDAG &DAG, SDValue MipsTargetLowering::getAddrGlobalLargeGOT(SDValue Op, SelectionDAG &DAG, unsigned HiFlag, unsigned LoFlag) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getValueType(); SDValue Hi = DAG.getNode(MipsISD::Hi, DL, Ty, getTargetNode(Op, DAG, HiFlag)); Hi = DAG.getNode(ISD::ADD, DL, Ty, Hi, getGlobalReg(DAG, Ty)); @@ -156,7 +161,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const { case MipsISD::FPCmp: return "MipsISD::FPCmp"; case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T"; case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F"; - case MipsISD::FPRound: return "MipsISD::FPRound"; + case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP"; case MipsISD::ExtractLOHI: return "MipsISD::ExtractLOHI"; case MipsISD::InsertLOHI: return "MipsISD::InsertLOHI"; case MipsISD::Mult: return "MipsISD::Mult"; @@ -250,6 +255,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::VASTART, MVT::Other, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); if (!TM.Options.NoNaNsFPMath) { setOperationAction(ISD::FABS, MVT::f32, Custom); @@ -265,6 +271,7 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::SELECT, MVT::i64, Custom); setOperationAction(ISD::LOAD, MVT::i64, Custom); setOperationAction(ISD::STORE, MVT::i64, Custom); + setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); } if (!HasMips64) { @@ -407,7 +414,7 @@ const MipsTargetLowering *MipsTargetLowering::create(MipsTargetMachine &TM) { return llvm::createMipsSETargetLowering(TM); } -EVT MipsTargetLowering::getSetCCResultType(EVT VT) const { +EVT MipsTargetLowering::getSetCCResultType(LLVMContext &, EVT VT) const { if (!VT.isVector()) return MVT::i32; return VT.changeVectorElementTypeToInteger(); @@ -424,7 +431,7 @@ static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG, unsigned HI = (Ty == MVT::i32) ? Mips::HI : Mips::HI64; unsigned Opc = N->getOpcode() == ISD::SDIVREM ? MipsISD::DivRem16 : MipsISD::DivRemU16; - DebugLoc DL = N->getDebugLoc(); + SDLoc DL(N); SDValue DivRem = DAG.getNode(Opc, DL, MVT::Glue, N->getOperand(0), N->getOperand(1)); @@ -502,7 +509,7 @@ static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op) { return Op; SDValue RHS = Op.getOperand(1); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); // Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of // node if necessary. @@ -514,7 +521,7 @@ static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op) { // Creates and returns a CMovFPT/F node. static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True, - SDValue False, DebugLoc DL) { + SDValue False, SDLoc DL) { ConstantSDNode *CC = cast<ConstantSDNode>(Cond.getOperand(2)); bool invert = invertFPCondCodeUser((Mips::CondCode)CC->getSExtValue()); @@ -545,7 +552,7 @@ static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, if (!CN || CN->getZExtValue()) return SDValue(); - const DebugLoc DL = N->getDebugLoc(); + const SDLoc DL(N); ISD::CondCode CC = cast<CondCodeSDNode>(SetCC.getOperand(2))->get(); SDValue True = N->getOperand(1); @@ -590,7 +597,7 @@ static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits()) return SDValue(); - return DAG.getNode(MipsISD::Ext, N->getDebugLoc(), ValTy, + return DAG.getNode(MipsISD::Ext, SDLoc(N), ValTy, ShiftRight.getOperand(0), DAG.getConstant(Pos, MVT::i32), DAG.getConstant(SMSize, MVT::i32)); } @@ -644,7 +651,7 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG, if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits())) return SDValue(); - return DAG.getNode(MipsISD::Ins, N->getDebugLoc(), ValTy, Shl.getOperand(0), + return DAG.getNode(MipsISD::Ins, SDLoc(N), ValTy, Shl.getOperand(0), DAG.getConstant(SMPos0, MVT::i32), DAG.getConstant(SMSize0, MVT::i32), And0.getOperand(0)); } @@ -669,7 +676,7 @@ static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); EVT ValTy = N->getValueType(0); - DebugLoc DL = N->getDebugLoc(); + SDLoc DL(N); SDValue Add1 = DAG.getNode(ISD::ADD, DL, ValTy, N->getOperand(0), Add.getOperand(0)); @@ -744,6 +751,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const case ISD::LOAD: return lowerLOAD(Op, DAG); case ISD::STORE: return lowerSTORE(Op, DAG); case ISD::ADD: return lowerADD(Op, DAG); + case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG); } return SDValue(); } @@ -763,6 +771,26 @@ addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC) return VReg; } +static MachineBasicBlock *expandPseudoDIV(MachineInstr *MI, + MachineBasicBlock &MBB, + const TargetInstrInfo &TII, + bool Is64Bit) { + if (NoZeroDivCheck) + return &MBB; + + // Insert instruction "teq $divisor_reg, $zero, 7". + MachineBasicBlock::iterator I(MI); + MachineInstrBuilder MIB; + MIB = BuildMI(MBB, llvm::next(I), MI->getDebugLoc(), TII.get(Mips::TEQ)) + .addOperand(MI->getOperand(2)).addReg(Mips::ZERO).addImm(7); + + // Use the 32-bit sub-register if this is a 64-bit division. + if (Is64Bit) + MIB->getOperand(0).setSubReg(Mips::sub_32); + + return &MBB; +} + MachineBasicBlock * MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { @@ -872,6 +900,12 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, case Mips::ATOMIC_CMP_SWAP_I64: case Mips::ATOMIC_CMP_SWAP_I64_P8: return emitAtomicCmpSwap(MI, BB, 8); + case Mips::PseudoSDIV: + case Mips::PseudoUDIV: + return expandPseudoDIV(MI, *BB, *getTargetMachine().getInstrInfo(), false); + case Mips::PseudoDSDIV: + case Mips::PseudoDUDIV: + return expandPseudoDIV(MI, *BB, *getTargetMachine().getInstrInfo(), true); } } @@ -1039,7 +1073,14 @@ MipsTargetLowering::emitAtomicBinaryPartword(MachineInstr *MI, BuildMI(BB, DL, TII->get(Mips::AND), AlignedAddr) .addReg(Ptr).addReg(MaskLSB2); BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2).addReg(Ptr).addImm(3); - BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3); + if (Subtarget->isLittle()) { + BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3); + } else { + unsigned Off = RegInfo.createVirtualRegister(RC); + BuildMI(BB, DL, TII->get(Mips::XORi), Off) + .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2); + BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3); + } BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper) .addReg(Mips::ZERO).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), Mask) @@ -1282,7 +1323,14 @@ MipsTargetLowering::emitAtomicCmpSwapPartword(MachineInstr *MI, BuildMI(BB, DL, TII->get(Mips::AND), AlignedAddr) .addReg(Ptr).addReg(MaskLSB2); BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2).addReg(Ptr).addImm(3); - BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3); + if (Subtarget->isLittle()) { + BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3); + } else { + unsigned Off = RegInfo.createVirtualRegister(RC); + BuildMI(BB, DL, TII->get(Mips::XORi), Off) + .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2); + BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3); + } BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper) .addReg(Mips::ZERO).addImm(MaskImm); BuildMI(BB, DL, TII->get(Mips::SLLV), Mask) @@ -1349,7 +1397,7 @@ SDValue MipsTargetLowering::lowerBR_JT(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); SDValue Table = Op.getOperand(1); SDValue Index = Op.getOperand(2); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT PTy = getPointerTy(); unsigned EntrySize = DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(*getDataLayout()); @@ -1382,7 +1430,7 @@ lowerBRCOND(SDValue Op, SelectionDAG &DAG) const // the block to branch to if the condition is true. SDValue Chain = Op.getOperand(0); SDValue Dest = Op.getOperand(2); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue CondRes = createFPCmp(DAG, Op.getOperand(1)); @@ -1409,15 +1457,16 @@ lowerSELECT(SDValue Op, SelectionDAG &DAG) const return Op; return createCMovFP(DAG, Cond, Op.getOperand(1), Op.getOperand(2), - Op.getDebugLoc()); + SDLoc(Op)); } SDValue MipsTargetLowering:: lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = Op.getOperand(0).getValueType(); - SDValue Cond = DAG.getNode(ISD::SETCC, DL, getSetCCResultType(Ty), + SDValue Cond = DAG.getNode(ISD::SETCC, DL, + getSetCCResultType(*DAG.getContext(), Ty), Op.getOperand(0), Op.getOperand(1), Op.getOperand(4)); @@ -1434,13 +1483,13 @@ SDValue MipsTargetLowering::lowerSETCC(SDValue Op, SelectionDAG &DAG) const { SDValue True = DAG.getConstant(1, MVT::i32); SDValue False = DAG.getConstant(0, MVT::i32); - return createCMovFP(DAG, Cond, True, False, Op.getDebugLoc()); + return createCMovFP(DAG, Cond, True, False, SDLoc(Op)); } SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { // FIXME there isn't actually debug info here - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) { @@ -1488,7 +1537,7 @@ lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const // Local Exec TLS Model. GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op); - DebugLoc DL = GA->getDebugLoc(); + SDLoc DL(GA); const GlobalValue *GV = GA->getGlobal(); EVT PtrVT = getPointerTy(); @@ -1593,7 +1642,7 @@ SDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const { MachineFunction &MF = DAG.getMachineFunction(); MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>(); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), getPointerTy()); @@ -1609,7 +1658,7 @@ static SDValue lowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG, bool HasR2) { EVT TyY = Op.getOperand(1).getValueType(); SDValue Const1 = DAG.getConstant(1, MVT::i32); SDValue Const31 = DAG.getConstant(31, MVT::i32); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue Res; // If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it @@ -1654,7 +1703,7 @@ static SDValue lowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG, bool HasR2) { unsigned WidthY = Op.getOperand(1).getValueSizeInBits(); EVT TyX = MVT::getIntegerVT(WidthX), TyY = MVT::getIntegerVT(WidthY); SDValue Const1 = DAG.getConstant(1, MVT::i32); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); // Bitcast to integer nodes. SDValue X = DAG.getNode(ISD::BITCAST, DL, TyX, Op.getOperand(0)); @@ -1707,7 +1756,7 @@ MipsTargetLowering::lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const { static SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG, bool HasR2) { SDValue Res, Const1 = DAG.getConstant(1, MVT::i32); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); // If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it // to i32. @@ -1736,7 +1785,7 @@ static SDValue lowerFABS32(SDValue Op, SelectionDAG &DAG, bool HasR2) { static SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG, bool HasR2) { SDValue Res, Const1 = DAG.getConstant(1, MVT::i32); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); // Bitcast to integer node. SDValue X = DAG.getNode(ISD::BITCAST, DL, MVT::i64, Op.getOperand(0)); @@ -1771,7 +1820,7 @@ lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); MFI->setFrameAddressIsTaken(true); EVT VT = Op.getValueType(); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, IsN64 ? Mips::FP_64 : Mips::FP, VT); return FrameAddr; @@ -1791,7 +1840,7 @@ SDValue MipsTargetLowering::lowerRETURNADDR(SDValue Op, // Return RA, which contains the return address. Mark it an implicit live-in. unsigned Reg = MF.addLiveIn(RA, getRegClassFor(VT)); - return DAG.getCopyFromReg(DAG.getEntryNode(), Op.getDebugLoc(), Reg, VT); + return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Reg, VT); } // An EH_RETURN is the result of lowering llvm.eh.return which in turn is @@ -1807,7 +1856,7 @@ SDValue MipsTargetLowering::lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) SDValue Chain = Op.getOperand(0); SDValue Offset = Op.getOperand(1); SDValue Handler = Op.getOperand(2); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); EVT Ty = IsN64 ? MVT::i64 : MVT::i32; // Store stack offset in V1, store jump target in V0. Glue CopyToReg and @@ -1827,14 +1876,14 @@ SDValue MipsTargetLowering::lowerATOMIC_FENCE(SDValue Op, // FIXME: Need pseudo-fence for 'singlethread' fences // FIXME: Set SType for weaker fences where supported/appropriate. unsigned SType = 0; - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); return DAG.getNode(MipsISD::Sync, DL, MVT::Other, Op.getOperand(0), DAG.getConstant(SType, MVT::i32)); } SDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1); SDValue Shamt = Op.getOperand(2); @@ -1865,7 +1914,7 @@ SDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op, SDValue MipsTargetLowering::lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1); SDValue Shamt = Op.getOperand(2); @@ -1909,7 +1958,7 @@ static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD, SDValue Ptr = LD->getBasePtr(); EVT VT = LD->getValueType(0), MemVT = LD->getMemoryVT(); EVT BasePtrVT = Ptr.getValueType(); - DebugLoc DL = LD->getDebugLoc(); + SDLoc DL(LD); SDVTList VTList = DAG.getVTList(VT, MVT::Other); if (Offset) @@ -1975,7 +2024,7 @@ SDValue MipsTargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const { // (set tmp1, (lwr baseptr, tmp0)) // (set tmp2, (shl tmp1, 32)) // (set dst, (srl tmp2, 32)) - DebugLoc DL = LD->getDebugLoc(); + SDLoc DL(LD); SDValue Const32 = DAG.getConstant(32, MVT::i32); SDValue SLL = DAG.getNode(ISD::SHL, DL, MVT::i64, LWR, Const32); SDValue SRL = DAG.getNode(ISD::SRL, DL, MVT::i64, SLL, Const32); @@ -1987,7 +2036,7 @@ static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD, SDValue Chain, unsigned Offset) { SDValue Ptr = SD->getBasePtr(), Value = SD->getValue(); EVT MemVT = SD->getMemoryVT(), BasePtrVT = Ptr.getValueType(); - DebugLoc DL = SD->getDebugLoc(); + SDLoc DL(SD); SDVTList VTList = DAG.getVTList(MVT::Other); if (Offset) @@ -2000,16 +2049,8 @@ static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD, } // Expand an unaligned 32 or 64-bit integer store node. -SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { - StoreSDNode *SD = cast<StoreSDNode>(Op); - EVT MemVT = SD->getMemoryVT(); - - // Return if store is aligned or if MemVT is neither i32 nor i64. - if ((SD->getAlignment() >= MemVT.getSizeInBits() / 8) || - ((MemVT != MVT::i32) && (MemVT != MVT::i64))) - return SDValue(); - - bool IsLittle = Subtarget->isLittle(); +static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG, + bool IsLittle) { SDValue Value = SD->getValue(), Chain = SD->getChain(); EVT VT = Value.getValueType(); @@ -2036,6 +2077,34 @@ SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { return createStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7); } +// Lower (store (fp_to_sint $fp) $ptr) to (store (TruncIntFP $fp), $ptr). +static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG) { + SDValue Val = SD->getValue(); + + if (Val.getOpcode() != ISD::FP_TO_SINT) + return SDValue(); + + EVT FPTy = EVT::getFloatingPointVT(Val.getValueSizeInBits()); + SDValue Tr = DAG.getNode(MipsISD::TruncIntFP, SDLoc(Val), FPTy, + Val.getOperand(0)); + + return DAG.getStore(SD->getChain(), SDLoc(SD), Tr, SD->getBasePtr(), + SD->getPointerInfo(), SD->isVolatile(), + SD->isNonTemporal(), SD->getAlignment()); +} + +SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { + StoreSDNode *SD = cast<StoreSDNode>(Op); + EVT MemVT = SD->getMemoryVT(); + + // Lower unaligned integer stores. + if ((SD->getAlignment() < MemVT.getSizeInBits() / 8) && + ((MemVT == MVT::i32) || (MemVT == MVT::i64))) + return lowerUnalignedIntStore(SD, DAG, Subtarget->isLittle()); + + return lowerFP_TO_SINT_STORE(SD, DAG); +} + SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const { if (Op->getOperand(0).getOpcode() != ISD::FRAMEADDR || cast<ConstantSDNode> @@ -2053,10 +2122,18 @@ SDValue MipsTargetLowering::lowerADD(SDValue Op, SelectionDAG &DAG) const { EVT ValTy = Op->getValueType(0); int FI = MFI->CreateFixedObject(Op.getValueSizeInBits() / 8, 0, false); SDValue InArgsAddr = DAG.getFrameIndex(FI, ValTy); - return DAG.getNode(ISD::ADD, Op->getDebugLoc(), ValTy, InArgsAddr, + return DAG.getNode(ISD::ADD, SDLoc(Op), ValTy, InArgsAddr, DAG.getConstant(0, ValTy)); } +SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op, + SelectionDAG &DAG) const { + EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits()); + SDValue Trunc = DAG.getNode(MipsISD::TruncIntFP, SDLoc(Op), FPTy, + Op.getOperand(0)); + return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// @@ -2175,7 +2252,7 @@ static unsigned getNextIntArgReg(unsigned Reg) { SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset, - SDValue Chain, SDValue Arg, DebugLoc DL, + SDValue Chain, SDValue Arg, SDLoc DL, bool IsTailCall, SelectionDAG &DAG) const { if (!IsTailCall) { SDValue PtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(), StackPtr, @@ -2229,6 +2306,15 @@ getOpndList(SmallVectorImpl<SDValue> &Ops, const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); const uint32_t *Mask = TRI->getCallPreservedMask(CLI.CallConv); assert(Mask && "Missing call preserved mask for calling convention"); + if (Subtarget->inMips16HardFloat()) { + if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(CLI.Callee)) { + llvm::StringRef Sym = G->getGlobal()->getName(); + Function *F = G->getGlobal()->getParent()->getFunction(Sym); + if (F->hasFnAttribute("__Mips16RetHelper")) { + Mask = MipsRegisterInfo::getMips16RetHelperMask(); + } + } + } Ops.push_back(CLI.DAG.getRegisterMask(Mask)); if (InFlag.getNode()) @@ -2241,7 +2327,7 @@ SDValue MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl<SDValue> &InVals) const { SelectionDAG &DAG = CLI.DAG; - DebugLoc &DL = CLI.DL; + SDLoc DL = CLI.DL; SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs; SmallVector<SDValue, 32> &OutVals = CLI.OutVals; SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; @@ -2260,7 +2346,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVector<CCValAssign, 16> ArgLocs; CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), getTargetMachine(), ArgLocs, *DAG.getContext()); - MipsCC MipsCCInfo(CallConv, IsO32, CCInfo); + MipsCC::SpecialCallingConvType SpecialCallingConv = + getSpecialCallingConv(Callee); + MipsCC MipsCCInfo(CallConv, IsO32, CCInfo, SpecialCallingConv); MipsCCInfo.analyzeCallOperands(Outs, IsVarArg, getTargetMachine().Options.UseSoftFloat, @@ -2286,7 +2374,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SDValue NextStackOffsetVal = DAG.getIntPtrConstant(NextStackOffset, true); if (!IsTailCall) - Chain = DAG.getCALLSEQ_START(Chain, NextStackOffsetVal); + Chain = DAG.getCALLSEQ_START(Chain, NextStackOffsetVal, DL); SDValue StackPtr = DAG.getCopyFromReg(Chain, DL, IsN64 ? Mips::SP_64 : Mips::SP, @@ -2424,7 +2512,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // Create the CALLSEQ_END node. Chain = DAG.getCALLSEQ_END(Chain, NextStackOffsetVal, - DAG.getIntPtrConstant(0, true), InFlag); + DAG.getIntPtrConstant(0, true), InFlag, DL); InFlag = Chain.getValue(1); // Handle result values, copying them out of physregs into vregs that we @@ -2439,7 +2527,7 @@ SDValue MipsTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc DL, SelectionDAG &DAG, + SDLoc DL, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, const SDNode *CallNode, const Type *RetTy) const { @@ -2478,7 +2566,7 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc DL, SelectionDAG &DAG, + SDLoc DL, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { MachineFunction &MF = DAG.getMachineFunction(); @@ -2644,7 +2732,7 @@ MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, - DebugLoc DL, SelectionDAG &DAG) const { + SDLoc DL, SelectionDAG &DAG) const { // CCValAssign - represent the assignment of // the return value to a location SmallVector<CCValAssign, 16> RVLocs; @@ -3029,13 +3117,32 @@ static bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode) { return (ES && Ty->isIntegerTy(128) && isF128SoftLibCall(ES->getSymbol())); } -MipsTargetLowering::MipsCC::MipsCC(CallingConv::ID CC, bool IsO32_, - CCState &Info) - : CCInfo(Info), CallConv(CC), IsO32(IsO32_) { +MipsTargetLowering::MipsCC::SpecialCallingConvType + MipsTargetLowering::getSpecialCallingConv(SDValue Callee) const { + MipsCC::SpecialCallingConvType SpecialCallingConv = + MipsCC::NoSpecialCallingConv;; + if (Subtarget->inMips16HardFloat()) { + if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { + llvm::StringRef Sym = G->getGlobal()->getName(); + Function *F = G->getGlobal()->getParent()->getFunction(Sym); + if (F->hasFnAttribute("__Mips16RetHelper")) { + SpecialCallingConv = MipsCC::Mips16RetHelperConv; + } + } + } + return SpecialCallingConv; +} + +MipsTargetLowering::MipsCC::MipsCC( + CallingConv::ID CC, bool IsO32_, CCState &Info, + MipsCC::SpecialCallingConvType SpecialCallingConv_) + : CCInfo(Info), CallConv(CC), IsO32(IsO32_), + SpecialCallingConv(SpecialCallingConv_){ // Pre-allocate reserved argument area. CCInfo.AllocateStack(reservedArgArea(), 1); } + void MipsTargetLowering::MipsCC:: analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Args, bool IsVarArg, bool IsSoftFloat, const SDNode *CallNode, @@ -3183,6 +3290,8 @@ llvm::CCAssignFn *MipsTargetLowering::MipsCC::fixedArgFn() const { if (CallConv == CallingConv::Fast) return CC_Mips_FastCC; + if (SpecialCallingConv == Mips16RetHelperConv) + return CC_Mips16RetHelper; return IsO32 ? CC_MipsO32 : CC_MipsN; } @@ -3233,7 +3342,7 @@ MVT MipsTargetLowering::MipsCC::getRegVT(MVT VT, const Type *OrigTy, } void MipsTargetLowering:: -copyByValRegs(SDValue Chain, DebugLoc DL, std::vector<SDValue> &OutChains, +copyByValRegs(SDValue Chain, SDLoc DL, std::vector<SDValue> &OutChains, SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags, SmallVectorImpl<SDValue> &InVals, const Argument *FuncArg, const MipsCC &CC, const ByValArgInfo &ByVal) const { @@ -3277,7 +3386,7 @@ copyByValRegs(SDValue Chain, DebugLoc DL, std::vector<SDValue> &OutChains, // Copy byVal arg to registers and stack. void MipsTargetLowering:: -passByValArg(SDValue Chain, DebugLoc DL, +passByValArg(SDValue Chain, SDLoc DL, std::deque< std::pair<unsigned, SDValue> > &RegsToPass, SmallVector<SDValue, 8> &MemOpChains, SDValue StackPtr, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, @@ -3375,7 +3484,7 @@ passByValArg(SDValue Chain, DebugLoc DL, void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains, const MipsCC &CC, SDValue Chain, - DebugLoc DL, SelectionDAG &DAG) const { + SDLoc DL, SelectionDAG &DAG) const { unsigned NumRegs = CC.numIntArgRegs(); const uint16_t *ArgRegs = CC.intArgRegs(); const CCState &CCInfo = CC.getCCInfo(); diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 5587e8f..fe043ae 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -60,8 +60,8 @@ namespace llvm { CMovFP_T, CMovFP_F, - // Floating Point Rounding - FPRound, + // FP-to-int truncation node. + TruncIntFP, // Return Ret, @@ -195,7 +195,7 @@ namespace llvm { virtual const char *getTargetNodeName(unsigned Opcode) const; /// getSetCCResultType - get the ISD::SETCC result ValueType - EVT getSetCCResultType(EVT VT) const; + EVT getSetCCResultType(LLVMContext &Context, EVT VT) const; virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; @@ -240,7 +240,14 @@ namespace llvm { /// arguments and inquire about calling convention information. class MipsCC { public: - MipsCC(CallingConv::ID CallConv, bool IsO32, CCState &Info); + enum SpecialCallingConvType { + Mips16RetHelperConv, NoSpecialCallingConv + }; + + MipsCC( + CallingConv::ID CallConv, bool IsO32, CCState &Info, + SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv); + void analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs, bool IsVarArg, bool IsSoftFloat, @@ -313,20 +320,23 @@ namespace llvm { CCState &CCInfo; CallingConv::ID CallConv; bool IsO32; + SpecialCallingConvType SpecialCallingConv; SmallVector<ByValArgInfo, 2> ByValArgs; }; - + protected: // Subtarget Info const MipsSubtarget *Subtarget; bool HasMips64, IsN64, IsO32; private: + + MipsCC::SpecialCallingConvType getSpecialCallingConv(SDValue Callee) const; // Lower Operand helpers SDValue LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, const SDNode *CallNode, const Type *RetTy) const; @@ -354,6 +364,7 @@ namespace llvm { SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const; SDValue lowerADD(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const; /// isEligibleForTailCallOptimization - Check whether the call is eligible /// for tail call optimization. @@ -365,7 +376,7 @@ namespace llvm { /// copyByValArg - Copy argument registers which were used to pass a byval /// argument to the stack. Create a stack frame object for the byval /// argument. - void copyByValRegs(SDValue Chain, DebugLoc DL, + void copyByValRegs(SDValue Chain, SDLoc DL, std::vector<SDValue> &OutChains, SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags, SmallVectorImpl<SDValue> &InVals, @@ -373,7 +384,7 @@ namespace llvm { const MipsCC &CC, const ByValArgInfo &ByVal) const; /// passByValArg - Pass a byval argument in registers or on stack. - void passByValArg(SDValue Chain, DebugLoc DL, + void passByValArg(SDValue Chain, SDLoc DL, std::deque< std::pair<unsigned, SDValue> > &RegsToPass, SmallVector<SDValue, 8> &MemOpChains, SDValue StackPtr, MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, @@ -384,17 +395,17 @@ namespace llvm { /// to the stack. Also create a stack frame object for the first variable /// argument. void writeVarArgRegs(std::vector<SDValue> &OutChains, const MipsCC &CC, - SDValue Chain, DebugLoc DL, SelectionDAG &DAG) const; + SDValue Chain, SDLoc DL, SelectionDAG &DAG) const; virtual SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, - DebugLoc dl, SelectionDAG &DAG, + SDLoc dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain, - SDValue Arg, DebugLoc DL, bool IsTailCall, + SDValue Arg, SDLoc DL, bool IsTailCall, SelectionDAG &DAG) const; virtual SDValue @@ -412,7 +423,7 @@ namespace llvm { CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, const SmallVectorImpl<SDValue> &OutVals, - DebugLoc dl, SelectionDAG &DAG) const; + SDLoc dl, SelectionDAG &DAG) const; // Inline asm support ConstraintType getConstraintType(const std::string &Constraint) const; diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index 6b23057..e2acf28 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -30,6 +30,7 @@ def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<1>, SDTCisVT<2, i32>]>; def SDT_MipsCMovFP : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; +def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>; def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; @@ -42,6 +43,7 @@ def MipsCMovFP_T : SDNode<"MipsISD::CMovFP_T", SDT_MipsCMovFP, [SDNPInGlue]>; def MipsCMovFP_F : SDNode<"MipsISD::CMovFP_F", SDT_MipsCMovFP, [SDNPInGlue]>; def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, [SDNPHasChain, SDNPOptInGlue]>; +def MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>; def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>; def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64", SDT_MipsExtractElementF64>; @@ -154,6 +156,7 @@ class LW_FT<string opstr, RegisterClass RC, InstrItinClass Itin, InstSE<(outs RC:$rt), (ins MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI> { let DecoderMethod = "DecodeFMem"; + let mayLoad = 1; } class SW_FT<string opstr, RegisterClass RC, InstrItinClass Itin, @@ -161,6 +164,7 @@ class SW_FT<string opstr, RegisterClass RC, InstrItinClass Itin, InstSE<(outs), (ins RC:$rt, MemOpnd:$addr), !strconcat(opstr, "\t$rt, $addr"), [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI> { let DecoderMethod = "DecodeFMem"; + let mayStore = 1; } class MADDS_FT<string opstr, RegisterClass RC, InstrItinClass Itin, @@ -251,11 +255,19 @@ let Predicates = [NotFP64bit, HasStdEnc] in { } let Predicates = [IsFP64bit, HasStdEnc], DecoderNamespace = "Mips64" in { - def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 17>; - def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 21>; - def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 20>; - def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 16>; - def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64, FGR64, IIFcvt>, ABSS_FM<0x21, 21>; + def CVT_S_D64 : ABSS_FT<"cvt.s.d", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 17>; + def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32, FGR64, IIFcvt>, ABSS_FM<0x20, 21>; + def CVT_D64_W : ABSS_FT<"cvt.d.w", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 20>; + def CVT_D64_S : ABSS_FT<"cvt.d.s", FGR64, FGR32, IIFcvt>, ABSS_FM<0x21, 16>; + def CVT_D64_L : ABSS_FT<"cvt.d.l", FGR64, FGR64, IIFcvt>, ABSS_FM<0x21, 21>; +} + +let isPseudo = 1, isCodeGenOnly = 1 in { + def PseudoCVT_S_W : ABSS_FT<"", FGR32, CPURegs, IIFcvt>; + def PseudoCVT_D32_W : ABSS_FT<"", AFGR64, CPURegs, IIFcvt>; + def PseudoCVT_S_L : ABSS_FT<"", FGR64, CPU64Regs, IIFcvt>; + def PseudoCVT_D64_W : ABSS_FT<"", FGR64, CPURegs, IIFcvt>; + def PseudoCVT_D64_L : ABSS_FT<"", FGR64, CPU64Regs, IIFcvt>; } let Predicates = [NoNaNsFPMath, HasStdEnc] in { @@ -314,8 +326,12 @@ let Predicates = [NotN64, HasMips64, HasStdEnc], } let Predicates = [NotN64, NotMips64, HasStdEnc] in { - def LDC1 : LW_FT<"ldc1", AFGR64, IILoad, mem, load>, LW_FM<0x35>; - def SDC1 : SW_FT<"sdc1", AFGR64, IIStore, mem, store>, LW_FM<0x3d>; + let isPseudo = 1, isCodeGenOnly = 1 in { + def PseudoLDC1 : LW_FT<"", AFGR64, IILoad, mem, load>; + def PseudoSDC1 : SW_FT<"", AFGR64, IIStore, mem, store>; + } + def LDC1 : LW_FT<"ldc1", AFGR64, IILoad, mem>, LW_FM<0x35>; + def SDC1 : SW_FT<"sdc1", AFGR64, IIStore, mem>, LW_FM<0x3d>; } // Indexed loads and stores. @@ -470,14 +486,13 @@ def ExtractElementF64 : def : MipsPat<(f32 fpimm0), (MTC1 ZERO)>; def : MipsPat<(f32 fpimm0neg), (FNEG_S (MTC1 ZERO))>; -def : MipsPat<(f32 (sint_to_fp CPURegs:$src)), (CVT_S_W (MTC1 CPURegs:$src))>; -def : MipsPat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (TRUNC_W_S FGR32:$src))>; +def : MipsPat<(f32 (sint_to_fp CPURegs:$src)), (PseudoCVT_S_W CPURegs:$src)>; +def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_W_S FGR32:$src)>; let Predicates = [NotFP64bit, HasStdEnc] in { def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), - (CVT_D32_W (MTC1 CPURegs:$src))>; - def : MipsPat<(i32 (fp_to_sint AFGR64:$src)), - (MFC1 (TRUNC_W_D32 AFGR64:$src))>; + (PseudoCVT_D32_W CPURegs:$src)>; + def : MipsPat<(MipsTruncIntFP AFGR64:$src), (TRUNC_W_D32 AFGR64:$src)>; def : MipsPat<(f32 (fround AFGR64:$src)), (CVT_S_D32 AFGR64:$src)>; def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D32_S FGR32:$src)>; } @@ -487,17 +502,15 @@ let Predicates = [IsFP64bit, HasStdEnc] in { def : MipsPat<(f64 fpimm0neg), (FNEG_D64 (DMTC1 ZERO_64))>; def : MipsPat<(f64 (sint_to_fp CPURegs:$src)), - (CVT_D64_W (MTC1 CPURegs:$src))>; + (PseudoCVT_D64_W CPURegs:$src)>; def : MipsPat<(f32 (sint_to_fp CPU64Regs:$src)), - (CVT_S_L (DMTC1 CPU64Regs:$src))>; + (EXTRACT_SUBREG (PseudoCVT_S_L CPU64Regs:$src), sub_32)>; def : MipsPat<(f64 (sint_to_fp CPU64Regs:$src)), - (CVT_D64_L (DMTC1 CPU64Regs:$src))>; + (PseudoCVT_D64_L CPU64Regs:$src)>; - def : MipsPat<(i32 (fp_to_sint FGR64:$src)), - (MFC1 (TRUNC_W_D64 FGR64:$src))>; - def : MipsPat<(i64 (fp_to_sint FGR32:$src)), (DMFC1 (TRUNC_L_S FGR32:$src))>; - def : MipsPat<(i64 (fp_to_sint FGR64:$src)), - (DMFC1 (TRUNC_L_D64 FGR64:$src))>; + def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_W_D64 FGR64:$src)>; + def : MipsPat<(MipsTruncIntFP FGR32:$src), (TRUNC_L_S FGR32:$src)>; + def : MipsPat<(MipsTruncIntFP FGR64:$src), (TRUNC_L_D64 FGR64:$src)>; def : MipsPat<(f32 (fround FGR64:$src)), (CVT_S_D64 FGR64:$src)>; def : MipsPat<(f64 (fextend FGR32:$src)), (CVT_D64_S FGR32:$src)>; @@ -523,7 +536,7 @@ let AddedComplexity = 40 in { } let Predicates = [NotN64, NotMips64, HasStdEnc] in { - def : LoadRegImmPat<LDC1, f64, load>; - def : StoreRegImmPat<SDC1, f64>; + def : LoadRegImmPat<PseudoLDC1, f64, load>; + def : StoreRegImmPat<PseudoSDC1, f64>; } } diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index ea07372..14cfcf9 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -476,6 +476,20 @@ class RDHWR_FM { let Inst{5-0} = 0x3b; } +class TEQ_FM<bits<6> funct> { + bits<5> rs; + bits<5> rt; + bits<10> code_; + + bits<32> Inst; + + let Inst{31-26} = 0; + let Inst{25-21} = rs; + let Inst{20-16} = rt; + let Inst{15-6} = code_; + let Inst{5-0} = funct; +} + //===----------------------------------------------------------------------===// // // FLOATING POINT INSTRUCTION FORMATS diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index ad92d41..3144dae 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -77,7 +77,7 @@ MipsInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc, MachineBasicBlock *&BB, SmallVectorImpl<MachineOperand> &Cond) const { - assert(GetAnalyzableBrOpc(Opc) && "Not an analyzable branch"); + assert(getAnalyzableBrOpc(Opc) && "Not an analyzable branch"); int NumOp = Inst->getNumExplicitOperands(); // for both int and fp branches, the last explicit operand is the @@ -167,7 +167,7 @@ RemoveBranch(MachineBasicBlock &MBB) const // Up to 2 branches are removed. // Note that indirect branches are not removed. for(removed = 0; I != REnd && removed < 2; ++I, ++removed) - if (!GetAnalyzableBrOpc(I->getOpcode())) + if (!getAnalyzableBrOpc(I->getOpcode())) break; MBB.erase(I.base(), FirstBr.base()); @@ -182,7 +182,7 @@ ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { assert( (Cond.size() && Cond.size() <= 3) && "Invalid Mips branch condition!"); - Cond[0].setImm(GetOppositeBranchOpc(Cond[0].getImm())); + Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm())); return false; } @@ -210,7 +210,7 @@ AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, BranchInstrs.push_back(LastInst); // Not an analyzable branch (e.g., indirect jump). - if (!GetAnalyzableBrOpc(LastOpc)) + if (!getAnalyzableBrOpc(LastOpc)) return LastInst->isIndirectBranch() ? BT_Indirect : BT_None; // Get the second to last instruction in the block. @@ -219,7 +219,7 @@ AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, if (++I != REnd) { SecondLastInst = &*I; - SecondLastOpc = GetAnalyzableBrOpc(SecondLastInst->getOpcode()); + SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode()); // Not an analyzable branch (must be an indirect jump). if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc) @@ -282,3 +282,16 @@ unsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { } } } + +MachineInstrBuilder +MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc, + MachineBasicBlock::iterator I) const { + MachineInstrBuilder MIB; + MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc)); + + for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) + MIB.addOperand(I->getOperand(J)); + + MIB.setMemRefs(I->memoperands_begin(), I->memoperands_end()); + return MIB; +} diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index 8c05d97..0f075ec 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -17,6 +17,7 @@ #include "Mips.h" #include "MipsAnalyzeImmediate.h" #include "MipsRegisterInfo.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetInstrInfo.h" @@ -81,7 +82,7 @@ public: /// virtual const MipsRegisterInfo &getRegisterInfo() const = 0; - virtual unsigned GetOppositeBranchOpc(unsigned Opc) const = 0; + virtual unsigned getOppositeBranchOpc(unsigned Opc) const = 0; /// Return the number of bytes of code the specified instruction may be. unsigned GetInstSizeInBytes(const MachineInstr *MI) const; @@ -116,6 +117,11 @@ public: const TargetRegisterInfo *TRI, int64_t Offset) const = 0; + /// Create an instruction which has the same operands and memory operands + /// as MI but has a new opcode. + MachineInstrBuilder genInstrWithNewOpc(unsigned NewOpc, + MachineBasicBlock::iterator I) const; + protected: bool isZeroImm(const MachineOperand &op) const; @@ -123,7 +129,7 @@ protected: unsigned Flag) const; private: - virtual unsigned GetAnalyzableBrOpc(unsigned Opc) const = 0; + virtual unsigned getAnalyzableBrOpc(unsigned Opc) const = 0; void AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc, MachineBasicBlock *&BB, diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 86ec729..dc3e4be 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -26,7 +26,8 @@ def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; def SDT_ExtractLOHI : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVT<1, untyped>, SDTCisVT<2, i32>]>; def SDT_InsertLOHI : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, - SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; + SDTCisVT<1, i32>, + SDTCisSameAs<1, 2>]>; def SDT_MipsMultDiv : SDTypeProfile<1, 2, [SDTCisVT<0, untyped>, SDTCisInt<1>, SDTCisSameAs<1, 2>]>; def SDT_MipsMAddMSub : SDTypeProfile<1, 3, @@ -104,7 +105,8 @@ def MipsMSubu : SDNode<"MipsISD::MSubu", SDT_MipsMAddMSub>; // DivRem(u) nodes def MipsDivRem : SDNode<"MipsISD::DivRem", SDT_MipsMultDiv>; def MipsDivRemU : SDNode<"MipsISD::DivRemU", SDT_MipsMultDiv>; -def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16, [SDNPOutGlue]>; +def MipsDivRem16 : SDNode<"MipsISD::DivRem16", SDT_MipsDivRem16, + [SDNPOutGlue]>; def MipsDivRemU16 : SDNode<"MipsISD::DivRemU16", SDT_MipsDivRem16, [SDNPOutGlue]>; @@ -389,6 +391,7 @@ class ArithLogicI<string opstr, Operand Od, RegisterOperand RO, [(set RO:$rt, (OpNode RO:$rs, imm_type:$imm16))], IIAlu, FrmI, opstr> { let isReMaterializable = 1; + let TwoOperandAliasConstraint = "$rs = $rt"; } // Arithmetic Multiply ADD/SUB @@ -521,7 +524,7 @@ multiclass StoreLeftRightM<string opstr, SDNode OpNode, RegisterClass RC> { } // Conditional Branch -class CBranch<string opstr, PatFrag cond_op, RegisterClass RC> : +class CBranch<string opstr, PatFrag cond_op, RegisterOperand RC> : InstSE<(outs), (ins RC:$rs, RC:$rt, brtarget:$offset), !strconcat(opstr, "\t$rs, $rt, $offset"), [(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$offset)], IIBranch, @@ -532,7 +535,7 @@ class CBranch<string opstr, PatFrag cond_op, RegisterClass RC> : let Defs = [AT]; } -class CBranchZero<string opstr, PatFrag cond_op, RegisterClass RC> : +class CBranchZero<string opstr, PatFrag cond_op, RegisterOperand RC> : InstSE<(outs), (ins RC:$rs, brtarget:$offset), !strconcat(opstr, "\t$rs, $offset"), [(brcond (i32 (cond_op RC:$rs, 0)), bb:$offset)], IIBranch, FrmI> { @@ -637,6 +640,11 @@ class SYNC_FT : InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)], NoItinerary, FrmOther>; +let hasSideEffects = 1 in +class TEQ_FT<string opstr, RegisterOperand RO> : + InstSE<(outs), (ins RO:$rs, RO:$rt, uimm16:$code_), + !strconcat(opstr, "\t$rs, $rt, $code_"), [], NoItinerary, FrmI>; + // Mul, Div class Mult<string opstr, InstrItinClass itin, RegisterOperand RO, list<Register> DefRegs> : @@ -651,12 +659,14 @@ class Mult<string opstr, InstrItinClass itin, RegisterOperand RO, // operands. class MultDivPseudo<Instruction RealInst, RegisterClass R0, RegisterOperand R1, SDPatternOperator OpNode, InstrItinClass Itin, - bit IsComm = 1, bit HasSideEffects = 0> : + bit IsComm = 1, bit HasSideEffects = 0, + bit UsesCustomInserter = 0> : PseudoSE<(outs R0:$ac), (ins R1:$rs, R1:$rt), [(set R0:$ac, (OpNode R1:$rs, R1:$rt))], Itin>, PseudoInstExpansion<(RealInst R1:$rs, R1:$rt)> { let isCommutable = IsComm; let hasSideEffects = HasSideEffects; + let usesCustomInserter = UsesCustomInserter; } // Pseudo multiply add/sub instruction with explicit accumulator register @@ -923,6 +933,7 @@ defm SWL : StoreLeftRightM<"swl", MipsSWL, CPURegs>, LW_FM<0x2a>; defm SWR : StoreLeftRightM<"swr", MipsSWR, CPURegs>, LW_FM<0x2e>; def SYNC : SYNC_FT, SYNC_FM; +def TEQ : TEQ_FT<"teq", CPURegsOpnd>, TEQ_FM<0x34>; /// Load-linked, Store-conditional let Predicates = [NotN64, HasStdEnc] in { @@ -940,12 +951,12 @@ def J : JumpFJ<jmptarget, "j", br, bb>, FJ<2>, Requires<[RelocStatic, HasStdEnc]>, IsBranch; def JR : IndirectBranch<CPURegs>, MTLO_FM<8>; def B : UncondBranch<"b">, B_FM; -def BEQ : CBranch<"beq", seteq, CPURegs>, BEQ_FM<4>; -def BNE : CBranch<"bne", setne, CPURegs>, BEQ_FM<5>; -def BGEZ : CBranchZero<"bgez", setge, CPURegs>, BGEZ_FM<1, 1>; -def BGTZ : CBranchZero<"bgtz", setgt, CPURegs>, BGEZ_FM<7, 0>; -def BLEZ : CBranchZero<"blez", setle, CPURegs>, BGEZ_FM<6, 0>; -def BLTZ : CBranchZero<"bltz", setlt, CPURegs>, BGEZ_FM<1, 0>; +def BEQ : CBranch<"beq", seteq, CPURegsOpnd>, BEQ_FM<4>; +def BNE : CBranch<"bne", setne, CPURegsOpnd>, BEQ_FM<5>; +def BGEZ : CBranchZero<"bgez", setge, CPURegsOpnd>, BGEZ_FM<1, 1>; +def BGTZ : CBranchZero<"bgtz", setgt, CPURegsOpnd>, BGEZ_FM<7, 0>; +def BLEZ : CBranchZero<"blez", setle, CPURegsOpnd>, BGEZ_FM<6, 0>; +def BLTZ : CBranchZero<"bltz", setlt, CPURegsOpnd>, BGEZ_FM<1, 0>; def BAL_BR: BAL_FT, BAL_FM; @@ -989,9 +1000,10 @@ def PseudoMULT : MultDivPseudo<MULT, ACRegs, CPURegsOpnd, MipsMult, IIImul>; def PseudoMULTu : MultDivPseudo<MULTu, ACRegs, CPURegsOpnd, MipsMultu, IIImul>; def SDIV : Div<"div", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1a>; def UDIV : Div<"divu", IIIdiv, CPURegsOpnd, [HI, LO]>, MULT_FM<0, 0x1b>; -def PseudoSDIV : MultDivPseudo<SDIV, ACRegs, CPURegsOpnd, MipsDivRem, IIIdiv, 0>; +def PseudoSDIV : MultDivPseudo<SDIV, ACRegs, CPURegsOpnd, MipsDivRem, IIIdiv, + 0, 1, 1>; def PseudoUDIV : MultDivPseudo<UDIV, ACRegs, CPURegsOpnd, MipsDivRemU, IIIdiv, - 0>; + 0, 1, 1>; def MTHI : MoveToLOHI<"mthi", CPURegs, [HI]>, MTLO_FM<0x11>; def MTLO : MoveToLOHI<"mtlo", CPURegs, [LO]>, MTLO_FM<0x13>; @@ -1095,7 +1107,12 @@ def : InstAlias<"mfc2 $rt, $rd", (MFC2_3OP CPURegsOpnd:$rt, CPURegsOpnd:$rd, 0), 0>; def : InstAlias<"mtc2 $rt, $rd", (MTC2_3OP CPURegsOpnd:$rd, 0, CPURegsOpnd:$rt), 0>; - +def : InstAlias<"bnez $rs,$offset", + (BNE CPURegsOpnd:$rs, ZERO, brtarget:$offset), 1>, + Requires<[NotMips64]>; +def : InstAlias<"beqz $rs,$offset", + (BEQ CPURegsOpnd:$rs, ZERO, brtarget:$offset), 1>, + Requires<[NotMips64]>; //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions //===----------------------------------------------------------------------===// @@ -1248,6 +1265,10 @@ def : MipsPat<(brcond (i32 (setge RC:$lhs, immSExt16:$rhs)), bb:$dst), (BEQ (SLTiOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; def : MipsPat<(brcond (i32 (setuge RC:$lhs, immSExt16:$rhs)), bb:$dst), (BEQ (SLTiuOp RC:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>; +def : MipsPat<(brcond (i32 (setgt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), + (BEQ (SLTiOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>; +def : MipsPat<(brcond (i32 (setugt RC:$lhs, immSExt16Plus1:$rhs)), bb:$dst), + (BEQ (SLTiuOp RC:$lhs, (Plus1 imm:$rhs)), ZERO, bb:$dst)>; def : MipsPat<(brcond (i32 (setle RC:$lhs, RC:$rhs)), bb:$dst), (BEQ (SLTOp RC:$rhs, RC:$lhs), ZERO, bb:$dst)>; @@ -1260,9 +1281,18 @@ def : MipsPat<(brcond RC:$cond, bb:$dst), defm : BrcondPats<CPURegs, BEQ, BNE, SLT, SLTu, SLTi, SLTiu, ZERO>; +def : MipsPat<(brcond (i32 (setlt i32:$lhs, 1)), bb:$dst), + (BLEZ i32:$lhs, bb:$dst)>; +def : MipsPat<(brcond (i32 (setgt i32:$lhs, -1)), bb:$dst), + (BGEZ i32:$lhs, bb:$dst)>; + // setcc patterns multiclass SeteqPats<RegisterClass RC, Instruction SLTiuOp, Instruction XOROp, Instruction SLTuOp, Register ZEROReg> { + def : MipsPat<(seteq RC:$lhs, 0), + (SLTiuOp RC:$lhs, 1)>; + def : MipsPat<(setne RC:$lhs, 0), + (SLTuOp ZEROReg, RC:$lhs)>; def : MipsPat<(seteq RC:$lhs, RC:$rhs), (SLTiuOp (XOROp RC:$lhs, RC:$rhs), 1)>; def : MipsPat<(setne RC:$lhs, RC:$rhs), diff --git a/lib/Target/Mips/MipsLongBranch.cpp b/lib/Target/Mips/MipsLongBranch.cpp index bf5ad37..073daba 100644 --- a/lib/Target/Mips/MipsLongBranch.cpp +++ b/lib/Target/Mips/MipsLongBranch.cpp @@ -65,7 +65,6 @@ namespace { static char ID; MipsLongBranch(TargetMachine &tm) : MachineFunctionPass(ID), TM(tm), - TII(static_cast<const MipsInstrInfo*>(tm.getInstrInfo())), IsPIC(TM.getRelocationModel() == Reloc::PIC_), ABI(TM.getSubtarget<MipsSubtarget>().getTargetABI()), LongBranchSeqSize(!IsPIC ? 2 : (ABI == MipsSubtarget::N64 ? 13 : 9)) {} @@ -85,7 +84,6 @@ namespace { void expandToLongBranch(MBBInfo &Info); const TargetMachine &TM; - const MipsInstrInfo *TII; MachineFunction *MF; SmallVector<MBBInfo, 16> MBBInfos; bool IsPIC; @@ -172,6 +170,8 @@ void MipsLongBranch::initMBBInfo() { MBBInfos.clear(); MBBInfos.resize(MF->size()); + const MipsInstrInfo *TII = + static_cast<const MipsInstrInfo*>(TM.getInstrInfo()); for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) { MachineBasicBlock *MBB = MF->getBlockNumbered(I); @@ -217,7 +217,9 @@ int64_t MipsLongBranch::computeOffset(const MachineInstr *Br) { // MachineBasicBlock operand MBBOpnd. void MipsLongBranch::replaceBranch(MachineBasicBlock &MBB, Iter Br, DebugLoc DL, MachineBasicBlock *MBBOpnd) { - unsigned NewOpc = TII->GetOppositeBranchOpc(Br->getOpcode()); + const MipsInstrInfo *TII = + static_cast<const MipsInstrInfo*>(TM.getInstrInfo()); + unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode()); const MCInstrDesc &NewDesc = TII->get(NewOpc); MachineInstrBuilder MIB = BuildMI(MBB, Br, DL, NewDesc); @@ -247,6 +249,9 @@ void MipsLongBranch::expandToLongBranch(MBBInfo &I) { MachineFunction::iterator FallThroughMBB = ++MachineFunction::iterator(MBB); MachineBasicBlock *LongBrMBB = MF->CreateMachineBasicBlock(BB); + const MipsInstrInfo *TII = + static_cast<const MipsInstrInfo*>(TM.getInstrInfo()); + MF->insert(FallThroughMBB, LongBrMBB); MBB->removeSuccessor(TgtMBB); MBB->addSuccessor(LongBrMBB); @@ -399,6 +404,9 @@ static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) { } bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { + const MipsInstrInfo *TII = + static_cast<const MipsInstrInfo*>(TM.getInstrInfo()); + if (TM.getSubtarget<MipsSubtarget>().inMips16Mode()) return false; if ((TM.getRelocationModel() == Reloc::PIC_) && diff --git a/lib/Target/Mips/MipsOptimizeMathLibCalls.cpp b/lib/Target/Mips/MipsOptimizeMathLibCalls.cpp new file mode 100644 index 0000000..de3f09c --- /dev/null +++ b/lib/Target/Mips/MipsOptimizeMathLibCalls.cpp @@ -0,0 +1,175 @@ +//===---- MipsOptimizeMathLibCalls.cpp - Optimize math lib calls. ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass does an IR transformation which enables the backend to emit native +// math instructions. +// +//===----------------------------------------------------------------------===// + +#include "MipsTargetMachine.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Target/TargetLibraryInfo.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" + +using namespace llvm; + +static cl::opt<bool> DisableOpt("disable-mips-math-optimization", + cl::init(false), + cl::desc("MIPS: Disable math lib call " + "optimization."), cl::Hidden); + +namespace { + class MipsOptimizeMathLibCalls : public FunctionPass { + public: + static char ID; + + MipsOptimizeMathLibCalls(MipsTargetMachine &TM_) : + FunctionPass(ID), TM(TM_) {} + + virtual const char *getPassName() const { + return "MIPS: Optimize calls to math library functions."; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + + virtual bool runOnFunction(Function &F); + + private: + /// Optimize calls to sqrt. + bool optimizeSQRT(CallInst *Call, Function *CalledFunc, + BasicBlock &CurrBB, + Function::iterator &BB); + + const TargetMachine &TM; + }; + + char MipsOptimizeMathLibCalls::ID = 0; +} + +FunctionPass *llvm::createMipsOptimizeMathLibCalls(MipsTargetMachine &TM) { + return new MipsOptimizeMathLibCalls(TM); +} + +void MipsOptimizeMathLibCalls::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<TargetLibraryInfo>(); + FunctionPass::getAnalysisUsage(AU); +} + +bool MipsOptimizeMathLibCalls::runOnFunction(Function &F) { + if (DisableOpt) + return false; + + const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); + + if (Subtarget.inMips16Mode()) + return false; + + bool Changed = false; + Function::iterator CurrBB; + const TargetLibraryInfo *LibInfo = &getAnalysis<TargetLibraryInfo>(); + + for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) { + CurrBB = BB++; + + for (BasicBlock::iterator II = CurrBB->begin(), IE = CurrBB->end(); + II != IE; ++II) { + CallInst *Call = dyn_cast<CallInst>(&*II); + Function *CalledFunc; + + if (!Call || !(CalledFunc = Call->getCalledFunction())) + continue; + + LibFunc::Func LibFunc; + Attribute A = CalledFunc->getAttributes() + .getAttribute(AttributeSet::FunctionIndex, "use-soft-float"); + + // Skip if function has "use-soft-float" attribute. + if ((A.isStringAttribute() && (A.getValueAsString() == "true")) || + TM.Options.UseSoftFloat) + continue; + + // Skip if function either has local linkage or is not a known library + // function. + if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() || + !LibInfo->getLibFunc(CalledFunc->getName(), LibFunc)) + continue; + + switch (LibFunc) { + case LibFunc::sqrtf: + case LibFunc::sqrt: + if (optimizeSQRT(Call, CalledFunc, *CurrBB, BB)) + break; + continue; + default: + continue; + } + + Changed = true; + break; + } + } + + return Changed; +} + +bool MipsOptimizeMathLibCalls::optimizeSQRT(CallInst *Call, + Function *CalledFunc, + BasicBlock &CurrBB, + Function::iterator &BB) { + // There is no need to change the IR, since backend will emit sqrt + // instruction if the call has already been marked read-only. + if (Call->onlyReadsMemory()) + return false; + + // Do the following transformation: + // + // (before) + // dst = sqrt(src) + // + // (after) + // v0 = sqrt_noreadmem(src) # native sqrt instruction. + // if (v0 is a NaN) + // v1 = sqrt(src) # library call. + // dst = phi(v0, v1) + // + + // Move all instructions following Call to newly created block JoinBB. + // Create phi and replace all uses. + BasicBlock *JoinBB = llvm::SplitBlock(&CurrBB, Call->getNextNode(), this); + IRBuilder<> Builder(JoinBB, JoinBB->begin()); + PHINode *Phi = Builder.CreatePHI(Call->getType(), 2); + Call->replaceAllUsesWith(Phi); + + // Create basic block LibCallBB and insert a call to library function sqrt. + BasicBlock *LibCallBB = BasicBlock::Create(CurrBB.getContext(), "call.sqrt", + CurrBB.getParent(), JoinBB); + Builder.SetInsertPoint(LibCallBB); + Instruction *LibCall = Call->clone(); + Builder.Insert(LibCall); + Builder.CreateBr(JoinBB); + + // Add attribute "readnone" so that backend can use a native sqrt instruction + // for this call. Insert a FP compare instruction and a conditional branch + // at the end of CurrBB. + Call->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone); + CurrBB.getTerminator()->eraseFromParent(); + Builder.SetInsertPoint(&CurrBB); + Value *FCmp = Builder.CreateFCmpOEQ(Call, Call); + Builder.CreateCondBr(FCmp, JoinBB, LibCallBB); + + // Add phi operands. + Phi->addIncoming(Call, &CurrBB); + Phi->addIncoming(LibCall, LibCallBB); + + BB = JoinBB; + return true; +} diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index 3250733..ae25e45 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -100,6 +100,10 @@ MipsRegisterInfo::getCallPreservedMask(CallingConv::ID) const { return CSR_N64_RegMask; } +const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() { + return CSR_Mips16RetHelper_RegMask; +} + BitVector MipsRegisterInfo:: getReservedRegs(const MachineFunction &MF) const { static const uint16_t ReservedCPURegs[] = { @@ -145,7 +149,11 @@ getReservedRegs(const MachineFunction &MF) const { Reserved.set(Mips::HWR29_64); // Reserve DSP control register. - Reserved.set(Mips::DSPCtrl); + Reserved.set(Mips::DSPPos); + Reserved.set(Mips::DSPSCount); + Reserved.set(Mips::DSPCarry); + Reserved.set(Mips::DSPEFI); + Reserved.set(Mips::DSPOutFlag); // Reserve RA if in mips16 mode. if (Subtarget.inMips16Mode()) { diff --git a/lib/Target/Mips/MipsRegisterInfo.h b/lib/Target/Mips/MipsRegisterInfo.h index 5ed5124..20ba41d 100644 --- a/lib/Target/Mips/MipsRegisterInfo.h +++ b/lib/Target/Mips/MipsRegisterInfo.h @@ -46,6 +46,7 @@ public: MachineFunction &MF) const; const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const; const uint32_t *getCallPreservedMask(CallingConv::ID) const; + static const uint32_t *getMips16RetHelperMask(); BitVector getReservedRegs(const MachineFunction &MF) const; diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index 865d4d7..ad6912c 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -11,11 +11,16 @@ // Declarations that describe the MIPS register file //===----------------------------------------------------------------------===// let Namespace = "Mips" in { -def sub_fpeven : SubRegIndex; -def sub_fpodd : SubRegIndex; -def sub_32 : SubRegIndex; -def sub_lo : SubRegIndex; -def sub_hi : SubRegIndex; +def sub_fpeven : SubRegIndex<32>; +def sub_fpodd : SubRegIndex<32, 32>; +def sub_32 : SubRegIndex<32>; +def sub_lo : SubRegIndex<32>; +def sub_hi : SubRegIndex<32, 32>; +def sub_dsp16_19 : SubRegIndex<4, 16>; +def sub_dsp20 : SubRegIndex<1, 20>; +def sub_dsp21 : SubRegIndex<1, 21>; +def sub_dsp22 : SubRegIndex<1, 22>; +def sub_dsp23 : SubRegIndex<1, 23>; } class Unallocatable { @@ -264,8 +269,23 @@ let Namespace = "Mips" in { def AC0_64 : ACC<0, "ac0", [LO64, HI64]>; - def DSPCtrl : Register<"dspctrl">; + // DSP-ASE control register fields. + def DSPPos : Register<"">; + def DSPSCount : Register<"">; + def DSPCarry : Register<"">; + def DSPEFI : Register<"">; + def DSPOutFlag16_19 : Register<"">; + def DSPOutFlag20 : Register<"">; + def DSPOutFlag21 : Register<"">; + def DSPOutFlag22 : Register<"">; + def DSPOutFlag23 : Register<"">; def DSPCCond : Register<"">; + + let SubRegIndices = [sub_dsp16_19, sub_dsp20, sub_dsp21, sub_dsp22, + sub_dsp23] in + def DSPOutFlag : RegisterWithSubRegs<"", [DSPOutFlag16_19, DSPOutFlag20, + DSPOutFlag21, DSPOutFlag22, + DSPOutFlag23]>; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsSEFrameLowering.cpp b/lib/Target/Mips/MipsSEFrameLowering.cpp index 2b76704..91ffb94 100644 --- a/lib/Target/Mips/MipsSEFrameLowering.cpp +++ b/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -40,6 +40,8 @@ public: private: bool expandInstr(MachineBasicBlock &MBB, Iter I); + void expandLoadCCond(MachineBasicBlock &MBB, Iter I); + void expandStoreCCond(MachineBasicBlock &MBB, Iter I); void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize); void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize); bool expandCopy(MachineBasicBlock &MBB, Iter I); @@ -47,16 +49,12 @@ private: unsigned Src, unsigned RegSize); MachineFunction &MF; - const MipsSEInstrInfo &TII; - const MipsRegisterInfo &RegInfo; MachineRegisterInfo &MRI; }; } ExpandPseudo::ExpandPseudo(MachineFunction &MF_) - : MF(MF_), - TII(*static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo())), - RegInfo(TII.getRegisterInfo()), MRI(MF.getRegInfo()) {} + : MF(MF_), MRI(MF.getRegInfo()) {} bool ExpandPseudo::expand() { bool Expanded = false; @@ -71,6 +69,14 @@ bool ExpandPseudo::expand() { bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) { switch(I->getOpcode()) { + case Mips::LOAD_CCOND_DSP: + case Mips::LOAD_CCOND_DSP_P8: + expandLoadCCond(MBB, I); + break; + case Mips::STORE_CCOND_DSP: + case Mips::STORE_CCOND_DSP_P8: + expandStoreCCond(MBB, I); + break; case Mips::LOAD_AC64: case Mips::LOAD_AC64_P8: case Mips::LOAD_AC_DSP: @@ -103,6 +109,46 @@ bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) { return true; } +void ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) { + // load $vr, FI + // copy ccond, $vr + + assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); + + const MipsSEInstrInfo &TII = + *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); + const MipsRegisterInfo &RegInfo = + *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + + const TargetRegisterClass *RC = RegInfo.intRegClass(4); + unsigned VR = MRI.createVirtualRegister(RC); + unsigned Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); + + TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0); + BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst) + .addReg(VR, RegState::Kill); +} + +void ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) { + // copy $vr, ccond + // store $vr, FI + + assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); + + const MipsSEInstrInfo &TII = + *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); + const MipsRegisterInfo &RegInfo = + *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + + const TargetRegisterClass *RC = RegInfo.intRegClass(4); + unsigned VR = MRI.createVirtualRegister(RC); + unsigned Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex(); + + BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR) + .addReg(Src, getKillRegState(I->getOperand(0).isKill())); + TII.storeRegToStack(MBB, I, VR, true, FI, RC, &RegInfo, 0); +} + void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize) { // load $vr0, FI @@ -112,6 +158,11 @@ void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I, assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); + const MipsSEInstrInfo &TII = + *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); + const MipsRegisterInfo &RegInfo = + *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); unsigned VR0 = MRI.createVirtualRegister(RC); unsigned VR1 = MRI.createVirtualRegister(RC); @@ -136,6 +187,11 @@ void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I, assert(I->getOperand(0).isReg() && I->getOperand(1).isFI()); + const MipsSEInstrInfo &TII = + *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); + const MipsRegisterInfo &RegInfo = + *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); unsigned VR0 = MRI.createVirtualRegister(RC); unsigned VR1 = MRI.createVirtualRegister(RC); @@ -170,6 +226,11 @@ bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned Dst, // copy $vr1, src_hi // copy dst_hi, $vr1 + const MipsSEInstrInfo &TII = + *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); + const MipsRegisterInfo &RegInfo = + *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize); unsigned VR0 = MRI.createVirtualRegister(RC); unsigned VR1 = MRI.createVirtualRegister(RC); @@ -204,10 +265,12 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); - const MipsRegisterInfo *RegInfo = - static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + const MipsSEInstrInfo &TII = *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); + const MipsRegisterInfo &RegInfo = + *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + MachineBasicBlock::iterator MBBI = MBB.begin(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; @@ -222,7 +285,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { if (StackSize == 0 && !MFI->adjustsStack()) return; MachineModuleInfo &MMI = MF.getMMI(); - std::vector<MachineMove> &Moves = MMI.getFrameMoves(); + const MCRegisterInfo &MRI = MMI.getContext().getRegisterInfo(); MachineLocation DstML, SrcML; // Adjust stack. @@ -232,9 +295,8 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); - DstML = MachineLocation(MachineLocation::VirtualFP); - SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); - Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); + MMI.addFrameInst( + MCCFIInstruction::createDefCfaOffset(AdjustSPLabel, -StackSize)); const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); @@ -258,21 +320,22 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { // If Reg is a double precision register, emit two cfa_offsets, // one for each of the paired single precision registers. if (Mips::AFGR64RegClass.contains(Reg)) { - MachineLocation DstML0(MachineLocation::VirtualFP, Offset); - MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4); - MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven)); - MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd)); + unsigned Reg0 = + MRI.getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpeven), true); + unsigned Reg1 = + MRI.getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_fpodd), true); if (!STI.isLittle()) - std::swap(SrcML0, SrcML1); + std::swap(Reg0, Reg1); - Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0)); - Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1)); + MMI.addFrameInst( + MCCFIInstruction::createOffset(CSLabel, Reg0, Offset)); + MMI.addFrameInst( + MCCFIInstruction::createOffset(CSLabel, Reg1, Offset + 4)); } else { // Reg is either in CPURegs or FGR32. - DstML = MachineLocation(MachineLocation::VirtualFP, Offset); - SrcML = MachineLocation(Reg); - Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); + MMI.addFrameInst(MCCFIInstruction::createOffset( + CSLabel, MRI.getDwarfRegNum(Reg, 1), Offset)); } } } @@ -286,7 +349,7 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { if (!MBB.isLiveIn(ehDataReg(I))) MBB.addLiveIn(ehDataReg(I)); TII.storeRegToStackSlot(MBB, MBBI, ehDataReg(I), false, - MipsFI->getEhDataRegFI(I), RC, RegInfo); + MipsFI->getEhDataRegFI(I), RC, &RegInfo); } // Emit .cfi_offset directives for eh data registers. @@ -295,9 +358,8 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel2); for (int I = 0; I < 4; ++I) { int64_t Offset = MFI->getObjectOffset(MipsFI->getEhDataRegFI(I)); - DstML = MachineLocation(MachineLocation::VirtualFP, Offset); - SrcML = MachineLocation(ehDataReg(I)); - Moves.push_back(MachineMove(CSLabel2, DstML, SrcML)); + unsigned Reg = MRI.getDwarfRegNum(ehDataReg(I), true); + MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel2, Reg, Offset)); } } @@ -310,9 +372,8 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); - DstML = MachineLocation(FP); - SrcML = MachineLocation(MachineLocation::VirtualFP); - Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML)); + MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister( + SetFPLabel, MRI.getDwarfRegNum(FP, true))); } } @@ -321,10 +382,12 @@ void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); MachineFrameInfo *MFI = MF.getFrameInfo(); MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); - const MipsRegisterInfo *RegInfo = - static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + const MipsSEInstrInfo &TII = *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo()); + const MipsRegisterInfo &RegInfo = + *static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + DebugLoc dl = MBBI->getDebugLoc(); unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; @@ -355,7 +418,7 @@ void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, // Insert instructions that restore eh data registers. for (int J = 0; J < 4; ++J) { TII.loadRegFromStackSlot(MBB, I, ehDataReg(J), MipsFI->getEhDataRegFI(J), - RC, RegInfo); + RC, &RegInfo); } } diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index b54f1f4..7684bec 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -41,6 +41,31 @@ bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { return MipsDAGToDAGISel::runOnMachineFunction(MF); } +void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, + MachineFunction &MF) { + MachineInstrBuilder MIB(MF, &MI); + unsigned Mask = MI.getOperand(1).getImm(); + unsigned Flag = IsDef ? RegState::ImplicitDefine : RegState::Implicit; + + if (Mask & 1) + MIB.addReg(Mips::DSPPos, Flag); + + if (Mask & 2) + MIB.addReg(Mips::DSPSCount, Flag); + + if (Mask & 4) + MIB.addReg(Mips::DSPCarry, Flag); + + if (Mask & 8) + MIB.addReg(Mips::DSPOutFlag, Flag); + + if (Mask & 16) + MIB.addReg(Mips::DSPCCond, Flag); + + if (Mask & 32) + MIB.addReg(Mips::DSPEFI, Flag); +} + bool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr& MI) { unsigned DstReg = 0, ZeroReg = 0; @@ -178,12 +203,18 @@ void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI != MFE; ++MFI) - for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) - replaceUsesWithZeroReg(MRI, *I); + for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) { + if (I->getOpcode() == Mips::RDDSP) + addDSPCtrlRegOperands(false, *I, MF); + else if (I->getOpcode() == Mips::WRDSP) + addDSPCtrlRegOperands(true, *I, MF); + else + replaceUsesWithZeroReg(MRI, *I); + } } SDNode *MipsSEDAGToDAGISel::selectAddESubE(unsigned MOp, SDValue InFlag, - SDValue CmpLHS, DebugLoc DL, + SDValue CmpLHS, SDLoc DL, SDNode *Node) const { unsigned Opc = InFlag.getOpcode(); (void)Opc; @@ -285,7 +316,7 @@ bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { unsigned Opcode = Node->getOpcode(); - DebugLoc DL = Node->getDebugLoc(); + SDLoc DL(Node); /// // Instruction Selection not handled by the auto-generated @@ -343,7 +374,7 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { AnalyzeImm.Analyze(Imm, Size, false); MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); - DebugLoc DL = CN->getDebugLoc(); + SDLoc DL(CN); SDNode *RegOpnd; SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), MVT::i64); @@ -371,7 +402,7 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { } case MipsISD::ThreadPointer: { - EVT PtrVT = TLI.getPointerTy(); + EVT PtrVT = TLI->getPointerTy(); unsigned RdhwrOpc, SrcReg, DestReg; if (PtrVT == MVT::i32) { @@ -385,7 +416,7 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { } SDNode *Rdhwr = - CurDAG->getMachineNode(RdhwrOpc, Node->getDebugLoc(), + CurDAG->getMachineNode(RdhwrOpc, SDLoc(Node), Node->getValueType(0), CurDAG->getRegister(SrcReg, PtrVT)); SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, DestReg, diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.h b/lib/Target/Mips/MipsSEISelDAGToDAG.h index 0dae73d..03ed1f9 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -27,13 +27,16 @@ private: virtual bool runOnMachineFunction(MachineFunction &MF); + void addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, + MachineFunction &MF); + bool replaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr&); - std::pair<SDNode*, SDNode*> selectMULT(SDNode *N, unsigned Opc, DebugLoc dl, + std::pair<SDNode*, SDNode*> selectMULT(SDNode *N, unsigned Opc, SDLoc dl, EVT Ty, bool HasLo, bool HasHi); SDNode *selectAddESubE(unsigned MOp, SDValue InFlag, SDValue CmpLHS, - DebugLoc DL, SDNode *Node) const; + SDLoc DL, SDNode *Node) const; virtual bool selectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset) const; diff --git a/lib/Target/Mips/MipsSEISelLowering.cpp b/lib/Target/Mips/MipsSEISelLowering.cpp index 8544bb8..f640ecc 100644 --- a/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/lib/Target/Mips/MipsSEISelLowering.cpp @@ -186,7 +186,7 @@ static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) { if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) return false; - DebugLoc DL = ADDENode->getDebugLoc(); + SDLoc DL(ADDENode); // Initialize accumulator. SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, @@ -262,7 +262,7 @@ static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) { if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) return false; - DebugLoc DL = SUBENode->getDebugLoc(); + SDLoc DL(SUBENode); // Initialize accumulator. SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, @@ -337,7 +337,7 @@ static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty, (SplatValue.getZExtValue() >= EltSize)) return SDValue(); - return DAG.getNode(Opc, N->getDebugLoc(), Ty, N->getOperand(0), + return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0), DAG.getConstant(SplatValue.getZExtValue(), MVT::i32)); } @@ -402,7 +402,7 @@ static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) { if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get())) return SDValue(); - return DAG.getNode(MipsISD::SETCC_DSP, N->getDebugLoc(), Ty, N->getOperand(0), + return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0), N->getOperand(1), N->getOperand(2)); } @@ -417,7 +417,7 @@ static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) { if (SetCC.getOpcode() != MipsISD::SETCC_DSP) return SDValue(); - return DAG.getNode(MipsISD::SELECT_CC_DSP, N->getDebugLoc(), Ty, + return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty, SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1), N->getOperand(2), SetCC.getOperand(2)); } @@ -500,7 +500,7 @@ SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, bool HasLo, bool HasHi, SelectionDAG &DAG) const { EVT Ty = Op.getOperand(0).getValueType(); - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped, Op.getOperand(0), Op.getOperand(1)); SDValue Lo, Hi; @@ -520,7 +520,7 @@ SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, } -static SDValue initAccumulator(SDValue In, DebugLoc DL, SelectionDAG &DAG) { +static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) { SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, DAG.getConstant(0, MVT::i32)); SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, @@ -528,7 +528,7 @@ static SDValue initAccumulator(SDValue In, DebugLoc DL, SelectionDAG &DAG) { return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi); } -static SDValue extractLOHI(SDValue Op, DebugLoc DL, SelectionDAG &DAG) { +static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) { SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, DAG.getConstant(Mips::sub_lo, MVT::i32)); SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, @@ -549,7 +549,7 @@ static SDValue extractLOHI(SDValue Op, DebugLoc DL, SelectionDAG &DAG) { // out64 = merge-values (v0, v1) // static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { - DebugLoc DL = Op.getDebugLoc(); + SDLoc DL(Op); bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other; SmallVector<SDValue, 3> Ops; unsigned OpNo = 0; diff --git a/lib/Target/Mips/MipsSEInstrInfo.cpp b/lib/Target/Mips/MipsSEInstrInfo.cpp index 2e7048d..e2a33dd 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.cpp +++ b/lib/Target/Mips/MipsSEInstrInfo.cpp @@ -18,15 +18,21 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; +static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false), + cl::desc("Expand double precision loads and " + "stores to their single precision " + "counterparts.")); + MipsSEInstrInfo::MipsSEInstrInfo(MipsTargetMachine &tm) : MipsInstrInfo(tm, tm.getRelocationModel() == Reloc::PIC_ ? Mips::B : Mips::J), - RI(*tm.getSubtargetImpl(), *this), + RI(*tm.getSubtargetImpl()), IsN64(tm.getSubtarget<MipsSubtarget>().isABI_N64()) {} const MipsRegisterInfo &MipsSEInstrInfo::getRegisterInfo() const { @@ -103,6 +109,11 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, Opc = Mips::MFHI_DSP; else if (Mips::LORegsDSPRegClass.contains(SrcReg)) Opc = Mips::MFLO_DSP; + else if (Mips::DSPCCRegClass.contains(SrcReg)) { + BuildMI(MBB, I, DL, get(Mips::RDDSP), DestReg).addImm(1 << 4) + .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); + return; + } } else if (Mips::CPURegsRegClass.contains(SrcReg)) { // Copy from CPU Reg. if (Mips::CCRRegClass.contains(DestReg)) @@ -117,6 +128,12 @@ void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB, Opc = Mips::MTHI_DSP; else if (Mips::LORegsDSPRegClass.contains(DestReg)) Opc = Mips::MTLO_DSP; + else if (Mips::DSPCCRegClass.contains(DestReg)) { + BuildMI(MBB, I, DL, get(Mips::WRDSP)) + .addReg(SrcReg, getKillRegState(KillSrc)).addImm(1 << 4) + .addReg(DestReg, RegState::ImplicitDefine); + return; + } } else if (Mips::FGR32RegClass.contains(DestReg, SrcReg)) Opc = Mips::FMOV_S; @@ -180,6 +197,8 @@ storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Opc = IsN64 ? Mips::STORE_AC_DSP_P8 : Mips::STORE_AC_DSP; else if (Mips::ACRegs128RegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::STORE_AC128_P8 : Mips::STORE_AC128; + else if (Mips::DSPCCRegClass.hasSubClassEq(RC)) + Opc = IsN64 ? Mips::STORE_CCOND_DSP_P8 : Mips::STORE_CCOND_DSP; else if (Mips::FGR32RegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::SWC1_P8 : Mips::SWC1; else if (Mips::AFGR64RegClass.hasSubClassEq(RC)) @@ -211,6 +230,8 @@ loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Opc = IsN64 ? Mips::LOAD_AC_DSP_P8 : Mips::LOAD_AC_DSP; else if (Mips::ACRegs128RegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::LOAD_AC128_P8 : Mips::LOAD_AC128; + else if (Mips::DSPCCRegClass.hasSubClassEq(RC)) + Opc = IsN64 ? Mips::LOAD_CCOND_DSP_P8 : Mips::LOAD_CCOND_DSP; else if (Mips::FGR32RegClass.hasSubClassEq(RC)) Opc = IsN64 ? Mips::LWC1_P8 : Mips::LWC1; else if (Mips::AFGR64RegClass.hasSubClassEq(RC)) @@ -230,17 +251,38 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { default: return false; case Mips::RetRA: - ExpandRetRA(MBB, MI, Mips::RET); + expandRetRA(MBB, MI, Mips::RET); + break; + case Mips::PseudoCVT_S_W: + expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false); + break; + case Mips::PseudoCVT_D32_W: + expandCvtFPInt(MBB, MI, Mips::CVT_D32_W, Mips::MTC1, false); + break; + case Mips::PseudoCVT_S_L: + expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, true); + break; + case Mips::PseudoCVT_D64_W: + expandCvtFPInt(MBB, MI, Mips::CVT_D64_W, Mips::MTC1, true); + break; + case Mips::PseudoCVT_D64_L: + expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true); break; case Mips::BuildPairF64: - ExpandBuildPairF64(MBB, MI); + expandBuildPairF64(MBB, MI); break; case Mips::ExtractElementF64: - ExpandExtractElementF64(MBB, MI); + expandExtractElementF64(MBB, MI); + break; + case Mips::PseudoLDC1: + expandDPLoadStore(MBB, MI, Mips::LDC1, Mips::LWC1); + break; + case Mips::PseudoSDC1: + expandDPLoadStore(MBB, MI, Mips::SDC1, Mips::SWC1); break; case Mips::MIPSeh_return32: case Mips::MIPSeh_return64: - ExpandEhReturn(MBB, MI); + expandEhReturn(MBB, MI); break; } @@ -248,9 +290,9 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { return true; } -/// GetOppositeBranchOpc - Return the inverse of the specified +/// getOppositeBranchOpc - Return the inverse of the specified /// opcode, e.g. turning BEQ to BNE. -unsigned MipsSEInstrInfo::GetOppositeBranchOpc(unsigned Opc) const { +unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const { switch (Opc) { default: llvm_unreachable("Illegal opcode!"); case Mips::BEQ: return Mips::BNE; @@ -331,7 +373,7 @@ MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB, return Reg; } -unsigned MipsSEInstrInfo::GetAnalyzableBrOpc(unsigned Opc) const { +unsigned MipsSEInstrInfo::getAnalyzableBrOpc(unsigned Opc) const { return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ || Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ || Opc == Mips::BEQ64 || Opc == Mips::BNE64 || Opc == Mips::BGTZ64 || @@ -341,13 +383,49 @@ unsigned MipsSEInstrInfo::GetAnalyzableBrOpc(unsigned Opc) const { Opc : 0; } -void MipsSEInstrInfo::ExpandRetRA(MachineBasicBlock &MBB, +void MipsSEInstrInfo::expandRetRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned Opc) const { BuildMI(MBB, I, I->getDebugLoc(), get(Opc)).addReg(Mips::RA); } -void MipsSEInstrInfo::ExpandExtractElementF64(MachineBasicBlock &MBB, +std::pair<bool, bool> +MipsSEInstrInfo::compareOpndSize(unsigned Opc, + const MachineFunction &MF) const { + const MCInstrDesc &Desc = get(Opc); + assert(Desc.NumOperands == 2 && "Unary instruction expected."); + const MipsRegisterInfo *RI = &getRegisterInfo(); + unsigned DstRegSize = getRegClass(Desc, 0, RI, MF)->getSize(); + unsigned SrcRegSize = getRegClass(Desc, 1, RI, MF)->getSize(); + + return std::make_pair(DstRegSize > SrcRegSize, DstRegSize < SrcRegSize); +} + +void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned CvtOpc, unsigned MovOpc, + bool IsI64) const { + const MCInstrDesc &CvtDesc = get(CvtOpc), &MovDesc = get(MovOpc); + const MachineOperand &Dst = I->getOperand(0), &Src = I->getOperand(1); + unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg; + unsigned KillSrc = getKillRegState(Src.isKill()); + DebugLoc DL = I->getDebugLoc(); + unsigned SubIdx = (IsI64 ? Mips::sub_32 : Mips::sub_fpeven); + bool DstIsLarger, SrcIsLarger; + + tie(DstIsLarger, SrcIsLarger) = compareOpndSize(CvtOpc, *MBB.getParent()); + + if (DstIsLarger) + TmpReg = getRegisterInfo().getSubReg(DstReg, SubIdx); + + if (SrcIsLarger) + DstReg = getRegisterInfo().getSubReg(DstReg, SubIdx); + + BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc); + BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill); +} + +void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { unsigned DstReg = I->getOperand(0).getReg(); unsigned SrcReg = I->getOperand(1).getReg(); @@ -362,7 +440,7 @@ void MipsSEInstrInfo::ExpandExtractElementF64(MachineBasicBlock &MBB, BuildMI(MBB, I, dl, Mfc1Tdd, DstReg).addReg(SubReg); } -void MipsSEInstrInfo::ExpandBuildPairF64(MachineBasicBlock &MBB, +void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { unsigned DstReg = I->getOperand(0).getReg(); unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg(); @@ -378,7 +456,57 @@ void MipsSEInstrInfo::ExpandBuildPairF64(MachineBasicBlock &MBB, .addReg(HiReg); } -void MipsSEInstrInfo::ExpandEhReturn(MachineBasicBlock &MBB, +/// Add 4 to the displacement of operand MO. +static void fixDisp(MachineOperand &MO) { + switch (MO.getType()) { + default: + llvm_unreachable("Unhandled operand type."); + case MachineOperand::MO_Immediate: + MO.setImm(MO.getImm() + 4); + break; + case MachineOperand::MO_GlobalAddress: + case MachineOperand::MO_ConstantPoolIndex: + case MachineOperand::MO_BlockAddress: + case MachineOperand::MO_TargetIndex: + case MachineOperand::MO_ExternalSymbol: + MO.setOffset(MO.getOffset() + 4); + break; + } +} + +void MipsSEInstrInfo::expandDPLoadStore(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned OpcD, unsigned OpcS) const { + // If NoDPLoadStore is false, just change the opcode. + if (!NoDPLoadStore) { + genInstrWithNewOpc(OpcD, I); + return; + } + + // Expand a double precision FP load or store to two single precision + // instructions. + + const TargetRegisterInfo &TRI = getRegisterInfo(); + const MachineOperand &ValReg = I->getOperand(0); + unsigned LoReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_fpeven); + unsigned HiReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_fpodd); + + if (!TM.getSubtarget<MipsSubtarget>().isLittle()) + std::swap(LoReg, HiReg); + + // Create an instruction which loads from or stores to the lower memory + // address. + MachineInstrBuilder MIB = genInstrWithNewOpc(OpcS, I); + MIB->getOperand(0).setReg(LoReg); + + // Create an instruction which loads from or stores to the higher memory + // address. + MIB = genInstrWithNewOpc(OpcS, I); + MIB->getOperand(0).setReg(HiReg); + fixDisp(MIB->getOperand(2)); +} + +void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { // This pseudo instruction is generated as part of the lowering of // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and diff --git a/lib/Target/Mips/MipsSEInstrInfo.h b/lib/Target/Mips/MipsSEInstrInfo.h index 0bf7876..d962ef0 100644 --- a/lib/Target/Mips/MipsSEInstrInfo.h +++ b/lib/Target/Mips/MipsSEInstrInfo.h @@ -65,7 +65,7 @@ public: virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const; - virtual unsigned GetOppositeBranchOpc(unsigned Opc) const; + virtual unsigned getOppositeBranchOpc(unsigned Opc) const; /// Adjust SP by Amount bytes. void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, @@ -79,15 +79,35 @@ public: unsigned *NewImm) const; private: - virtual unsigned GetAnalyzableBrOpc(unsigned Opc) const; + virtual unsigned getAnalyzableBrOpc(unsigned Opc) const; - void ExpandRetRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + void expandRetRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned Opc) const; - void ExpandExtractElementF64(MachineBasicBlock &MBB, + + std::pair<bool, bool> compareOpndSize(unsigned Opc, + const MachineFunction &MF) const; + + /// Expand pseudo Int-to-FP conversion instructions. + /// + /// For example, the following pseudo instruction + /// PseudoCVT_D32_W D2, A5 + /// gets expanded into these two instructions: + /// MTC1 F4, A5 + /// CVT_D32_W D2, F4 + /// + /// We do this expansion post-RA to avoid inserting a floating point copy + /// instruction between MTC1 and CVT_D32_W. + void expandCvtFPInt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + unsigned CvtOpc, unsigned MovOpc, bool IsI64) const; + + void expandExtractElementF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; - void ExpandBuildPairF64(MachineBasicBlock &MBB, + void expandBuildPairF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; - void ExpandEhReturn(MachineBasicBlock &MBB, + void expandDPLoadStore(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, unsigned OpcD, + unsigned OpcS) const; + void expandEhReturn(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; }; diff --git a/lib/Target/Mips/MipsSERegisterInfo.cpp b/lib/Target/Mips/MipsSERegisterInfo.cpp index 9696738..9763f85 100644 --- a/lib/Target/Mips/MipsSERegisterInfo.cpp +++ b/lib/Target/Mips/MipsSERegisterInfo.cpp @@ -40,9 +40,8 @@ using namespace llvm; -MipsSERegisterInfo::MipsSERegisterInfo(const MipsSubtarget &ST, - const MipsSEInstrInfo &I) - : MipsRegisterInfo(ST), TII(I) {} +MipsSERegisterInfo::MipsSERegisterInfo(const MipsSubtarget &ST) + : MipsRegisterInfo(ST) {} bool MipsSERegisterInfo:: requiresRegisterScavenging(const MachineFunction &MF) const { @@ -119,7 +118,9 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, DebugLoc DL = II->getDebugLoc(); unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu; unsigned NewImm; - + const MipsSEInstrInfo &TII = + *static_cast<const MipsSEInstrInfo*>( + MBB.getParent()->getTarget().getInstrInfo()); unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL, &NewImm); BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(FrameReg) .addReg(Reg, RegState::Kill); diff --git a/lib/Target/Mips/MipsSERegisterInfo.h b/lib/Target/Mips/MipsSERegisterInfo.h index 2f7c37b..76cdd9d 100644 --- a/lib/Target/Mips/MipsSERegisterInfo.h +++ b/lib/Target/Mips/MipsSERegisterInfo.h @@ -21,11 +21,8 @@ namespace llvm { class MipsSEInstrInfo; class MipsSERegisterInfo : public MipsRegisterInfo { - const MipsSEInstrInfo &TII; - public: - MipsSERegisterInfo(const MipsSubtarget &Subtarget, - const MipsSEInstrInfo &TII); + MipsSERegisterInfo(const MipsSubtarget &Subtarget); bool requiresRegisterScavenging(const MachineFunction &MF) const; diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp index 14a2b27..259e68d 100644 --- a/lib/Target/Mips/MipsSubtarget.cpp +++ b/lib/Target/Mips/MipsSubtarget.cpp @@ -48,6 +48,11 @@ static cl::opt<bool> Mips_Os16( "floating point as Mips 16"), cl::Hidden); +static cl::opt<bool> +Mips16HardFloat("mips16-hard-float", cl::NotHidden, + cl::desc("MIPS: mips16 hard float enable."), + cl::init(false)); + void MipsSubtarget::anchor() { } MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, @@ -58,7 +63,8 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, IsSingleFloat(false), IsFP64bit(false), IsGP64bit(false), HasVFPU(false), IsLinux(true), HasSEInReg(false), HasCondMov(false), HasSwap(false), HasBitCount(false), HasFPIdx(false), - InMips16Mode(false), InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), + InMips16Mode(false), InMips16HardFloat(Mips16HardFloat), + InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), RM(_RM), OverrideMode(NoOverride), TM(_TM) { diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index f2f0e15..ef7568a 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -93,6 +93,9 @@ protected: // InMips16 -- can process Mips16 instructions bool InMips16Mode; + // Mips16 hard float + bool InMips16HardFloat; + // PreviousInMips16 -- the function we just processed was in Mips 16 Mode bool PreviousInMips16Mode; @@ -170,9 +173,12 @@ public: } llvm_unreachable("Unexpected mode"); } - bool inMips16ModeDefault() { + bool inMips16ModeDefault() const { return InMips16Mode; } + bool inMips16HardFloat() const { + return inMips16Mode() && InMips16HardFloat; + } bool inMicroMipsMode() const { return InMicroMipsMode; } bool hasDSP() const { return HasDSP; } bool hasDSPR2() const { return HasDSPR2; } @@ -188,7 +194,8 @@ public: bool hasBitCount() const { return HasBitCount; } bool hasFPIdx() const { return HasFPIdx; } - bool allowMixed16_32() const { return AllowMixed16_32;}; + bool allowMixed16_32() const { return inMips16ModeDefault() | + AllowMixed16_32;} bool os16() const { return Os16;}; diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp index ee28e2a..9af2f1b 100644 --- a/lib/Target/Mips/MipsTargetMachine.cpp +++ b/lib/Target/Mips/MipsTargetMachine.cpp @@ -22,6 +22,7 @@ #include "MipsSEISelLowering.h" #include "MipsSEISelDAGToDAG.h" #include "Mips16FrameLowering.h" +#include "Mips16HardFloat.h" #include "Mips16InstrInfo.h" #include "Mips16ISelDAGToDAG.h" #include "Mips16ISelLowering.h" @@ -71,6 +72,7 @@ MipsTargetMachine(const Target &T, StringRef TT, FrameLowering(MipsFrameLowering::create(*this, Subtarget)), TLInfo(MipsTargetLowering::create(*this)), TSInfo(*this), JITInfo() { + initAsmInfo(); } @@ -156,6 +158,9 @@ void MipsPassConfig::addIRPasses() { TargetPassConfig::addIRPasses(); if (getMipsSubtarget().os16()) addPass(createMipsOs16(getMipsTargetMachine())); + if (getMipsSubtarget().inMips16HardFloat()) + addPass(createMips16HardFloat(getMipsTargetMachine())); + addPass(createMipsOptimizeMathLibCalls(getMipsTargetMachine())); } // Install an instruction selector pass using // the ISelDag to gen Mips code. |
