#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
SDNode *Select(SDNode *N);
// Complex Pattern.
- bool SelectAddr(SDValue N, SDValue &Base, SDValue &Offset);
+ bool SelectAddr(SDNode *Parent, SDValue N, SDValue &Base, SDValue &Offset);
// getImm - Return a target constant with the specified value.
inline SDValue getImm(const SDNode *Node, unsigned Imm) {
// passes from moving them.
void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) {
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
-
+
if (!MipsFI->globalBaseRegSet())
return;
unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg();
bool FixGlobalBaseReg = MipsFI->globalBaseRegFixed();
- if (FixGlobalBaseReg) // $gp is the global base register.
+ if (Subtarget.isABI_O32() && FixGlobalBaseReg)
+ // $gp is the global base register.
V0 = V1 = GlobalBaseReg;
else {
const TargetRegisterClass *RC;
RC = Subtarget.isABI_N64() ?
- Mips::CPU64RegsRegisterClass : Mips::CPURegsRegisterClass;
-
+ Mips::CPU64RegsRegisterClass : Mips::CPURegsRegisterClass;
+
V0 = RegInfo.createVirtualRegister(RC);
V1 = RegInfo.createVirtualRegister(RC);
}
BuildMI(MBB, I, DL, TII.get(Mips::SETGP2), GlobalBaseReg)
.addReg(Mips::T9);
}
- }
+ }
}
bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
-
+
InitGlobalBaseReg(MF);
return Ret;
/// ComplexPattern used on MipsInstrInfo
/// Used on Mips Load/Store instructions
bool MipsDAGToDAGISel::
-SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) {
+SelectAddr(SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset) {
EVT ValTy = Addr.getValueType();
// if Address is FI, get the TargetFrameIndex.
// lwc1 $f0, %lo($CPI1_0)($2)
if (Addr.getOperand(1).getOpcode() == MipsISD::Lo) {
SDValue LoVal = Addr.getOperand(1);
- if (isa<ConstantPoolSDNode>(LoVal.getOperand(0)) ||
+ if (isa<ConstantPoolSDNode>(LoVal.getOperand(0)) ||
isa<GlobalAddressSDNode>(LoVal.getOperand(0))) {
Base = Addr.getOperand(0);
Offset = LoVal.getOperand(0);
return true;
}
}
+
+ // If an indexed load/store can be emitted, return false.
+ if (const LSBaseSDNode* LS = dyn_cast<LSBaseSDNode>(Parent))
+ if ((LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() == MVT::f64) &&
+ Subtarget.hasMips32r2Or64())
+ return false;
}
Base = Addr;
/// Select multiply instructions.
std::pair<SDNode*, SDNode*>
-MipsDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty,
+MipsDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty,
bool HasLo, bool HasHi) {
SDNode *Lo = 0, *Hi = 0;
SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N->getOperand(0),
if (HasHi)
Hi = CurDAG->getMachineNode(Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64, dl,
Ty, InFlag);
-
+
return std::make_pair(Lo, Hi);
}
const MipsAnalyzeImmediate::InstSeq &Seq =
AnalyzeImm.Analyze(Imm, Size, false);
-
+
MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
DebugLoc DL = CN->getDebugLoc();
SDNode *RegOpnd;
SrcReg = Mips::HWR29_64;
DestReg = Mips::V1_64;
}
-
+
SDNode *Rdhwr =
CurDAG->getMachineNode(RdhwrOpc, Node->getDebugLoc(),
Node->getValueType(0),