summaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-01-15 15:37:28 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-01-15 15:37:28 +0000
commit3fba7d16b41dfbefe3b1be6bc0ab94c017728f79 (patch)
treebe5a687969f682edded4aa6f13594ffd9aa9030e /lib/Target
parenta16c51cee9225a354c999dd1076d5dba2aa79807 (diff)
downloadFreeBSD-src-3fba7d16b41dfbefe3b1be6bc0ab94c017728f79.zip
FreeBSD-src-3fba7d16b41dfbefe3b1be6bc0ab94c017728f79.tar.gz
Update LLVM to 93512.
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp67
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.h2
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp15
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp321
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp23
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td4
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td33
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td2
-rw-r--r--lib/Target/ARM/ARMLoadStoreOptimizer.cpp12
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.td13
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp39
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp27
-rw-r--r--lib/Target/Alpha/AlphaISelDAGToDAG.cpp26
-rw-r--r--lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp9
-rw-r--r--lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp11
-rw-r--r--lib/Target/CBackend/CBackend.cpp38
-rw-r--r--lib/Target/CellSPU/SPUISelDAGToDAG.cpp171
-rw-r--r--lib/Target/MSP430/MSP430ISelDAGToDAG.cpp67
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp13
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td40
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp75
-rw-r--r--lib/Target/PIC16/PIC16ISelDAGToDAG.cpp4
-rw-r--r--lib/Target/PIC16/PIC16ISelDAGToDAG.h4
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp122
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp36
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td8
-rw-r--r--lib/Target/PowerPC/PPCJITInfo.cpp2
-rw-r--r--lib/Target/PowerPC/PPCMCAsmInfo.cpp1
-rw-r--r--lib/Target/PowerPC/README.txt33
-rw-r--r--lib/Target/README.txt48
-rw-r--r--lib/Target/Sparc/SparcISelDAGToDAG.cpp19
-rw-r--r--lib/Target/SubtargetFeature.cpp3
-rw-r--r--lib/Target/SystemZ/SystemZISelDAGToDAG.cpp115
-rw-r--r--lib/Target/Target.cpp2
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp34
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp36
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp66
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.cpp28
-rw-r--r--lib/Target/X86/README-SSE.txt20
-rw-r--r--lib/Target/X86/README.txt83
-rw-r--r--lib/Target/X86/X86.td4
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp20
-rw-r--r--lib/Target/X86/X86FastISel.cpp16
-rw-r--r--lib/Target/X86/X86FloatingPoint.cpp16
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp157
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp241
-rw-r--r--lib/Target/X86/X86Instr64bit.td94
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp73
-rw-r--r--lib/Target/X86/X86InstrInfo.h10
-rw-r--r--lib/Target/X86/X86InstrInfo.td75
-rw-r--r--lib/Target/X86/X86InstrSSE.td10
-rw-r--r--lib/Target/X86/X86JITInfo.cpp2
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp9
-rw-r--r--lib/Target/X86/X86Subtarget.cpp3
-rw-r--r--lib/Target/X86/X86Subtarget.h7
-rw-r--r--lib/Target/XCore/XCoreISelDAGToDAG.cpp31
56 files changed, 1368 insertions, 1072 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 7cfa097..969c4a4 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -938,6 +938,35 @@ ARMBaseInstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
return false;
}
+/// Create a copy of a const pool value. Update CPI to the new index and return
+/// the label UID.
+static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) {
+ MachineConstantPool *MCP = MF.getConstantPool();
+ ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+
+ const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
+ assert(MCPE.isMachineConstantPoolEntry() &&
+ "Expecting a machine constantpool entry!");
+ ARMConstantPoolValue *ACPV =
+ static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
+
+ unsigned PCLabelId = AFI->createConstPoolEntryUId();
+ ARMConstantPoolValue *NewCPV = 0;
+ if (ACPV->isGlobalValue())
+ NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId,
+ ARMCP::CPValue, 4);
+ else if (ACPV->isExtSymbol())
+ NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(),
+ ACPV->getSymbol(), PCLabelId, 4);
+ else if (ACPV->isBlockAddress())
+ NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId,
+ ARMCP::CPBlockAddress, 4);
+ else
+ llvm_unreachable("Unexpected ARM constantpool value type!!");
+ CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment());
+ return PCLabelId;
+}
+
void ARMBaseInstrInfo::
reMaterialize(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
@@ -960,28 +989,8 @@ reMaterialize(MachineBasicBlock &MBB,
case ARM::tLDRpci_pic:
case ARM::t2LDRpci_pic: {
MachineFunction &MF = *MBB.getParent();
- ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
- MachineConstantPool *MCP = MF.getConstantPool();
unsigned CPI = Orig->getOperand(1).getIndex();
- const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
- assert(MCPE.isMachineConstantPoolEntry() &&
- "Expecting a machine constantpool entry!");
- ARMConstantPoolValue *ACPV =
- static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
- unsigned PCLabelId = AFI->createConstPoolEntryUId();
- ARMConstantPoolValue *NewCPV = 0;
- if (ACPV->isGlobalValue())
- NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId,
- ARMCP::CPValue, 4);
- else if (ACPV->isExtSymbol())
- NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(),
- ACPV->getSymbol(), PCLabelId, 4);
- else if (ACPV->isBlockAddress())
- NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId,
- ARMCP::CPBlockAddress, 4);
- else
- llvm_unreachable("Unexpected ARM constantpool value type!!");
- CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment());
+ unsigned PCLabelId = duplicateCPV(MF, CPI);
MachineInstrBuilder MIB = BuildMI(MBB, I, Orig->getDebugLoc(), get(Opcode),
DestReg)
.addConstantPoolIndex(CPI).addImm(PCLabelId);
@@ -994,6 +1003,22 @@ reMaterialize(MachineBasicBlock &MBB,
NewMI->getOperand(0).setSubReg(SubIdx);
}
+MachineInstr *
+ARMBaseInstrInfo::duplicate(MachineInstr *Orig, MachineFunction &MF) const {
+ MachineInstr *MI = TargetInstrInfoImpl::duplicate(Orig, MF);
+ switch(Orig->getOpcode()) {
+ case ARM::tLDRpci_pic:
+ case ARM::t2LDRpci_pic: {
+ unsigned CPI = Orig->getOperand(1).getIndex();
+ unsigned PCLabelId = duplicateCPV(MF, CPI);
+ Orig->getOperand(1).setIndex(CPI);
+ Orig->getOperand(2).setImm(PCLabelId);
+ break;
+ }
+ }
+ return MI;
+}
+
bool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0,
const MachineInstr *MI1,
const MachineRegisterInfo *MRI) const {
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h
index 78d9135..0d9d4a7 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -287,6 +287,8 @@ public:
const MachineInstr *Orig,
const TargetRegisterInfo *TRI) const;
+ MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const;
+
virtual bool isIdentical(const MachineInstr *MI, const MachineInstr *Other,
const MachineRegisterInfo *MRI) const;
};
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 7aebdf4..f1b6e1d 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -217,7 +217,8 @@ ARMBaseRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
? DarwinCalleeSavedRegClasses : CalleeSavedRegClasses;
}
-BitVector ARMBaseRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
+BitVector ARMBaseRegisterInfo::
+getReservedRegs(const MachineFunction &MF) const {
// FIXME: avoid re-calculating this everytime.
BitVector Reserved(getNumRegs());
Reserved.set(ARM::SP);
@@ -494,7 +495,8 @@ needsStackRealignment(const MachineFunction &MF) const {
!MFI->hasVarSizedObjects());
}
-bool ARMBaseRegisterInfo::cannotEliminateFrame(const MachineFunction &MF) const {
+bool ARMBaseRegisterInfo::
+cannotEliminateFrame(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
if (NoFramePointerElim && MFI->hasCalls())
return true;
@@ -523,7 +525,7 @@ static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
/// estimateRSStackSizeLimit - Look at each instruction that references stack
/// frames and return the stack size limit beyond which some of these
-/// instructions will require scratch register during their expansion later.
+/// instructions will require a scratch register during their expansion later.
unsigned
ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
unsigned Limit = (1 << 12) - 1;
@@ -547,6 +549,9 @@ ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
// When the stack offset is negative, we will end up using
// the i8 instructions instead.
return (1 << 8) - 1;
+
+ if (AddrMode == ARMII::AddrMode6)
+ return 0;
break; // At most one FI per instruction
}
}
@@ -557,7 +562,7 @@ ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
void
ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS) const {
+ RegScavenger *RS) const {
// This tells PEI to spill the FP as if it is any other callee-save register
// to take advantage the eliminateFrameIndex machinery. This also ensures it
// is spilled in the order specified by getCalleeSavedRegs() to make it easier
@@ -852,7 +857,7 @@ int ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
}
unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg,
- const MachineFunction &MF) const {
+ const MachineFunction &MF) const {
switch (Reg) {
default: break;
// Return 0 if either register of the pair is a special register.
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index d63f3e6..14a45b3 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -64,53 +64,53 @@ public:
return CurDAG->getTargetConstant(Imm, MVT::i32);
}
- SDNode *Select(SDValue Op);
+ SDNode *Select(SDNode *N);
virtual void InstructionSelect();
- bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A,
+ bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A,
SDValue &B, SDValue &C);
- bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Offset, SDValue &Opc);
- bool SelectAddrMode2Offset(SDValue Op, SDValue N,
+ bool SelectAddrMode2Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc);
- bool SelectAddrMode3(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Offset, SDValue &Opc);
- bool SelectAddrMode3Offset(SDValue Op, SDValue N,
+ bool SelectAddrMode3Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc);
- bool SelectAddrMode4(SDValue Op, SDValue N, SDValue &Addr,
+ bool SelectAddrMode4(SDNode *Op, SDValue N, SDValue &Addr,
SDValue &Mode);
- bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectAddrMode5(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Offset);
- bool SelectAddrMode6(SDValue Op, SDValue N, SDValue &Addr, SDValue &Update,
+ bool SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Update,
SDValue &Opc, SDValue &Align);
- bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset,
+ bool SelectAddrModePC(SDNode *Op, SDValue N, SDValue &Offset,
SDValue &Label);
- bool SelectThumbAddrModeRR(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectThumbAddrModeRR(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Offset);
- bool SelectThumbAddrModeRI5(SDValue Op, SDValue N, unsigned Scale,
+ bool SelectThumbAddrModeRI5(SDNode *Op, SDValue N, unsigned Scale,
SDValue &Base, SDValue &OffImm,
SDValue &Offset);
- bool SelectThumbAddrModeS1(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectThumbAddrModeS1(SDNode *Op, SDValue N, SDValue &Base,
SDValue &OffImm, SDValue &Offset);
- bool SelectThumbAddrModeS2(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectThumbAddrModeS2(SDNode *Op, SDValue N, SDValue &Base,
SDValue &OffImm, SDValue &Offset);
- bool SelectThumbAddrModeS4(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectThumbAddrModeS4(SDNode *Op, SDValue N, SDValue &Base,
SDValue &OffImm, SDValue &Offset);
- bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectThumbAddrModeSP(SDNode *Op, SDValue N, SDValue &Base,
SDValue &OffImm);
- bool SelectT2ShifterOperandReg(SDValue Op, SDValue N,
+ bool SelectT2ShifterOperandReg(SDNode *Op, SDValue N,
SDValue &BaseReg, SDValue &Opc);
- bool SelectT2AddrModeImm12(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectT2AddrModeImm12(SDNode *Op, SDValue N, SDValue &Base,
SDValue &OffImm);
- bool SelectT2AddrModeImm8(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectT2AddrModeImm8(SDNode *Op, SDValue N, SDValue &Base,
SDValue &OffImm);
- bool SelectT2AddrModeImm8Offset(SDValue Op, SDValue N,
+ bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N,
SDValue &OffImm);
- bool SelectT2AddrModeImm8s4(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectT2AddrModeImm8s4(SDNode *Op, SDValue N, SDValue &Base,
SDValue &OffImm);
- bool SelectT2AddrModeSoReg(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectT2AddrModeSoReg(SDNode *Op, SDValue N, SDValue &Base,
SDValue &OffReg, SDValue &ShImm);
// Include the pieces autogenerated from the target description.
@@ -119,48 +119,48 @@ public:
private:
/// SelectARMIndexedLoad - Indexed (pre/post inc/dec) load matching code for
/// ARM.
- SDNode *SelectARMIndexedLoad(SDValue Op);
- SDNode *SelectT2IndexedLoad(SDValue Op);
+ SDNode *SelectARMIndexedLoad(SDNode *N);
+ SDNode *SelectT2IndexedLoad(SDNode *N);
/// SelectDYN_ALLOC - Select dynamic alloc for Thumb.
- SDNode *SelectDYN_ALLOC(SDValue Op);
+ SDNode *SelectDYN_ALLOC(SDNode *N);
/// SelectVLD - Select NEON load intrinsics. NumVecs should
/// be 2, 3 or 4. The opcode arrays specify the instructions used for
/// loads of D registers and even subregs and odd subregs of Q registers.
/// For NumVecs == 2, QOpcodes1 is not used.
- SDNode *SelectVLD(SDValue Op, unsigned NumVecs, unsigned *DOpcodes,
+ SDNode *SelectVLD(SDNode *N, unsigned NumVecs, unsigned *DOpcodes,
unsigned *QOpcodes0, unsigned *QOpcodes1);
/// SelectVST - Select NEON store intrinsics. NumVecs should
/// be 2, 3 or 4. The opcode arrays specify the instructions used for
/// stores of D registers and even subregs and odd subregs of Q registers.
/// For NumVecs == 2, QOpcodes1 is not used.
- SDNode *SelectVST(SDValue Op, unsigned NumVecs, unsigned *DOpcodes,
+ SDNode *SelectVST(SDNode *N, unsigned NumVecs, unsigned *DOpcodes,
unsigned *QOpcodes0, unsigned *QOpcodes1);
/// SelectVLDSTLane - Select NEON load/store lane intrinsics. NumVecs should
/// be 2, 3 or 4. The opcode arrays specify the instructions used for
/// load/store of D registers and even subregs and odd subregs of Q registers.
- SDNode *SelectVLDSTLane(SDValue Op, bool IsLoad, unsigned NumVecs,
+ SDNode *SelectVLDSTLane(SDNode *N, bool IsLoad, unsigned NumVecs,
unsigned *DOpcodes, unsigned *QOpcodes0,
unsigned *QOpcodes1);
/// SelectV6T2BitfieldExtractOp - Select SBFX/UBFX instructions for ARM.
- SDNode *SelectV6T2BitfieldExtractOp(SDValue Op, unsigned Opc);
+ SDNode *SelectV6T2BitfieldExtractOp(SDNode *N, unsigned Opc);
/// SelectCMOVOp - Select CMOV instructions for ARM.
- SDNode *SelectCMOVOp(SDValue Op);
- SDNode *SelectT2CMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
+ SDNode *SelectCMOVOp(SDNode *N);
+ SDNode *SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR,
SDValue InFlag);
- SDNode *SelectARMCMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
+ SDNode *SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR,
SDValue InFlag);
- SDNode *SelectT2CMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
+ SDNode *SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR,
SDValue InFlag);
- SDNode *SelectARMCMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
+ SDNode *SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR,
SDValue InFlag);
@@ -206,7 +206,7 @@ void ARMDAGToDAGISel::InstructionSelect() {
CurDAG->RemoveDeadNodes();
}
-bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op,
+bool ARMDAGToDAGISel::SelectShifterOperandReg(SDNode *Op,
SDValue N,
SDValue &BaseReg,
SDValue &ShReg,
@@ -230,7 +230,7 @@ bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op,
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode2(SDNode *Op, SDValue N,
SDValue &Base, SDValue &Offset,
SDValue &Opc) {
if (N.getOpcode() == ISD::MUL) {
@@ -340,9 +340,9 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N,
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc) {
- unsigned Opcode = Op.getOpcode();
+ unsigned Opcode = Op->getOpcode();
ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
? cast<LoadSDNode>(Op)->getAddressingMode()
: cast<StoreSDNode>(Op)->getAddressingMode();
@@ -379,7 +379,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDValue Op, SDValue N,
}
-bool ARMDAGToDAGISel::SelectAddrMode3(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode3(SDNode *Op, SDValue N,
SDValue &Base, SDValue &Offset,
SDValue &Opc) {
if (N.getOpcode() == ISD::SUB) {
@@ -429,9 +429,9 @@ bool ARMDAGToDAGISel::SelectAddrMode3(SDValue Op, SDValue N,
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc) {
- unsigned Opcode = Op.getOpcode();
+ unsigned Opcode = Op->getOpcode();
ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
? cast<LoadSDNode>(Op)->getAddressingMode()
: cast<StoreSDNode>(Op)->getAddressingMode();
@@ -451,14 +451,14 @@ bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N,
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode4(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode4(SDNode *Op, SDValue N,
SDValue &Addr, SDValue &Mode) {
Addr = N;
Mode = CurDAG->getTargetConstant(0, MVT::i32);
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode5(SDNode *Op, SDValue N,
SDValue &Base, SDValue &Offset) {
if (N.getOpcode() != ISD::ADD) {
Base = N;
@@ -506,7 +506,7 @@ bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N,
return true;
}
-bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Op, SDValue N,
SDValue &Addr, SDValue &Update,
SDValue &Opc, SDValue &Align) {
Addr = N;
@@ -518,7 +518,7 @@ bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N,
return true;
}
-bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectAddrModePC(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Label) {
if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
Offset = N.getOperand(0);
@@ -530,10 +530,10 @@ bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N,
return false;
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDNode *Op, SDValue N,
SDValue &Base, SDValue &Offset){
// FIXME dl should come from the parent load or store, not the address
- DebugLoc dl = Op.getDebugLoc();
+ DebugLoc dl = Op->getDebugLoc();
if (N.getOpcode() != ISD::ADD) {
ConstantSDNode *NC = dyn_cast<ConstantSDNode>(N);
if (!NC || NC->getZExtValue() != 0)
@@ -549,7 +549,7 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op, SDValue N,
}
bool
-ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op, SDValue N,
+ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDNode *Op, SDValue N,
unsigned Scale, SDValue &Base,
SDValue &OffImm, SDValue &Offset) {
if (Scale == 4) {
@@ -605,25 +605,25 @@ ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op, SDValue N,
return true;
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDNode *Op, SDValue N,
SDValue &Base, SDValue &OffImm,
SDValue &Offset) {
return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset);
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDNode *Op, SDValue N,
SDValue &Base, SDValue &OffImm,
SDValue &Offset) {
return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset);
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDNode *Op, SDValue N,
SDValue &Base, SDValue &OffImm,
SDValue &Offset) {
return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset);
}
-bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDNode *Op, SDValue N,
SDValue &Base, SDValue &OffImm) {
if (N.getOpcode() == ISD::FrameIndex) {
int FI = cast<FrameIndexSDNode>(N)->getIndex();
@@ -659,7 +659,7 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N,
return false;
}
-bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDNode *Op, SDValue N,
SDValue &BaseReg,
SDValue &Opc) {
ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
@@ -679,7 +679,7 @@ bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue Op, SDValue N,
return false;
}
-bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDNode *Op, SDValue N,
SDValue &Base, SDValue &OffImm) {
// Match simple R + imm12 operands.
@@ -729,7 +729,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue Op, SDValue N,
return true;
}
-bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDNode *Op, SDValue N,
SDValue &Base, SDValue &OffImm) {
// Match simple R - imm8 operands.
if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::SUB) {
@@ -753,9 +753,9 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue Op, SDValue N,
return false;
}
-bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N,
SDValue &OffImm){
- unsigned Opcode = Op.getOpcode();
+ unsigned Opcode = Op->getOpcode();
ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
? cast<LoadSDNode>(Op)->getAddressingMode()
: cast<StoreSDNode>(Op)->getAddressingMode();
@@ -772,7 +772,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDValue Op, SDValue N,
return false;
}
-bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDNode *Op, SDValue N,
SDValue &Base, SDValue &OffImm) {
if (N.getOpcode() == ISD::ADD) {
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
@@ -798,7 +798,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm8s4(SDValue Op, SDValue N,
return false;
}
-bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue Op, SDValue N,
+bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDNode *Op, SDValue N,
SDValue &Base,
SDValue &OffReg, SDValue &ShImm) {
// (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12.
@@ -854,8 +854,8 @@ static inline SDValue getAL(SelectionDAG *CurDAG) {
return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32);
}
-SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) {
- LoadSDNode *LD = cast<LoadSDNode>(Op);
+SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDNode *N) {
+ LoadSDNode *LD = cast<LoadSDNode>(N);
ISD::MemIndexedMode AM = LD->getAddressingMode();
if (AM == ISD::UNINDEXED)
return NULL;
@@ -866,23 +866,23 @@ SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) {
unsigned Opcode = 0;
bool Match = false;
if (LoadedVT == MVT::i32 &&
- SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
+ SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) {
Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST;
Match = true;
} else if (LoadedVT == MVT::i16 &&
- SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
+ SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) {
Match = true;
Opcode = (LD->getExtensionType() == ISD::SEXTLOAD)
? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
: (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
} else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) {
if (LD->getExtensionType() == ISD::SEXTLOAD) {
- if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
+ if (SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) {
Match = true;
Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
}
} else {
- if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
+ if (SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) {
Match = true;
Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST;
}
@@ -894,15 +894,15 @@ SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDValue Op) {
SDValue Base = LD->getBasePtr();
SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG),
CurDAG->getRegister(0, MVT::i32), Chain };
- return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(), MVT::i32, MVT::i32,
+ return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32,
MVT::Other, Ops, 6);
}
return NULL;
}
-SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDValue Op) {
- LoadSDNode *LD = cast<LoadSDNode>(Op);
+SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDNode *N) {
+ LoadSDNode *LD = cast<LoadSDNode>(N);
ISD::MemIndexedMode AM = LD->getAddressingMode();
if (AM == ISD::UNINDEXED)
return NULL;
@@ -913,7 +913,7 @@ SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDValue Op) {
bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
unsigned Opcode = 0;
bool Match = false;
- if (SelectT2AddrModeImm8Offset(Op, LD->getOffset(), Offset)) {
+ if (SelectT2AddrModeImm8Offset(N, LD->getOffset(), Offset)) {
switch (LoadedVT.getSimpleVT().SimpleTy) {
case MVT::i32:
Opcode = isPre ? ARM::t2LDR_PRE : ARM::t2LDR_POST;
@@ -942,20 +942,19 @@ SDNode *ARMDAGToDAGISel::SelectT2IndexedLoad(SDValue Op) {
SDValue Base = LD->getBasePtr();
SDValue Ops[]= { Base, Offset, getAL(CurDAG),
CurDAG->getRegister(0, MVT::i32), Chain };
- return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(), MVT::i32, MVT::i32,
+ return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32,
MVT::Other, Ops, 5);
}
return NULL;
}
-SDNode *ARMDAGToDAGISel::SelectDYN_ALLOC(SDValue Op) {
- SDNode *N = Op.getNode();
+SDNode *ARMDAGToDAGISel::SelectDYN_ALLOC(SDNode *N) {
DebugLoc dl = N->getDebugLoc();
- EVT VT = Op.getValueType();
- SDValue Chain = Op.getOperand(0);
- SDValue Size = Op.getOperand(1);
- SDValue Align = Op.getOperand(2);
+ EVT VT = N->getValueType(0);
+ SDValue Chain = N->getOperand(0);
+ SDValue Size = N->getOperand(1);
+ SDValue Align = N->getOperand(2);
SDValue SP = CurDAG->getRegister(ARM::SP, MVT::i32);
int32_t AlignVal = cast<ConstantSDNode>(Align)->getSExtValue();
if (AlignVal < 0)
@@ -1030,15 +1029,14 @@ static EVT GetNEONSubregVT(EVT VT) {
}
}
-SDNode *ARMDAGToDAGISel::SelectVLD(SDValue Op, unsigned NumVecs,
+SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
unsigned *DOpcodes, unsigned *QOpcodes0,
unsigned *QOpcodes1) {
assert(NumVecs >=2 && NumVecs <= 4 && "VLD NumVecs out-of-range");
- SDNode *N = Op.getNode();
DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, MemUpdate, MemOpc, Align;
- if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align))
+ if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align))
return NULL;
SDValue Chain = N->getOperand(0);
@@ -1124,15 +1122,14 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDValue Op, unsigned NumVecs,
return NULL;
}
-SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs,
+SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
unsigned *DOpcodes, unsigned *QOpcodes0,
unsigned *QOpcodes1) {
assert(NumVecs >=2 && NumVecs <= 4 && "VST NumVecs out-of-range");
- SDNode *N = Op.getNode();
DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, MemUpdate, MemOpc, Align;
- if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align))
+ if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align))
return NULL;
SDValue Chain = N->getOperand(0);
@@ -1225,16 +1222,15 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs,
return NULL;
}
-SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDValue Op, bool IsLoad,
+SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
unsigned NumVecs, unsigned *DOpcodes,
unsigned *QOpcodes0,
unsigned *QOpcodes1) {
assert(NumVecs >=2 && NumVecs <= 4 && "VLDSTLane NumVecs out-of-range");
- SDNode *N = Op.getNode();
DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, MemUpdate, MemOpc, Align;
- if (!SelectAddrMode6(Op, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align))
+ if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, MemUpdate, MemOpc, Align))
return NULL;
SDValue Chain = N->getOperand(0);
@@ -1324,38 +1320,38 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDValue Op, bool IsLoad,
return NULL;
}
-SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDValue Op,
+SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N,
unsigned Opc) {
if (!Subtarget->hasV6T2Ops())
return NULL;
unsigned Shl_imm = 0;
- if (isOpcWithIntImmediate(Op.getOperand(0).getNode(), ISD::SHL, Shl_imm)) {
+ if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, Shl_imm)) {
assert(Shl_imm > 0 && Shl_imm < 32 && "bad amount in shift node!");
unsigned Srl_imm = 0;
- if (isInt32Immediate(Op.getOperand(1), Srl_imm)) {
+ if (isInt32Immediate(N->getOperand(1), Srl_imm)) {
assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!");
unsigned Width = 32 - Srl_imm;
int LSB = Srl_imm - Shl_imm;
if (LSB < 0)
return NULL;
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
- SDValue Ops[] = { Op.getOperand(0).getOperand(0),
+ SDValue Ops[] = { N->getOperand(0).getOperand(0),
CurDAG->getTargetConstant(LSB, MVT::i32),
CurDAG->getTargetConstant(Width, MVT::i32),
getAL(CurDAG), Reg0 };
- return CurDAG->SelectNodeTo(Op.getNode(), Opc, MVT::i32, Ops, 5);
+ return CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5);
}
}
return NULL;
}
SDNode *ARMDAGToDAGISel::
-SelectT2CMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
+SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) {
SDValue CPTmp0;
SDValue CPTmp1;
- if (SelectT2ShifterOperandReg(Op, TrueVal, CPTmp0, CPTmp1)) {
+ if (SelectT2ShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1)) {
unsigned SOVal = cast<ConstantSDNode>(CPTmp1)->getZExtValue();
unsigned SOShOp = ARM_AM::getSORegShOp(SOVal);
unsigned Opc = 0;
@@ -1372,27 +1368,27 @@ SelectT2CMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
CurDAG->getTargetConstant(ARM_AM::getSORegOffset(SOVal), MVT::i32);
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, CPTmp0, SOShImm, CC, CCR, InFlag };
- return CurDAG->SelectNodeTo(Op.getNode(), Opc, MVT::i32,Ops, 6);
+ return CurDAG->SelectNodeTo(N, Opc, MVT::i32,Ops, 6);
}
return 0;
}
SDNode *ARMDAGToDAGISel::
-SelectARMCMOVShiftOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
+SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) {
SDValue CPTmp0;
SDValue CPTmp1;
SDValue CPTmp2;
- if (SelectShifterOperandReg(Op, TrueVal, CPTmp0, CPTmp1, CPTmp2)) {
+ if (SelectShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1, CPTmp2)) {
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag };
- return CurDAG->SelectNodeTo(Op.getNode(), ARM::MOVCCs, MVT::i32, Ops, 7);
+ return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7);
}
return 0;
}
SDNode *ARMDAGToDAGISel::
-SelectT2CMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
+SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) {
ConstantSDNode *T = dyn_cast<ConstantSDNode>(TrueVal);
if (!T)
@@ -1402,14 +1398,14 @@ SelectT2CMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32);
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
- return CurDAG->SelectNodeTo(Op.getNode(),
+ return CurDAG->SelectNodeTo(N,
ARM::t2MOVCCi, MVT::i32, Ops, 5);
}
return 0;
}
SDNode *ARMDAGToDAGISel::
-SelectARMCMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
+SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) {
ConstantSDNode *T = dyn_cast<ConstantSDNode>(TrueVal);
if (!T)
@@ -1419,19 +1415,19 @@ SelectARMCMOVSoImmOp(SDValue Op, SDValue FalseVal, SDValue TrueVal,
SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32);
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
- return CurDAG->SelectNodeTo(Op.getNode(),
+ return CurDAG->SelectNodeTo(N,
ARM::MOVCCi, MVT::i32, Ops, 5);
}
return 0;
}
-SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDValue Op) {
- EVT VT = Op.getValueType();
- SDValue FalseVal = Op.getOperand(0);
- SDValue TrueVal = Op.getOperand(1);
- SDValue CC = Op.getOperand(2);
- SDValue CCR = Op.getOperand(3);
- SDValue InFlag = Op.getOperand(4);
+SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDNode *N) {
+ EVT VT = N->getValueType(0);
+ SDValue FalseVal = N->getOperand(0);
+ SDValue TrueVal = N->getOperand(1);
+ SDValue CC = N->getOperand(2);
+ SDValue CCR = N->getOperand(3);
+ SDValue InFlag = N->getOperand(4);
assert(CC.getOpcode() == ISD::Constant);
assert(CCR.getOpcode() == ISD::Register);
ARMCC::CondCodes CCVal =
@@ -1445,18 +1441,18 @@ SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDValue Op) {
SDValue CPTmp1;
SDValue CPTmp2;
if (Subtarget->isThumb()) {
- SDNode *Res = SelectT2CMOVShiftOp(Op, FalseVal, TrueVal,
+ SDNode *Res = SelectT2CMOVShiftOp(N, FalseVal, TrueVal,
CCVal, CCR, InFlag);
if (!Res)
- Res = SelectT2CMOVShiftOp(Op, TrueVal, FalseVal,
+ Res = SelectT2CMOVShiftOp(N, TrueVal, FalseVal,
ARMCC::getOppositeCondition(CCVal), CCR, InFlag);
if (Res)
return Res;
} else {
- SDNode *Res = SelectARMCMOVShiftOp(Op, FalseVal, TrueVal,
+ SDNode *Res = SelectARMCMOVShiftOp(N, FalseVal, TrueVal,
CCVal, CCR, InFlag);
if (!Res)
- Res = SelectARMCMOVShiftOp(Op, TrueVal, FalseVal,
+ Res = SelectARMCMOVShiftOp(N, TrueVal, FalseVal,
ARMCC::getOppositeCondition(CCVal), CCR, InFlag);
if (Res)
return Res;
@@ -1469,18 +1465,18 @@ SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDValue Op) {
// (so_imm:i32 (imm:i32):$true), (imm:i32):$cc)
// Pattern complexity = 10 cost = 1 size = 0
if (Subtarget->isThumb()) {
- SDNode *Res = SelectT2CMOVSoImmOp(Op, FalseVal, TrueVal,
+ SDNode *Res = SelectT2CMOVSoImmOp(N, FalseVal, TrueVal,
CCVal, CCR, InFlag);
if (!Res)
- Res = SelectT2CMOVSoImmOp(Op, TrueVal, FalseVal,
+ Res = SelectT2CMOVSoImmOp(N, TrueVal, FalseVal,
ARMCC::getOppositeCondition(CCVal), CCR, InFlag);
if (Res)
return Res;
} else {
- SDNode *Res = SelectARMCMOVSoImmOp(Op, FalseVal, TrueVal,
+ SDNode *Res = SelectARMCMOVSoImmOp(N, FalseVal, TrueVal,
CCVal, CCR, InFlag);
if (!Res)
- Res = SelectARMCMOVSoImmOp(Op, TrueVal, FalseVal,
+ Res = SelectARMCMOVSoImmOp(N, TrueVal, FalseVal,
ARMCC::getOppositeCondition(CCVal), CCR, InFlag);
if (Res)
return Res;
@@ -1514,11 +1510,10 @@ SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDValue Op) {
Opc = ARM::VMOVDcc;
break;
}
- return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5);
+ return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5);
}
-SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
- SDNode *N = Op.getNode();
+SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
DebugLoc dl = N->getDebugLoc();
if (N->isMachineOpcode())
@@ -1569,7 +1564,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
ResNode=CurDAG->getMachineNode(ARM::LDRcp, dl, MVT::i32, MVT::Other,
Ops, 6);
}
- ReplaceUses(Op, SDValue(ResNode, 0));
+ ReplaceUses(SDValue(N, 0), SDValue(ResNode, 0));
return NULL;
}
@@ -1593,28 +1588,28 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
}
}
case ARMISD::DYN_ALLOC:
- return SelectDYN_ALLOC(Op);
+ return SelectDYN_ALLOC(N);
case ISD::SRL:
- if (SDNode *I = SelectV6T2BitfieldExtractOp(Op,
+ if (SDNode *I = SelectV6T2BitfieldExtractOp(N,
Subtarget->isThumb() ? ARM::t2UBFX : ARM::UBFX))
return I;
break;
case ISD::SRA:
- if (SDNode *I = SelectV6T2BitfieldExtractOp(Op,
+ if (SDNode *I = SelectV6T2BitfieldExtractOp(N,
Subtarget->isThumb() ? ARM::t2SBFX : ARM::SBFX))
return I;
break;
case ISD::MUL:
if (Subtarget->isThumb1Only())
break;
- if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
+ if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
unsigned RHSV = C->getZExtValue();
if (!RHSV) break;
if (isPowerOf2_32(RHSV-1)) { // 2^n+1?
unsigned ShImm = Log2_32(RHSV-1);
if (ShImm >= 32)
break;
- SDValue V = Op.getOperand(0);
+ SDValue V = N->getOperand(0);
ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm);
SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32);
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
@@ -1630,7 +1625,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
unsigned ShImm = Log2_32(RHSV+1);
if (ShImm >= 32)
break;
- SDValue V = Op.getOperand(0);
+ SDValue V = N->getOperand(0);
ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, ShImm);
SDValue ShImmOp = CurDAG->getTargetConstant(ShImm, MVT::i32);
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
@@ -1650,7 +1645,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
// are entirely contributed by c2 and lower 16-bits are entirely contributed
// by x. That's equal to (or (and x, 0xffff), (and c1, 0xffff0000)).
// Select it to: "movt x, ((c1 & 0xffff) >> 16)
- EVT VT = Op.getValueType();
+ EVT VT = N->getValueType(0);
if (VT != MVT::i32)
break;
unsigned Opc = (Subtarget->isThumb() && Subtarget->hasThumb2())
@@ -1658,7 +1653,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
: (Subtarget->hasV6T2Ops() ? ARM::MOVTi16 : 0);
if (!Opc)
break;
- SDValue N0 = Op.getOperand(0), N1 = Op.getOperand(1);
+ SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
if (!N1C)
break;
@@ -1683,18 +1678,18 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
}
case ARMISD::VMOVRRD:
return CurDAG->getMachineNode(ARM::VMOVRRD, dl, MVT::i32, MVT::i32,
- Op.getOperand(0), getAL(CurDAG),
+ N->getOperand(0), getAL(CurDAG),
CurDAG->getRegister(0, MVT::i32));
case ISD::UMUL_LOHI: {
if (Subtarget->isThumb1Only())
break;
if (Subtarget->isThumb()) {
- SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
CurDAG->getRegister(0, MVT::i32) };
return CurDAG->getMachineNode(ARM::t2UMULL, dl, MVT::i32, MVT::i32, Ops,4);
} else {
- SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
CurDAG->getRegister(0, MVT::i32) };
return CurDAG->getMachineNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5);
@@ -1704,11 +1699,11 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
if (Subtarget->isThumb1Only())
break;
if (Subtarget->isThumb()) {
- SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) };
return CurDAG->getMachineNode(ARM::t2SMULL, dl, MVT::i32, MVT::i32, Ops,4);
} else {
- SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
CurDAG->getRegister(0, MVT::i32) };
return CurDAG->getMachineNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5);
@@ -1717,9 +1712,9 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
case ISD::LOAD: {
SDNode *ResNode = 0;
if (Subtarget->isThumb() && Subtarget->hasThumb2())
- ResNode = SelectT2IndexedLoad(Op);
+ ResNode = SelectT2IndexedLoad(N);
else
- ResNode = SelectARMIndexedLoad(Op);
+ ResNode = SelectARMIndexedLoad(N);
if (ResNode)
return ResNode;
// Other cases are autogenerated.
@@ -1740,11 +1735,11 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
unsigned Opc = Subtarget->isThumb() ?
((Subtarget->hasThumb2()) ? ARM::t2Bcc : ARM::tBcc) : ARM::Bcc;
- SDValue Chain = Op.getOperand(0);
- SDValue N1 = Op.getOperand(1);
- SDValue N2 = Op.getOperand(2);
- SDValue N3 = Op.getOperand(3);
- SDValue InFlag = Op.getOperand(4);
+ SDValue Chain = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
+ SDValue N3 = N->getOperand(3);
+ SDValue InFlag = N->getOperand(4);
assert(N1.getOpcode() == ISD::BasicBlock);
assert(N2.getOpcode() == ISD::Constant);
assert(N3.getOpcode() == ISD::Register);
@@ -1756,23 +1751,23 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other,
MVT::Flag, Ops, 5);
Chain = SDValue(ResNode, 0);
- if (Op.getNode()->getNumValues() == 2) {
+ if (N->getNumValues() == 2) {
InFlag = SDValue(ResNode, 1);
- ReplaceUses(SDValue(Op.getNode(), 1), InFlag);
+ ReplaceUses(SDValue(N, 1), InFlag);
}
- ReplaceUses(SDValue(Op.getNode(), 0),
+ ReplaceUses(SDValue(N, 0),
SDValue(Chain.getNode(), Chain.getResNo()));
return NULL;
}
case ARMISD::CMOV:
- return SelectCMOVOp(Op);
+ return SelectCMOVOp(N);
case ARMISD::CNEG: {
- EVT VT = Op.getValueType();
- SDValue N0 = Op.getOperand(0);
- SDValue N1 = Op.getOperand(1);
- SDValue N2 = Op.getOperand(2);
- SDValue N3 = Op.getOperand(3);
- SDValue InFlag = Op.getOperand(4);
+ EVT VT = N->getValueType(0);
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
+ SDValue N3 = N->getOperand(3);
+ SDValue InFlag = N->getOperand(4);
assert(N2.getOpcode() == ISD::Constant);
assert(N3.getOpcode() == ISD::Register);
@@ -1791,7 +1786,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
Opc = ARM::VNEGDcc;
break;
}
- return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5);
+ return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5);
}
case ARMISD::VZIP: {
@@ -1863,7 +1858,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
unsigned DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16,
ARM::VLD2d32, ARM::VLD2d64 };
unsigned QOpcodes[] = { ARM::VLD2q8, ARM::VLD2q16, ARM::VLD2q32 };
- return SelectVLD(Op, 2, DOpcodes, QOpcodes, 0);
+ return SelectVLD(N, 2, DOpcodes, QOpcodes, 0);
}
case Intrinsic::arm_neon_vld3: {
@@ -1871,7 +1866,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
ARM::VLD3d32, ARM::VLD3d64 };
unsigned QOpcodes0[] = { ARM::VLD3q8a, ARM::VLD3q16a, ARM::VLD3q32a };
unsigned QOpcodes1[] = { ARM::VLD3q8b, ARM::VLD3q16b, ARM::VLD3q32b };
- return SelectVLD(Op, 3, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVLD(N, 3, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vld4: {
@@ -1879,35 +1874,35 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
ARM::VLD4d32, ARM::VLD4d64 };
unsigned QOpcodes0[] = { ARM::VLD4q8a, ARM::VLD4q16a, ARM::VLD4q32a };
unsigned QOpcodes1[] = { ARM::VLD4q8b, ARM::VLD4q16b, ARM::VLD4q32b };
- return SelectVLD(Op, 4, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVLD(N, 4, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vld2lane: {
unsigned DOpcodes[] = { ARM::VLD2LNd8, ARM::VLD2LNd16, ARM::VLD2LNd32 };
unsigned QOpcodes0[] = { ARM::VLD2LNq16a, ARM::VLD2LNq32a };
unsigned QOpcodes1[] = { ARM::VLD2LNq16b, ARM::VLD2LNq32b };
- return SelectVLDSTLane(Op, true, 2, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVLDSTLane(N, true, 2, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vld3lane: {
unsigned DOpcodes[] = { ARM::VLD3LNd8, ARM::VLD3LNd16, ARM::VLD3LNd32 };
unsigned QOpcodes0[] = { ARM::VLD3LNq16a, ARM::VLD3LNq32a };
unsigned QOpcodes1[] = { ARM::VLD3LNq16b, ARM::VLD3LNq32b };
- return SelectVLDSTLane(Op, true, 3, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVLDSTLane(N, true, 3, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vld4lane: {
unsigned DOpcodes[] = { ARM::VLD4LNd8, ARM::VLD4LNd16, ARM::VLD4LNd32 };
unsigned QOpcodes0[] = { ARM::VLD4LNq16a, ARM::VLD4LNq32a };
unsigned QOpcodes1[] = { ARM::VLD4LNq16b, ARM::VLD4LNq32b };
- return SelectVLDSTLane(Op, true, 4, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVLDSTLane(N, true, 4, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vst2: {
unsigned DOpcodes[] = { ARM::VST2d8, ARM::VST2d16,
ARM::VST2d32, ARM::VST2d64 };
unsigned QOpcodes[] = { ARM::VST2q8, ARM::VST2q16, ARM::VST2q32 };
- return SelectVST(Op, 2, DOpcodes, QOpcodes, 0);
+ return SelectVST(N, 2, DOpcodes, QOpcodes, 0);
}
case Intrinsic::arm_neon_vst3: {
@@ -1915,7 +1910,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
ARM::VST3d32, ARM::VST3d64 };
unsigned QOpcodes0[] = { ARM::VST3q8a, ARM::VST3q16a, ARM::VST3q32a };
unsigned QOpcodes1[] = { ARM::VST3q8b, ARM::VST3q16b, ARM::VST3q32b };
- return SelectVST(Op, 3, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVST(N, 3, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vst4: {
@@ -1923,34 +1918,34 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
ARM::VST4d32, ARM::VST4d64 };
unsigned QOpcodes0[] = { ARM::VST4q8a, ARM::VST4q16a, ARM::VST4q32a };
unsigned QOpcodes1[] = { ARM::VST4q8b, ARM::VST4q16b, ARM::VST4q32b };
- return SelectVST(Op, 4, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVST(N, 4, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vst2lane: {
unsigned DOpcodes[] = { ARM::VST2LNd8, ARM::VST2LNd16, ARM::VST2LNd32 };
unsigned QOpcodes0[] = { ARM::VST2LNq16a, ARM::VST2LNq32a };
unsigned QOpcodes1[] = { ARM::VST2LNq16b, ARM::VST2LNq32b };
- return SelectVLDSTLane(Op, false, 2, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVLDSTLane(N, false, 2, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vst3lane: {
unsigned DOpcodes[] = { ARM::VST3LNd8, ARM::VST3LNd16, ARM::VST3LNd32 };
unsigned QOpcodes0[] = { ARM::VST3LNq16a, ARM::VST3LNq32a };
unsigned QOpcodes1[] = { ARM::VST3LNq16b, ARM::VST3LNq32b };
- return SelectVLDSTLane(Op, false, 3, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVLDSTLane(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1);
}
case Intrinsic::arm_neon_vst4lane: {
unsigned DOpcodes[] = { ARM::VST4LNd8, ARM::VST4LNd16, ARM::VST4LNd32 };
unsigned QOpcodes0[] = { ARM::VST4LNq16a, ARM::VST4LNq32a };
unsigned QOpcodes1[] = { ARM::VST4LNq16b, ARM::VST4LNq32b };
- return SelectVLDSTLane(Op, false, 4, DOpcodes, QOpcodes0, QOpcodes1);
+ return SelectVLDSTLane(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1);
}
}
}
}
- return SelectCode(Op);
+ return SelectCode(N);
}
bool ARMDAGToDAGISel::
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 334baae..7b62c00 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -3130,6 +3130,9 @@ ARMTargetLowering::EmitAtomicCmpSwap(MachineInstr *MI,
// exitMBB:
// ...
BB = exitMBB;
+
+ MF->DeleteMachineInstr(MI); // The instruction is gone now.
+
return BB;
}
@@ -3140,7 +3143,7 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
const BasicBlock *LLVM_BB = BB->getBasicBlock();
- MachineFunction *F = BB->getParent();
+ MachineFunction *MF = BB->getParent();
MachineFunction::iterator It = BB;
++It;
@@ -3155,7 +3158,7 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
default: llvm_unreachable("unsupported size for AtomicCmpSwap!");
case 1:
ldrOpc = isThumb2 ? ARM::t2LDREXB : ARM::LDREXB;
- strOpc = isThumb2 ? ARM::t2LDREXB : ARM::STREXB;
+ strOpc = isThumb2 ? ARM::t2STREXB : ARM::STREXB;
break;
case 2:
ldrOpc = isThumb2 ? ARM::t2LDREXH : ARM::LDREXH;
@@ -3167,13 +3170,13 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
break;
}
- MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
- F->insert(It, loopMBB);
- F->insert(It, exitMBB);
+ MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
+ MF->insert(It, loopMBB);
+ MF->insert(It, exitMBB);
exitMBB->transferSuccessors(BB);
- MachineRegisterInfo &RegInfo = F->getRegInfo();
+ MachineRegisterInfo &RegInfo = MF->getRegInfo();
unsigned scratch = RegInfo.createVirtualRegister(ARM::GPRRegisterClass);
unsigned scratch2 = (!BinOpcode) ? incr :
RegInfo.createVirtualRegister(ARM::GPRRegisterClass);
@@ -3216,7 +3219,7 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
// ...
BB = exitMBB;
- F->DeleteMachineInstr(MI); // The instruction is gone now.
+ MF->DeleteMachineInstr(MI); // The instruction is gone now.
return BB;
}
@@ -4258,10 +4261,10 @@ std::pair<unsigned, const TargetRegisterClass*>
ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
EVT VT) const {
if (Constraint.size() == 1) {
- // GCC RS6000 Constraint Letters
+ // GCC ARM Constraint Letters
switch (Constraint[0]) {
case 'l':
- if (Subtarget->isThumb1Only())
+ if (Subtarget->isThumb())
return std::make_pair(0U, ARM::tGPRRegisterClass);
else
return std::make_pair(0U, ARM::GPRRegisterClass);
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index da8b373..f67e74a 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -127,8 +127,8 @@ def IsThumb2 : Predicate<"Subtarget->isThumb2()">;
def IsARM : Predicate<"!Subtarget->isThumb()">;
def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">;
def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
-def CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">;
-def CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">;
+def CarryDefIsUnused : Predicate<"!N->hasAnyUseOfValue(1)">;
+def CarryDefIsUsed : Predicate<"N->hasAnyUseOfValue(1)">;
// FIXME: Eventually this will be just "hasV6T2Ops".
def UseMovt : Predicate<"Subtarget->useMovt()">;
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index 34d7d8f..603ccf5 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -113,7 +113,7 @@ def t_addrmode_s1 : Operand<i32>,
def t_addrmode_sp : Operand<i32>,
ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
let PrintMethod = "printThumbAddrModeSPOperand";
- let MIOperandInfo = (ops JustSP:$base, i32imm:$offsimm);
+ let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}
//===----------------------------------------------------------------------===//
@@ -208,9 +208,8 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst",
[(brind GPR:$dst)]>,
- T1Special<{1,0,?,?}> {
- // <Rd> = pc
- let Inst{7} = 1;
+ T1Special<{1,0,1,1}> {
+ // <Rd> = Inst{7:2-0} = pc
let Inst{2-0} = 0b111;
}
}
@@ -342,16 +341,28 @@ def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr,
"ldr", "\t$dst, $addr",
[(set tGPR:$dst, (load t_addrmode_s4:$addr))]>,
T1LdSt<0b100>;
+def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr,
+ "ldr", "\t$dst, $addr",
+ []>,
+ T1LdSt4Imm<{1,?,?}>;
def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr,
"ldrb", "\t$dst, $addr",
[(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>,
T1LdSt<0b110>;
+def tLDRBi: T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr,
+ "ldrb", "\t$dst, $addr",
+ []>,
+ T1LdSt1Imm<{1,?,?}>;
def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr,
"ldrh", "\t$dst, $addr",
[(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>,
T1LdSt<0b101>;
+def tLDRHi: T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr,
+ "ldrh", "\t$dst, $addr",
+ []>,
+ T1LdSt2Imm<{1,?,?}>;
let AddedComplexity = 10 in
def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr,
@@ -397,16 +408,28 @@ def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer,
"str", "\t$src, $addr",
[(store tGPR:$src, t_addrmode_s4:$addr)]>,
T1LdSt<0b000>;
+def tSTRi: T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer,
+ "str", "\t$src, $addr",
+ []>,
+ T1LdSt4Imm<{0,?,?}>;
def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer,
"strb", "\t$src, $addr",
[(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>,
T1LdSt<0b010>;
+def tSTRBi: T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer,
+ "strb", "\t$src, $addr",
+ []>,
+ T1LdSt1Imm<{0,?,?}>;
def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer,
"strh", "\t$src, $addr",
[(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>,
T1LdSt<0b001>;
+def tSTRHi: T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer,
+ "strh", "\t$src, $addr",
+ []>,
+ T1LdSt2Imm<{0,?,?}>;
def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
"str", "\t$src, $addr",
@@ -748,7 +771,7 @@ let usesCustomInserter = 1 in // Expanded after instruction selection.
// 16-bit movcc in IT blocks for Thumb2.
def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr,
"mov", "\t$dst, $rhs", []>,
- T1Special<{1,0,?,?}>;
+ T1Special<{1,0,1,1}>;
def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi,
"mov", "\t$dst, $rhs", []>,
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 6f20ed4..769df7e 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -360,8 +360,8 @@ multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode,
opc, ".w\t$dst, $lhs, $rhs",
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]> {
let Inst{31-27} = 0b11101;
- let Inst{24} = 1;
let Inst{26-25} = 0b01;
+ let Inst{24} = 1;
let Inst{23-21} = op23_21;
let Inst{20} = 0; // The S bit.
}
diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index b13f98a..b78b95b 100644
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -740,6 +740,18 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB,
/// isMemoryOp - Returns true if instruction is a memory operations (that this
/// pass is capable of operating on).
static bool isMemoryOp(const MachineInstr *MI) {
+ if (MI->hasOneMemOperand()) {
+ const MachineMemOperand *MMO = *MI->memoperands_begin();
+
+ // Don't touch volatile memory accesses - we may be changing their order.
+ if (MMO->isVolatile())
+ return false;
+
+ // Unaligned ldr/str is emulated by some kernels, but unaligned ldm/stm is not.
+ if (MMO->getAlignment() < 4)
+ return false;
+ }
+
int Opcode = MI->getOpcode();
switch (Opcode) {
default: break;
diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td
index 9fbde81..d393e8d 100644
--- a/lib/Target/ARM/ARMRegisterInfo.td
+++ b/lib/Target/ARM/ARMRegisterInfo.td
@@ -367,19 +367,6 @@ def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
// Condition code registers.
def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>;
-// Just the stack pointer (for tSTRspi and friends).
-def JustSP : RegisterClass<"ARM", [i32], 32, [SP]> {
- let MethodProtos = [{
- iterator allocation_order_end(const MachineFunction &MF) const;
- }];
- let MethodBodies = [{
- JustSPClass::iterator
- JustSPClass::allocation_order_end(const MachineFunction &MF) const {
- return allocation_order_begin(MF);
- }
- }];
-}
-
//===----------------------------------------------------------------------===//
// Subregister Set Definitions... now that we have all of the pieces, define the
// sub registers for each register.
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index ed4667b..132738e 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmLexer.h"
#include "llvm/MC/MCAsmParser.h"
+#include "llvm/MC/MCParsedAsmOperand.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
@@ -78,7 +79,7 @@ private:
/// @name Auto-generated Match Functions
/// {
- bool MatchInstruction(SmallVectorImpl<ARMOperand> &Operands,
+ bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCInst &Inst);
/// MatchRegisterName - Match the given string to a register name and return
@@ -94,14 +95,15 @@ public:
ARMAsmParser(const Target &T, MCAsmParser &_Parser)
: TargetAsmParser(T), Parser(_Parser) {}
- virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst);
+ virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands);
virtual bool ParseDirective(AsmToken DirectiveID);
};
/// ARMOperand - Instances of this class represent a parsed ARM machine
/// instruction.
-struct ARMOperand {
+struct ARMOperand : public MCParsedAsmOperand {
enum {
Token,
Register,
@@ -515,9 +517,10 @@ int ARMAsmParser::MatchRegisterName(const StringRef &Name) {
}
/// A hack to allow some testing, to be replaced by a real table gen version.
-bool ARMAsmParser::MatchInstruction(SmallVectorImpl<ARMOperand> &Operands,
- MCInst &Inst) {
- struct ARMOperand Op0 = Operands[0];
+bool ARMAsmParser::
+MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ MCInst &Inst) {
+ ARMOperand &Op0 = *(ARMOperand*)Operands[0];
assert(Op0.Kind == ARMOperand::Token && "First operand not a Token");
const StringRef &Mnemonic = Op0.getToken();
if (Mnemonic == "add" ||
@@ -578,33 +581,27 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) {
}
/// Parse an arm instruction mnemonic followed by its operands.
-bool ARMAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) {
- SmallVector<ARMOperand, 7> Operands;
-
- Operands.push_back(ARMOperand::CreateToken(Name));
+bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ Operands.push_back(new ARMOperand(ARMOperand::CreateToken(Name)));
SMLoc Loc = getLexer().getTok().getLoc();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
- Operands.push_back(ARMOperand());
- if (ParseOperand(Operands.back()))
- return true;
+ ARMOperand Op;
+ if (ParseOperand(Op)) return true;
+ Operands.push_back(new ARMOperand(Op));
while (getLexer().is(AsmToken::Comma)) {
getLexer().Lex(); // Eat the comma.
// Parse and remember the operand.
- Operands.push_back(ARMOperand());
- if (ParseOperand(Operands.back()))
- return true;
+ if (ParseOperand(Op)) return true;
+ Operands.push_back(new ARMOperand(Op));
}
}
- if (!MatchInstruction(Operands, Inst))
- return false;
-
- Error(Loc, "ARMAsmParser::ParseInstruction only partly implemented");
- return true;
+ return false;
}
/// ParseDirective parses the arm specific directives
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 931d8df..2d13533 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -175,16 +175,16 @@ namespace {
printDataDirective(MCPV->getType());
ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
- std::string Name;
+ SmallString<128> TmpNameStr;
if (ACPV->isLSDA()) {
- SmallString<16> LSDAName;
- raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() <<
+ raw_svector_ostream(TmpNameStr) << MAI->getPrivateGlobalPrefix() <<
"_LSDA_" << getFunctionNumber();
- Name = LSDAName.str();
+ O << TmpNameStr.str();
} else if (ACPV->isBlockAddress()) {
- Name = GetBlockAddressSymbol(ACPV->getBlockAddress())->getName();
+ O << GetBlockAddressSymbol(ACPV->getBlockAddress())->getName();
} else if (ACPV->isGlobalValue()) {
+ std::string Name;
GlobalValue *GV = ACPV->getGV();
bool isIndirect = Subtarget->isTargetDarwin() &&
Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
@@ -201,16 +201,16 @@ namespace {
GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
MMIMachO.getGVStubEntry(Sym);
if (StubSym == 0) {
- SmallString<128> NameStr;
- Mang->getNameWithPrefix(NameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+ Mang->getNameWithPrefix(TmpNameStr, GV, false);
+ StubSym = OutContext.GetOrCreateSymbol(TmpNameStr.str());
}
}
+ O << Name;
} else {
assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
- Name = Mang->makeNameProper(ACPV->getSymbol());
+ Mang->getNameWithPrefix(TmpNameStr, ACPV->getSymbol());
+ OutContext.GetOrCreateSymbol(TmpNameStr.str())->print(O, MAI);
}
- O << Name;
if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
if (ACPV->getPCAdjustment() != 0) {
@@ -392,9 +392,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
}
case MachineOperand::MO_ExternalSymbol: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
- std::string Name = Mang->makeNameProper(MO.getSymbolName());
-
- O << Name;
+ SmallString<128> NameStr;
+ Mang->getNameWithPrefix(NameStr, MO.getSymbolName());
+ OutContext.GetOrCreateSymbol(NameStr.str())->print(O, MAI);
+
if (isCallOp && Subtarget->isTargetELF() &&
TM.getRelocationModel() == Reloc::PIC_)
O << "(PLT)";
diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
index 5b0a89d..eaefef9 100644
--- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
+++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
@@ -157,7 +157,7 @@ namespace {
// Select - Convert the specified operand from a target-independent to a
// target-specific node if it hasn't already been changed.
- SDNode *Select(SDValue Op);
+ SDNode *Select(SDNode *N);
/// InstructionSelect - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
@@ -202,7 +202,7 @@ private:
SDNode *getGlobalBaseReg();
SDNode *getGlobalRetAddr();
- void SelectCALL(SDValue Op);
+ void SelectCALL(SDNode *Op);
};
}
@@ -232,8 +232,7 @@ void AlphaDAGToDAGISel::InstructionSelect() {
// Select - Convert the specified operand from a target-independent to a
// target-specific node if it hasn't already been changed.
-SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
- SDNode *N = Op.getNode();
+SDNode *AlphaDAGToDAGISel::Select(SDNode *N) {
if (N->isMachineOpcode()) {
return NULL; // Already selected.
}
@@ -242,7 +241,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
switch (N->getOpcode()) {
default: break;
case AlphaISD::CALL:
- SelectCALL(Op);
+ SelectCALL(N);
return NULL;
case ISD::FrameIndex: {
@@ -258,9 +257,9 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
case AlphaISD::DivCall: {
SDValue Chain = CurDAG->getEntryNode();
- SDValue N0 = Op.getOperand(0);
- SDValue N1 = Op.getOperand(1);
- SDValue N2 = Op.getOperand(2);
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R24, N1,
SDValue(0,0));
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R25, N2,
@@ -287,7 +286,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
if (uval == 0) {
SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
Alpha::R31, MVT::i64);
- ReplaceUses(Op, Result);
+ ReplaceUses(SDValue(N, 0), Result);
return NULL;
}
@@ -415,13 +414,12 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) {
}
- return SelectCode(Op);
+ return SelectCode(N);
}
-void AlphaDAGToDAGISel::SelectCALL(SDValue Op) {
+void AlphaDAGToDAGISel::SelectCALL(SDNode *N) {
//TODO: add flag stuff to prevent nondeturministic breakage!
- SDNode *N = Op.getNode();
SDValue Chain = N->getOperand(0);
SDValue Addr = N->getOperand(1);
SDValue InFlag = N->getOperand(N->getNumOperands() - 1);
@@ -442,8 +440,8 @@ void AlphaDAGToDAGISel::SelectCALL(SDValue Op) {
}
InFlag = Chain.getValue(1);
- ReplaceUses(Op.getValue(0), Chain);
- ReplaceUses(Op.getValue(1), InFlag);
+ ReplaceUses(SDValue(N, 0), Chain);
+ ReplaceUses(SDValue(N, 1), InFlag);
}
diff --git a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
index 917f7f5..0bd94d4 100644
--- a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
+++ b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
@@ -25,12 +25,14 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
@@ -179,9 +181,12 @@ void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << Mang->getMangledName(MO.getGlobal());
printOffset(MO.getOffset());
break;
- case MachineOperand::MO_ExternalSymbol:
- O << Mang->makeNameProper(MO.getSymbolName());
+ case MachineOperand::MO_ExternalSymbol: {
+ SmallString<60> NameStr;
+ Mang->getNameWithPrefix(NameStr, MO.getSymbolName());
+ OutContext.GetOrCreateSymbol(NameStr.str())->print(O, MAI);
break;
+ }
case MachineOperand::MO_ConstantPoolIndex:
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
<< MO.getIndex();
diff --git a/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp b/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp
index 2217af4..e1b6008 100644
--- a/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp
+++ b/lib/Target/Blackfin/BlackfinISelDAGToDAG.cpp
@@ -51,8 +51,8 @@ namespace {
#include "BlackfinGenDAGISel.inc"
private:
- SDNode *Select(SDValue Op);
- bool SelectADDRspii(SDValue Op, SDValue Addr,
+ SDNode *Select(SDNode *N);
+ bool SelectADDRspii(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Offset);
// Walk the DAG after instruction selection, fixing register class issues.
@@ -82,8 +82,7 @@ void BlackfinDAGToDAGISel::InstructionSelect() {
FixRegisterClasses(*CurDAG);
}
-SDNode *BlackfinDAGToDAGISel::Select(SDValue Op) {
- SDNode *N = Op.getNode();
+SDNode *BlackfinDAGToDAGISel::Select(SDNode *N) {
if (N->isMachineOpcode())
return NULL; // Already selected.
@@ -99,10 +98,10 @@ SDNode *BlackfinDAGToDAGISel::Select(SDValue Op) {
}
}
- return SelectCode(Op);
+ return SelectCode(N);
}
-bool BlackfinDAGToDAGISel::SelectADDRspii(SDValue Op,
+bool BlackfinDAGToDAGISel::SelectADDRspii(SDNode *Op,
SDValue Addr,
SDValue &Base,
SDValue &Offset) {
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 1ab3c0a..0fd975c 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -25,6 +25,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/InlineAsm.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/ConstantsScanner.h"
#include "llvm/Analysis/FindUsedTypes.h"
@@ -34,6 +35,7 @@
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/CallSite.h"
@@ -341,6 +343,15 @@ namespace {
char CWriter::ID = 0;
+
+static std::string Mangle(const std::string &S) {
+ std::string Result;
+ raw_string_ostream OS(Result);
+ MCSymbol::printMangledName(S, OS, 0);
+ return OS.str();
+}
+
+
/// This method inserts names for any unnamed structure types that are used by
/// the program, and removes names from structure types that are not used by the
/// program.
@@ -1431,8 +1442,11 @@ void CWriter::printConstantWithCast(Constant* CPV, unsigned Opcode) {
std::string CWriter::GetValueName(const Value *Operand) {
// Mangle globals with the standard mangler interface for LLC compatibility.
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(Operand))
- return Mang->getMangledName(GV);
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(Operand)) {
+ SmallString<128> Str;
+ Mang->getNameWithPrefix(Str, GV, false);
+ return Mangle(Str.str().str());
+ }
std::string Name = Operand->getName();
@@ -1857,7 +1871,6 @@ bool CWriter::doInitialization(Module &M) {
// Ensure that all structure types have names...
Mang = new Mangler(M);
- Mang->markCharUnacceptable('.');
// Keep track of which functions are static ctors/dtors so they can have
// an attribute added to their prototypes.
@@ -2210,7 +2223,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
// Print out forward declarations for structure types before anything else!
Out << "/* Structure forward decls */\n";
for (; I != End; ++I) {
- std::string Name = "struct l_" + Mang->makeNameProper(I->first);
+ std::string Name = "struct " + Mangle("l_"+I->first);
Out << Name << ";\n";
TypeNames.insert(std::make_pair(I->second, Name));
}
@@ -2221,7 +2234,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
// for struct or opaque types.
Out << "/* Typedefs */\n";
for (I = TST.begin(); I != End; ++I) {
- std::string Name = "l_" + Mang->makeNameProper(I->first);
+ std::string Name = Mangle("l_"+I->first);
Out << "typedef ";
printType(Out, I->second, false, Name);
Out << ";\n";
@@ -2921,7 +2934,6 @@ void CWriter::lowerIntrinsics(Function &F) {
case Intrinsic::setjmp:
case Intrinsic::longjmp:
case Intrinsic::prefetch:
- case Intrinsic::dbg_stoppoint:
case Intrinsic::powi:
case Intrinsic::x86_sse_cmp_ss:
case Intrinsic::x86_sse_cmp_ps:
@@ -3178,20 +3190,6 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID,
Out << "0; *((void**)&" << GetValueName(&I)
<< ") = __builtin_stack_save()";
return true;
- case Intrinsic::dbg_stoppoint: {
- // If we use writeOperand directly we get a "u" suffix which is rejected
- // by gcc.
- DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
- std::string dir;
- GetConstantStringInfo(SPI.getDirectory(), dir);
- std::string file;
- GetConstantStringInfo(SPI.getFileName(), file);
- Out << "\n#line "
- << SPI.getLine()
- << " \""
- << dir << '/' << file << "\"\n";
- return true;
- }
case Intrinsic::x86_sse_cmp_ss:
case Intrinsic::x86_sse_cmp_ps:
case Intrinsic::x86_sse2_cmp_sd:
diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
index c69a751..80693e1 100644
--- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
+++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp
@@ -277,10 +277,9 @@ namespace {
return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy());
}
- SDNode *emitBuildVector(SDValue build_vec) {
- EVT vecVT = build_vec.getValueType();
+ SDNode *emitBuildVector(SDNode *bvNode) {
+ EVT vecVT = bvNode->getValueType(0);
EVT eltVT = vecVT.getVectorElementType();
- SDNode *bvNode = build_vec.getNode();
DebugLoc dl = bvNode->getDebugLoc();
// Check to see if this vector can be represented as a CellSPU immediate
@@ -296,13 +295,13 @@ namespace {
((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
(SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) ||
(SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0))))
- return Select(build_vec);
+ return Select(bvNode);
// No, need to emit a constant pool spill:
std::vector<Constant*> CV;
- for (size_t i = 0; i < build_vec.getNumOperands(); ++i) {
- ConstantSDNode *V = dyn_cast<ConstantSDNode > (build_vec.getOperand(i));
+ for (size_t i = 0; i < bvNode->getNumOperands(); ++i) {
+ ConstantSDNode *V = dyn_cast<ConstantSDNode > (bvNode->getOperand(i));
CV.push_back(const_cast<ConstantInt *> (V->getConstantIntValue()));
}
@@ -312,49 +311,49 @@ namespace {
SDValue CGPoolOffset =
SPU::LowerConstantPool(CPIdx, *CurDAG,
SPUtli.getSPUTargetMachine());
- return SelectCode(CurDAG->getLoad(build_vec.getValueType(), dl,
+ return SelectCode(CurDAG->getLoad(vecVT, dl,
CurDAG->getEntryNode(), CGPoolOffset,
PseudoSourceValue::getConstantPool(), 0,
- false, Alignment));
+ false, Alignment).getNode());
}
/// Select - Convert the specified operand from a target-independent to a
/// target-specific node if it hasn't already been changed.
- SDNode *Select(SDValue Op);
+ SDNode *Select(SDNode *N);
//! Emit the instruction sequence for i64 shl
- SDNode *SelectSHLi64(SDValue &Op, EVT OpVT);
+ SDNode *SelectSHLi64(SDNode *N, EVT OpVT);
//! Emit the instruction sequence for i64 srl
- SDNode *SelectSRLi64(SDValue &Op, EVT OpVT);
+ SDNode *SelectSRLi64(SDNode *N, EVT OpVT);
//! Emit the instruction sequence for i64 sra
- SDNode *SelectSRAi64(SDValue &Op, EVT OpVT);
+ SDNode *SelectSRAi64(SDNode *N, EVT OpVT);
//! Emit the necessary sequence for loading i64 constants:
- SDNode *SelectI64Constant(SDValue &Op, EVT OpVT, DebugLoc dl);
+ SDNode *SelectI64Constant(SDNode *N, EVT OpVT, DebugLoc dl);
//! Alternate instruction emit sequence for loading i64 constants
SDNode *SelectI64Constant(uint64_t i64const, EVT OpVT, DebugLoc dl);
//! Returns true if the address N is an A-form (local store) address
- bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index);
//! D-form address predicate
- bool SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index);
/// Alternate D-form address using i7 offset predicate
- bool SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
+ bool SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
SDValue &Base);
/// D-form address selection workhorse
- bool DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Disp,
+ bool DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Disp,
SDValue &Base, int minOffset, int maxOffset);
//! Address predicate if N can be expressed as an indexed [r+r] operation.
- bool SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index);
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
@@ -366,13 +365,13 @@ namespace {
switch (ConstraintCode) {
default: return true;
case 'm': // memory
- if (!SelectDFormAddr(Op, Op, Op0, Op1)
- && !SelectAFormAddr(Op, Op, Op0, Op1))
- SelectXFormAddr(Op, Op, Op0, Op1);
+ if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
+ && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1))
+ SelectXFormAddr(Op.getNode(), Op, Op0, Op1);
break;
case 'o': // offsetable
- if (!SelectDFormAddr(Op, Op, Op0, Op1)
- && !SelectAFormAddr(Op, Op, Op0, Op1)) {
+ if (!SelectDFormAddr(Op.getNode(), Op, Op0, Op1)
+ && !SelectAFormAddr(Op.getNode(), Op, Op0, Op1)) {
Op0 = Op;
Op1 = getSmallIPtrImm(0);
}
@@ -429,7 +428,7 @@ SPUDAGToDAGISel::InstructionSelect()
\arg Index The base address index
*/
bool
-SPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
+SPUDAGToDAGISel::SelectAFormAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index) {
// These match the addr256k operand type:
EVT OffsVT = MVT::i16;
@@ -479,7 +478,7 @@ SPUDAGToDAGISel::SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base,
}
bool
-SPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
+SPUDAGToDAGISel::SelectDForm2Addr(SDNode *Op, SDValue N, SDValue &Disp,
SDValue &Base) {
const int minDForm2Offset = -(1 << 7);
const int maxDForm2Offset = (1 << 7) - 1;
@@ -500,7 +499,7 @@ SPUDAGToDAGISel::SelectDForm2Addr(SDValue Op, SDValue N, SDValue &Disp,
to non-empty SDValue instances.
*/
bool
-SPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
+SPUDAGToDAGISel::SelectDFormAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index) {
return DFormAddressPredicate(Op, N, Base, Index,
SPUFrameInfo::minFrameOffset(),
@@ -508,7 +507,7 @@ SPUDAGToDAGISel::SelectDFormAddr(SDValue Op, SDValue N, SDValue &Base,
}
bool
-SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base,
+SPUDAGToDAGISel::DFormAddressPredicate(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index, int minOffset,
int maxOffset) {
unsigned Opc = N.getOpcode();
@@ -618,7 +617,7 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base,
Index = N;
return true;
} else if (Opc == ISD::Register || Opc == ISD::CopyFromReg) {
- unsigned OpOpc = Op.getOpcode();
+ unsigned OpOpc = Op->getOpcode();
if (OpOpc == ISD::STORE || OpOpc == ISD::LOAD) {
// Direct load/store without getelementptr
@@ -630,7 +629,7 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base,
else
Addr = N; // Register
- Offs = ((OpOpc == ISD::STORE) ? Op.getOperand(3) : Op.getOperand(2));
+ Offs = ((OpOpc == ISD::STORE) ? Op->getOperand(3) : Op->getOperand(2));
if (Offs.getOpcode() == ISD::Constant || Offs.getOpcode() == ISD::UNDEF) {
if (Offs.getOpcode() == ISD::UNDEF)
@@ -667,7 +666,7 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base,
(r)(r) X-form address.
*/
bool
-SPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
+SPUDAGToDAGISel::SelectXFormAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index) {
if (!SelectAFormAddr(Op, N, Base, Index)
&& !SelectDFormAddr(Op, N, Base, Index)) {
@@ -685,12 +684,11 @@ SPUDAGToDAGISel::SelectXFormAddr(SDValue Op, SDValue N, SDValue &Base,
/*!
*/
SDNode *
-SPUDAGToDAGISel::Select(SDValue Op) {
- SDNode *N = Op.getNode();
+SPUDAGToDAGISel::Select(SDNode *N) {
unsigned Opc = N->getOpcode();
int n_ops = -1;
unsigned NewOpc;
- EVT OpVT = Op.getValueType();
+ EVT OpVT = N->getValueType(0);
SDValue Ops[8];
DebugLoc dl = N->getDebugLoc();
@@ -700,8 +698,8 @@ SPUDAGToDAGISel::Select(SDValue Op) {
if (Opc == ISD::FrameIndex) {
int FI = cast<FrameIndexSDNode>(N)->getIndex();
- SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType());
- SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType());
+ SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0));
+ SDValue Imm0 = CurDAG->getTargetConstant(0, N->getValueType(0));
if (FI < 128) {
NewOpc = SPU::AIr32;
@@ -710,9 +708,9 @@ SPUDAGToDAGISel::Select(SDValue Op) {
n_ops = 2;
} else {
NewOpc = SPU::Ar32;
- Ops[0] = CurDAG->getRegister(SPU::R1, Op.getValueType());
+ Ops[0] = CurDAG->getRegister(SPU::R1, N->getValueType(0));
Ops[1] = SDValue(CurDAG->getMachineNode(SPU::ILAr32, dl,
- Op.getValueType(), TFI, Imm0),
+ N->getValueType(0), TFI, Imm0),
0);
n_ops = 2;
}
@@ -720,10 +718,10 @@ SPUDAGToDAGISel::Select(SDValue Op) {
// Catch the i64 constants that end up here. Note: The backend doesn't
// attempt to legalize the constant (it's useless because DAGCombiner
// will insert 64-bit constants and we can't stop it).
- return SelectI64Constant(Op, OpVT, Op.getDebugLoc());
+ return SelectI64Constant(N, OpVT, N->getDebugLoc());
} else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND)
&& OpVT == MVT::i64) {
- SDValue Op0 = Op.getOperand(0);
+ SDValue Op0 = N->getOperand(0);
EVT Op0VT = Op0.getValueType();
EVT Op0VecVT = EVT::getVectorVT(*CurDAG->getContext(),
Op0VT, (128 / Op0VT.getSizeInBits()));
@@ -760,9 +758,10 @@ SPUDAGToDAGISel::Select(SDValue Op) {
break;
}
- SDNode *shufMaskLoad = emitBuildVector(shufMask);
+ SDNode *shufMaskLoad = emitBuildVector(shufMask.getNode());
SDNode *PromoteScalar =
- SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl, Op0VecVT, Op0));
+ SelectCode(CurDAG->getNode(SPUISD::PREFSLOT2VEC, dl,
+ Op0VecVT, Op0).getNode());
SDValue zextShuffle =
CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
@@ -773,32 +772,32 @@ SPUDAGToDAGISel::Select(SDValue Op) {
// N.B.: BIT_CONVERT replaces and updates the zextShuffle node, so we
// re-use it in the VEC2PREFSLOT selection without needing to explicitly
// call SelectCode (it's already done for us.)
- SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, dl, OpVecVT, zextShuffle));
+ SelectCode(CurDAG->getNode(ISD::BIT_CONVERT, dl, OpVecVT, zextShuffle).getNode());
return SelectCode(CurDAG->getNode(SPUISD::VEC2PREFSLOT, dl, OpVT,
- zextShuffle));
+ zextShuffle).getNode());
} else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
SDNode *CGLoad =
- emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl));
+ emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, dl, OpVT,
- Op.getOperand(0), Op.getOperand(1),
- SDValue(CGLoad, 0)));
+ N->getOperand(0), N->getOperand(1),
+ SDValue(CGLoad, 0)).getNode());
} else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
SDNode *CGLoad =
- emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl));
+ emitBuildVector(getBorrowGenerateShufMask(*CurDAG, dl).getNode());
return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, dl, OpVT,
- Op.getOperand(0), Op.getOperand(1),
- SDValue(CGLoad, 0)));
+ N->getOperand(0), N->getOperand(1),
+ SDValue(CGLoad, 0)).getNode());
} else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) {
SDNode *CGLoad =
- emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl));
+ emitBuildVector(getCarryGenerateShufMask(*CurDAG, dl).getNode());
return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, dl, OpVT,
- Op.getOperand(0), Op.getOperand(1),
- SDValue(CGLoad, 0)));
+ N->getOperand(0), N->getOperand(1),
+ SDValue(CGLoad, 0)).getNode());
} else if (Opc == ISD::TRUNCATE) {
- SDValue Op0 = Op.getOperand(0);
+ SDValue Op0 = N->getOperand(0);
if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL)
&& OpVT == MVT::i32
&& Op0.getValueType() == MVT::i64) {
@@ -834,22 +833,22 @@ SPUDAGToDAGISel::Select(SDValue Op) {
}
} else if (Opc == ISD::SHL) {
if (OpVT == MVT::i64) {
- return SelectSHLi64(Op, OpVT);
+ return SelectSHLi64(N, OpVT);
}
} else if (Opc == ISD::SRL) {
if (OpVT == MVT::i64) {
- return SelectSRLi64(Op, OpVT);
+ return SelectSRLi64(N, OpVT);
}
} else if (Opc == ISD::SRA) {
if (OpVT == MVT::i64) {
- return SelectSRAi64(Op, OpVT);
+ return SelectSRAi64(N, OpVT);
}
} else if (Opc == ISD::FNEG
&& (OpVT == MVT::f64 || OpVT == MVT::v2f64)) {
- DebugLoc dl = Op.getDebugLoc();
+ DebugLoc dl = N->getDebugLoc();
// Check if the pattern is a special form of DFNMS:
// (fneg (fsub (fmul R64FP:$rA, R64FP:$rB), R64FP:$rC))
- SDValue Op0 = Op.getOperand(0);
+ SDValue Op0 = N->getOperand(0);
if (Op0.getOpcode() == ISD::FSUB) {
SDValue Op00 = Op0.getOperand(0);
if (Op00.getOpcode() == ISD::FMUL) {
@@ -869,28 +868,28 @@ SPUDAGToDAGISel::Select(SDValue Op) {
unsigned Opc = SPU::XORfneg64;
if (OpVT == MVT::f64) {
- signMask = SelectI64Constant(negConst, MVT::i64, dl);
+ signMask = SelectI64Constant(negConst.getNode(), MVT::i64, dl);
} else if (OpVT == MVT::v2f64) {
Opc = SPU::XORfnegvec;
signMask = emitBuildVector(CurDAG->getNode(ISD::BUILD_VECTOR, dl,
MVT::v2i64,
- negConst, negConst));
+ negConst, negConst).getNode());
}
return CurDAG->getMachineNode(Opc, dl, OpVT,
- Op.getOperand(0), SDValue(signMask, 0));
+ N->getOperand(0), SDValue(signMask, 0));
} else if (Opc == ISD::FABS) {
if (OpVT == MVT::f64) {
SDNode *signMask = SelectI64Constant(0x7fffffffffffffffULL, MVT::i64, dl);
return CurDAG->getMachineNode(SPU::ANDfabs64, dl, OpVT,
- Op.getOperand(0), SDValue(signMask, 0));
+ N->getOperand(0), SDValue(signMask, 0));
} else if (OpVT == MVT::v2f64) {
SDValue absConst = CurDAG->getConstant(0x7fffffffffffffffULL, MVT::i64);
SDValue absVec = CurDAG->getNode(ISD::BUILD_VECTOR, dl, MVT::v2i64,
absConst, absConst);
- SDNode *signMask = emitBuildVector(absVec);
+ SDNode *signMask = emitBuildVector(absVec.getNode());
return CurDAG->getMachineNode(SPU::ANDfabsvec, dl, OpVT,
- Op.getOperand(0), SDValue(signMask, 0));
+ N->getOperand(0), SDValue(signMask, 0));
}
} else if (Opc == SPUISD::LDRESULT) {
// Custom select instructions for LDRESULT
@@ -925,7 +924,7 @@ SPUDAGToDAGISel::Select(SDValue Op) {
// SPUInstrInfo catches the following patterns:
// (SPUindirect (SPUhi ...), (SPUlo ...))
// (SPUindirect $sp, imm)
- EVT VT = Op.getValueType();
+ EVT VT = N->getValueType(0);
SDValue Op0 = N->getOperand(0);
SDValue Op1 = N->getOperand(1);
RegisterSDNode *RN;
@@ -952,7 +951,7 @@ SPUDAGToDAGISel::Select(SDValue Op) {
else
return CurDAG->getMachineNode(NewOpc, dl, OpVT, Ops, n_ops);
} else
- return SelectCode(Op);
+ return SelectCode(N);
}
/*!
@@ -968,15 +967,15 @@ SPUDAGToDAGISel::Select(SDValue Op) {
* @return The SDNode with the entire instruction sequence
*/
SDNode *
-SPUDAGToDAGISel::SelectSHLi64(SDValue &Op, EVT OpVT) {
- SDValue Op0 = Op.getOperand(0);
+SPUDAGToDAGISel::SelectSHLi64(SDNode *N, EVT OpVT) {
+ SDValue Op0 = N->getOperand(0);
EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
OpVT, (128 / OpVT.getSizeInBits()));
- SDValue ShiftAmt = Op.getOperand(1);
+ SDValue ShiftAmt = N->getOperand(1);
EVT ShiftAmtVT = ShiftAmt.getValueType();
SDNode *VecOp0, *SelMask, *ZeroFill, *Shift = 0;
SDValue SelMaskVal;
- DebugLoc dl = Op.getDebugLoc();
+ DebugLoc dl = N->getDebugLoc();
VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0);
SelMaskVal = CurDAG->getTargetConstant(0xff00ULL, MVT::i16);
@@ -1034,14 +1033,14 @@ SPUDAGToDAGISel::SelectSHLi64(SDValue &Op, EVT OpVT) {
* @return The SDNode with the entire instruction sequence
*/
SDNode *
-SPUDAGToDAGISel::SelectSRLi64(SDValue &Op, EVT OpVT) {
- SDValue Op0 = Op.getOperand(0);
+SPUDAGToDAGISel::SelectSRLi64(SDNode *N, EVT OpVT) {
+ SDValue Op0 = N->getOperand(0);
EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
OpVT, (128 / OpVT.getSizeInBits()));
- SDValue ShiftAmt = Op.getOperand(1);
+ SDValue ShiftAmt = N->getOperand(1);
EVT ShiftAmtVT = ShiftAmt.getValueType();
SDNode *VecOp0, *Shift = 0;
- DebugLoc dl = Op.getDebugLoc();
+ DebugLoc dl = N->getDebugLoc();
VecOp0 = CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op0);
@@ -1101,16 +1100,16 @@ SPUDAGToDAGISel::SelectSRLi64(SDValue &Op, EVT OpVT) {
* @return The SDNode with the entire instruction sequence
*/
SDNode *
-SPUDAGToDAGISel::SelectSRAi64(SDValue &Op, EVT OpVT) {
+SPUDAGToDAGISel::SelectSRAi64(SDNode *N, EVT OpVT) {
// Promote Op0 to vector
EVT VecVT = EVT::getVectorVT(*CurDAG->getContext(),
OpVT, (128 / OpVT.getSizeInBits()));
- SDValue ShiftAmt = Op.getOperand(1);
+ SDValue ShiftAmt = N->getOperand(1);
EVT ShiftAmtVT = ShiftAmt.getValueType();
- DebugLoc dl = Op.getDebugLoc();
+ DebugLoc dl = N->getDebugLoc();
SDNode *VecOp0 =
- CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, Op.getOperand(0));
+ CurDAG->getMachineNode(SPU::ORv2i64_i64, dl, VecVT, N->getOperand(0));
SDValue SignRotAmt = CurDAG->getTargetConstant(31, ShiftAmtVT);
SDNode *SignRot =
@@ -1170,9 +1169,9 @@ SPUDAGToDAGISel::SelectSRAi64(SDValue &Op, EVT OpVT) {
/*!
Do the necessary magic necessary to load a i64 constant
*/
-SDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, EVT OpVT,
+SDNode *SPUDAGToDAGISel::SelectI64Constant(SDNode *N, EVT OpVT,
DebugLoc dl) {
- ConstantSDNode *CN = cast<ConstantSDNode>(Op.getNode());
+ ConstantSDNode *CN = cast<ConstantSDNode>(N);
return SelectI64Constant(CN->getZExtValue(), OpVT, dl);
}
@@ -1192,7 +1191,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
ReplaceUses(i64vec, Op0);
return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT,
- SDValue(emitBuildVector(Op0), 0));
+ SDValue(emitBuildVector(Op0.getNode()), 0));
} else if (i64vec.getOpcode() == SPUISD::SHUFB) {
SDValue lhs = i64vec.getOperand(0);
SDValue rhs = i64vec.getOperand(1);
@@ -1205,7 +1204,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
SDNode *lhsNode = (lhs.getNode()->isMachineOpcode()
? lhs.getNode()
- : emitBuildVector(lhs));
+ : emitBuildVector(lhs.getNode()));
if (rhs.getOpcode() == ISD::BIT_CONVERT) {
ReplaceUses(rhs, rhs.getOperand(0));
@@ -1214,7 +1213,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
SDNode *rhsNode = (rhs.getNode()->isMachineOpcode()
? rhs.getNode()
- : emitBuildVector(rhs));
+ : emitBuildVector(rhs.getNode()));
if (shufmask.getOpcode() == ISD::BIT_CONVERT) {
ReplaceUses(shufmask, shufmask.getOperand(0));
@@ -1223,18 +1222,18 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(uint64_t Value64, EVT OpVT,
SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode()
? shufmask.getNode()
- : emitBuildVector(shufmask));
+ : emitBuildVector(shufmask.getNode()));
SDNode *shufNode =
Select(CurDAG->getNode(SPUISD::SHUFB, dl, OpVecVT,
SDValue(lhsNode, 0), SDValue(rhsNode, 0),
- SDValue(shufMaskNode, 0)));
+ SDValue(shufMaskNode, 0)).getNode());
return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT,
SDValue(shufNode, 0));
} else if (i64vec.getOpcode() == ISD::BUILD_VECTOR) {
return CurDAG->getMachineNode(SPU::ORi64_v2i64, dl, OpVT,
- SDValue(emitBuildVector(i64vec), 0));
+ SDValue(emitBuildVector(i64vec.getNode()), 0));
} else {
llvm_report_error("SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec"
"condition");
diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
index 4d40769..4eec757 100644
--- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
+++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp
@@ -146,12 +146,12 @@ namespace {
private:
DenseMap<SDNode*, SDNode*> RMWStores;
void PreprocessForRMW();
- SDNode *Select(SDValue Op);
- SDNode *SelectIndexedLoad(SDValue Op);
- SDNode *SelectIndexedBinOp(SDValue Op, SDValue N1, SDValue N2,
+ SDNode *Select(SDNode *N);
+ SDNode *SelectIndexedLoad(SDNode *Op);
+ SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2,
unsigned Opc8, unsigned Opc16);
- bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Disp);
+ bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp);
#ifndef NDEBUG
unsigned Indent;
@@ -283,7 +283,7 @@ bool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) {
/// SelectAddr - returns true if it is able pattern match an addressing mode.
/// It returns the operands which make up the maximal addressing mode it can
/// match by reference.
-bool MSP430DAGToDAGISel::SelectAddr(SDValue Op, SDValue N,
+bool MSP430DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N,
SDValue &Base, SDValue &Disp) {
MSP430ISelAddressMode AM;
@@ -326,7 +326,7 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
switch (ConstraintCode) {
default: return true;
case 'm': // memory
- if (!SelectAddr(Op, Op, Op0, Op1))
+ if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
return true;
break;
}
@@ -627,8 +627,8 @@ static bool isValidIndexedLoad(const LoadSDNode *LD) {
return true;
}
-SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) {
- LoadSDNode *LD = cast<LoadSDNode>(Op);
+SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) {
+ LoadSDNode *LD = cast<LoadSDNode>(N);
if (!isValidIndexedLoad(LD))
return NULL;
@@ -646,17 +646,17 @@ SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDValue Op) {
return NULL;
}
- return CurDAG->getMachineNode(Opcode, Op.getDebugLoc(),
+ return CurDAG->getMachineNode(Opcode, N->getDebugLoc(),
VT, MVT::i16, MVT::Other,
LD->getBasePtr(), LD->getChain());
}
-SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDValue Op,
+SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op,
SDValue N1, SDValue N2,
unsigned Opc8, unsigned Opc16) {
if (N1.getOpcode() == ISD::LOAD &&
N1.hasOneUse() &&
- IsLegalAndProfitableToFold(N1.getNode(), Op.getNode(), Op.getNode())) {
+ IsLegalAndProfitableToFold(N1.getNode(), Op, Op)) {
LoadSDNode *LD = cast<LoadSDNode>(N1);
if (!isValidIndexedLoad(LD))
return NULL;
@@ -667,7 +667,7 @@ SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDValue Op,
MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand();
SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() };
SDNode *ResNode =
- CurDAG->SelectNodeTo(Op.getNode(), Opc,
+ CurDAG->SelectNodeTo(Op, Opc,
VT, MVT::i16, MVT::Other,
Ops0, 3);
cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1);
@@ -707,9 +707,8 @@ void MSP430DAGToDAGISel::InstructionSelect() {
RMWStores.clear();
}
-SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
- SDNode *Node = Op.getNode();
- DebugLoc dl = Op.getDebugLoc();
+SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) {
+ DebugLoc dl = Node->getDebugLoc();
// Dump information about the Node being selected
DEBUG(errs().indent(Indent) << "Selecting: ");
@@ -730,7 +729,7 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
switch (Node->getOpcode()) {
default: break;
case ISD::FrameIndex: {
- assert(Op.getValueType() == MVT::i16);
+ assert(Node->getValueType(0) == MVT::i16);
int FI = cast<FrameIndexSDNode>(Node)->getIndex();
SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
if (Node->hasOneUse())
@@ -740,18 +739,18 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
TFI, CurDAG->getTargetConstant(0, MVT::i16));
}
case ISD::LOAD:
- if (SDNode *ResNode = SelectIndexedLoad(Op))
+ if (SDNode *ResNode = SelectIndexedLoad(Node))
return ResNode;
// Other cases are autogenerated.
break;
case ISD::ADD:
if (SDNode *ResNode =
- SelectIndexedBinOp(Op,
- Op.getOperand(0), Op.getOperand(1),
+ SelectIndexedBinOp(Node,
+ Node->getOperand(0), Node->getOperand(1),
MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
return ResNode;
else if (SDNode *ResNode =
- SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0),
+ SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
MSP430::ADD8rm_POST, MSP430::ADD16rm_POST))
return ResNode;
@@ -759,8 +758,8 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
break;
case ISD::SUB:
if (SDNode *ResNode =
- SelectIndexedBinOp(Op,
- Op.getOperand(0), Op.getOperand(1),
+ SelectIndexedBinOp(Node,
+ Node->getOperand(0), Node->getOperand(1),
MSP430::SUB8rm_POST, MSP430::SUB16rm_POST))
return ResNode;
@@ -768,12 +767,12 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
break;
case ISD::AND:
if (SDNode *ResNode =
- SelectIndexedBinOp(Op,
- Op.getOperand(0), Op.getOperand(1),
+ SelectIndexedBinOp(Node,
+ Node->getOperand(0), Node->getOperand(1),
MSP430::AND8rm_POST, MSP430::AND16rm_POST))
return ResNode;
else if (SDNode *ResNode =
- SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0),
+ SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
MSP430::AND8rm_POST, MSP430::AND16rm_POST))
return ResNode;
@@ -781,12 +780,12 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
break;
case ISD::OR:
if (SDNode *ResNode =
- SelectIndexedBinOp(Op,
- Op.getOperand(0), Op.getOperand(1),
+ SelectIndexedBinOp(Node,
+ Node->getOperand(0), Node->getOperand(1),
MSP430::OR8rm_POST, MSP430::OR16rm_POST))
return ResNode;
else if (SDNode *ResNode =
- SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0),
+ SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
MSP430::OR8rm_POST, MSP430::OR16rm_POST))
return ResNode;
@@ -794,12 +793,12 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
break;
case ISD::XOR:
if (SDNode *ResNode =
- SelectIndexedBinOp(Op,
- Op.getOperand(0), Op.getOperand(1),
+ SelectIndexedBinOp(Node,
+ Node->getOperand(0), Node->getOperand(1),
MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
return ResNode;
else if (SDNode *ResNode =
- SelectIndexedBinOp(Op, Op.getOperand(1), Op.getOperand(0),
+ SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0),
MSP430::XOR8rm_POST, MSP430::XOR16rm_POST))
return ResNode;
@@ -808,11 +807,11 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
}
// Select the default instruction
- SDNode *ResNode = SelectCode(Op);
+ SDNode *ResNode = SelectCode(Node);
DEBUG(errs() << std::string(Indent-2, ' ') << "=> ");
- if (ResNode == NULL || ResNode == Op.getNode())
- DEBUG(Op.getNode()->dump(CurDAG));
+ if (ResNode == NULL || ResNode == Node)
+ DEBUG(Node->dump(CurDAG));
else
DEBUG(ResNode->dump(CurDAG));
DEBUG(errs() << "\n");
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index 5fe9b20..d3dce4b 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -660,16 +660,16 @@ static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
default: llvm_unreachable("Invalid integer condition!");
case ISD::SETEQ:
TCC = MSP430CC::COND_E; // aka COND_Z
- // Minor optimization: if RHS is a constant, swap operands, then the
+ // Minor optimization: if LHS is a constant, swap operands, then the
// constant can be folded into comparison.
- if (RHS.getOpcode() == ISD::Constant)
+ if (LHS.getOpcode() == ISD::Constant)
std::swap(LHS, RHS);
break;
case ISD::SETNE:
TCC = MSP430CC::COND_NE; // aka COND_NZ
- // Minor optimization: if RHS is a constant, swap operands, then the
+ // Minor optimization: if LHS is a constant, swap operands, then the
// constant can be folded into comparison.
- if (RHS.getOpcode() == ISD::Constant)
+ if (LHS.getOpcode() == ISD::Constant)
std::swap(LHS, RHS);
break;
case ISD::SETULE:
@@ -1014,8 +1014,8 @@ MSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
// BB:
// cmp 0, N
// je RemBB
- BuildMI(BB, dl, TII.get(MSP430::CMP8ir))
- .addImm(0).addReg(ShiftAmtSrcReg);
+ BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
+ .addReg(ShiftAmtSrcReg).addImm(0);
BuildMI(BB, dl, TII.get(MSP430::JCC))
.addMBB(RemBB)
.addImm(MSP430CC::COND_E);
@@ -1045,6 +1045,7 @@ MSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
.addReg(SrcReg).addMBB(BB)
.addReg(ShiftReg2).addMBB(LoopBB);
+ F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
return RemBB;
}
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index d67ba90..022d171 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -819,38 +819,40 @@ def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
// Integer comparisons
let Defs = [SRW] in {
def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
- "cmp.b\t{$src1, $src2}",
+ "cmp.b\t{$src2, $src1}",
[(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
- "cmp.w\t{$src1, $src2}",
+ "cmp.w\t{$src2, $src1}",
[(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
-def CMP8ir : Pseudo<(outs), (ins i8imm:$src1, GR8:$src2),
- "cmp.b\t{$src1, $src2}",
- [(MSP430cmp imm:$src1, GR8:$src2), (implicit SRW)]>;
-def CMP16ir : Pseudo<(outs), (ins i16imm:$src1, GR16:$src2),
- "cmp.w\t{$src1, $src2}",
- [(MSP430cmp imm:$src1, GR16:$src2), (implicit SRW)]>;
-
-def CMP8im : Pseudo<(outs), (ins i8imm:$src1, memsrc:$src2),
- "cmp.b\t{$src1, $src2}",
- [(MSP430cmp (i8 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
-def CMP16im : Pseudo<(outs), (ins i16imm:$src1, memsrc:$src2),
- "cmp.w\t{$src1, $src2}",
- [(MSP430cmp (i16 imm:$src1), (load addr:$src2)), (implicit SRW)]>;
+def CMP8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>;
+def CMP16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>;
+
+def CMP8mi : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1),
+ (i8 imm:$src2)), (implicit SRW)]>;
+def CMP16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1),
+ (i16 imm:$src2)), (implicit SRW)]>;
def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),
- "cmp.b\t{$src1, $src2}",
+ "cmp.b\t{$src2, $src1}",
[(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>;
def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2),
- "cmp.w\t{$src1, $src2}",
+ "cmp.w\t{$src2, $src1}",
[(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>;
def CMP8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
- "cmp.b\t{$src1, $src2}",
+ "cmp.b\t{$src2, $src1}",
[(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>;
def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
- "cmp.w\t{$src1, $src2}",
+ "cmp.w\t{$src2, $src1}",
[(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>;
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index ede111d..a53e918 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -84,14 +84,14 @@ private:
}
SDNode *getGlobalBaseReg();
- SDNode *Select(SDValue N);
+ SDNode *Select(SDNode *N);
// Complex Pattern.
- bool SelectAddr(SDValue Op, SDValue N,
+ bool SelectAddr(SDNode *Op, SDValue N,
SDValue &Base, SDValue &Offset);
- SDNode *SelectLoadFp64(SDValue N);
- SDNode *SelectStoreFp64(SDValue N);
+ SDNode *SelectLoadFp64(SDNode *N);
+ SDNode *SelectStoreFp64(SDNode *N);
// getI32Imm - Return a target constant with the specified
// value, of type i32.
@@ -132,7 +132,7 @@ SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
/// ComplexPattern used on MipsInstrInfo
/// Used on Mips Load/Store instructions
bool MipsDAGToDAGISel::
-SelectAddr(SDValue Op, SDValue Addr, SDValue &Offset, SDValue &Base)
+SelectAddr(SDNode *Op, SDValue Addr, SDValue &Offset, SDValue &Base)
{
// if Address is FI, get the TargetFrameIndex.
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
@@ -199,19 +199,19 @@ SelectAddr(SDValue Op, SDValue Addr, SDValue &Offset, SDValue &Base)
return true;
}
-SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDValue N) {
+SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDNode *N) {
MVT::SimpleValueType NVT =
- N.getNode()->getValueType(0).getSimpleVT().SimpleTy;
+ N->getValueType(0).getSimpleVT().SimpleTy;
if (!Subtarget.isMips1() || NVT != MVT::f64)
return NULL;
- if (!Predicate_unindexedload(N.getNode()) ||
- !Predicate_load(N.getNode()))
+ if (!Predicate_unindexedload(N) ||
+ !Predicate_load(N))
return NULL;
- SDValue Chain = N.getOperand(0);
- SDValue N1 = N.getOperand(1);
+ SDValue Chain = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
SDValue Offset0, Offset1, Base;
if (!SelectAddr(N, N1, Offset0, Base) ||
@@ -220,7 +220,7 @@ SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDValue N) {
MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
- DebugLoc dl = N.getDebugLoc();
+ DebugLoc dl = N->getDebugLoc();
// The second load should start after for 4 bytes.
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Offset0))
@@ -255,27 +255,27 @@ SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDValue N) {
SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPODD, dl,
MVT::f64, I0, SDValue(LD1, 0));
- ReplaceUses(N, I1);
- ReplaceUses(N.getValue(1), Chain);
+ ReplaceUses(SDValue(N, 0), I1);
+ ReplaceUses(SDValue(N, 1), Chain);
cast<MachineSDNode>(LD0)->setMemRefs(MemRefs0, MemRefs0 + 1);
cast<MachineSDNode>(LD1)->setMemRefs(MemRefs0, MemRefs0 + 1);
return I1.getNode();
}
-SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDValue N) {
+SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDNode *N) {
if (!Subtarget.isMips1() ||
- N.getOperand(1).getValueType() != MVT::f64)
+ N->getOperand(1).getValueType() != MVT::f64)
return NULL;
- SDValue Chain = N.getOperand(0);
+ SDValue Chain = N->getOperand(0);
- if (!Predicate_unindexedstore(N.getNode()) ||
- !Predicate_store(N.getNode()))
+ if (!Predicate_unindexedstore(N) ||
+ !Predicate_store(N))
return NULL;
- SDValue N1 = N.getOperand(1);
- SDValue N2 = N.getOperand(2);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
SDValue Offset0, Offset1, Base;
if (!SelectAddr(N, N2, Offset0, Base) ||
@@ -285,7 +285,7 @@ SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDValue N) {
MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
- DebugLoc dl = N.getDebugLoc();
+ DebugLoc dl = N->getDebugLoc();
// Get the even and odd part from the f64 register
SDValue FPOdd = CurDAG->getTargetExtractSubreg(Mips::SUBREG_FPODD,
@@ -318,14 +318,13 @@ SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDValue N) {
MVT::Other, Ops1, 4), 0);
cast<MachineSDNode>(Chain.getNode())->setMemRefs(MemRefs0, MemRefs0 + 1);
- ReplaceUses(N.getValue(0), Chain);
+ ReplaceUses(SDValue(N, 0), Chain);
return Chain.getNode();
}
/// Select instructions not customized! Used for
/// expanded, promoted and normal instructions
-SDNode* MipsDAGToDAGISel::Select(SDValue N) {
- SDNode *Node = N.getNode();
+SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
unsigned Opcode = Node->getOpcode();
DebugLoc dl = Node->getDebugLoc();
@@ -379,7 +378,7 @@ SDNode* MipsDAGToDAGISel::Select(SDValue N) {
SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, dl, VT,
SDValue(Carry,0), RHS);
- return CurDAG->SelectNodeTo(N.getNode(), MOp, VT, MVT::Flag,
+ return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Flag,
LHS, SDValue(AddCarry,0));
}
@@ -405,11 +404,11 @@ SDNode* MipsDAGToDAGISel::Select(SDValue N) {
InFlag = SDValue(Lo,1);
SDNode *Hi = CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag);
- if (!N.getValue(0).use_empty())
- ReplaceUses(N.getValue(0), SDValue(Lo,0));
+ if (!SDValue(Node, 0).use_empty())
+ ReplaceUses(SDValue(Node, 0), SDValue(Lo,0));
- if (!N.getValue(1).use_empty())
- ReplaceUses(N.getValue(1), SDValue(Hi,0));
+ if (!SDValue(Node, 1).use_empty())
+ ReplaceUses(SDValue(Node, 1), SDValue(Hi,0));
return NULL;
}
@@ -460,23 +459,23 @@ SDNode* MipsDAGToDAGISel::Select(SDValue N) {
return getGlobalBaseReg();
case ISD::ConstantFP: {
- ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
- if (N.getValueType() == MVT::f64 && CN->isExactlyValue(+0.0)) {
+ ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);
+ if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32);
- ReplaceUses(N, Zero);
+ ReplaceUses(SDValue(Node, 0), Zero);
return Zero.getNode();
}
break;
}
case ISD::LOAD:
- if (SDNode *ResNode = SelectLoadFp64(N))
+ if (SDNode *ResNode = SelectLoadFp64(Node))
return ResNode;
// Other cases are autogenerated.
break;
case ISD::STORE:
- if (SDNode *ResNode = SelectStoreFp64(N))
+ if (SDNode *ResNode = SelectStoreFp64(Node))
return ResNode;
// Other cases are autogenerated.
break;
@@ -523,11 +522,11 @@ SDNode* MipsDAGToDAGISel::Select(SDValue N) {
}
// Select the default instruction
- SDNode *ResNode = SelectCode(N);
+ SDNode *ResNode = SelectCode(Node);
DEBUG(errs().indent(Indent-2) << "=> ");
- if (ResNode == NULL || ResNode == N.getNode())
- DEBUG(N.getNode()->dump(CurDAG));
+ if (ResNode == NULL || ResNode == Node)
+ DEBUG(Node->dump(CurDAG));
else
DEBUG(ResNode->dump(CurDAG));
DEBUG(errs() << "\n");
diff --git a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp b/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp
index e13e6cd..82197ae 100644
--- a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp
+++ b/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp
@@ -36,7 +36,7 @@ void PIC16DAGToDAGISel::InstructionSelect() {
/// Select - Select instructions not customized! Used for
/// expanded, promoted and normal instructions.
-SDNode* PIC16DAGToDAGISel::Select(SDValue N) {
+SDNode* PIC16DAGToDAGISel::Select(SDNode *N) {
// Select the default instruction.
SDNode *ResNode = SelectCode(N);
@@ -47,7 +47,7 @@ SDNode* PIC16DAGToDAGISel::Select(SDValue N) {
// SelectDirectAddr - Match a direct address for DAG.
// A direct address could be a globaladdress or externalsymbol.
-bool PIC16DAGToDAGISel::SelectDirectAddr(SDValue Op, SDValue N,
+bool PIC16DAGToDAGISel::SelectDirectAddr(SDNode *Op, SDValue N,
SDValue &Address) {
// Return true if TGA or ES.
if (N.getOpcode() == ISD::TargetGlobalAddress
diff --git a/lib/Target/PIC16/PIC16ISelDAGToDAG.h b/lib/Target/PIC16/PIC16ISelDAGToDAG.h
index d9172f2..813a540 100644
--- a/lib/Target/PIC16/PIC16ISelDAGToDAG.h
+++ b/lib/Target/PIC16/PIC16ISelDAGToDAG.h
@@ -52,10 +52,10 @@ private:
// Include the pieces autogenerated from the target description.
#include "PIC16GenDAGISel.inc"
- SDNode *Select(SDValue N);
+ SDNode *Select(SDNode *N);
// Match direct address complex pattern.
- bool SelectDirectAddr(SDValue Op, SDValue N, SDValue &Address);
+ bool SelectDirectAddr(SDNode *Op, SDValue N, SDValue &Address);
};
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index aae4607..d505d38 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -32,6 +32,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
@@ -49,6 +50,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/SmallString.h"
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -57,27 +59,42 @@ namespace {
class PPCAsmPrinter : public AsmPrinter {
protected:
struct FnStubInfo {
- std::string Stub, LazyPtr, AnonSymbol;
+ MCSymbol *Stub, *LazyPtr, *AnonSymbol;
- FnStubInfo() {}
+ FnStubInfo() {
+ Stub = LazyPtr = AnonSymbol = 0;
+ }
- void Init(const GlobalValue *GV, Mangler *Mang) {
+ void Init(const GlobalValue *GV, Mangler *Mang, MCContext &Ctx) {
// Already initialized.
- if (!Stub.empty()) return;
- Stub = Mang->getMangledName(GV, "$stub", true);
- LazyPtr = Mang->getMangledName(GV, "$lazy_ptr", true);
- AnonSymbol = Mang->getMangledName(GV, "$stub$tmp", true);
+ if (Stub != 0) return;
+
+ // Get the names.
+ SmallString<128> TmpStr;
+ Mang->getNameWithPrefix(TmpStr, GV, true);
+ MakeSymbols(TmpStr, Ctx);
}
- void Init(const std::string &GV, Mangler *Mang) {
- // Already initialized.
- if (!Stub.empty()) return;
- Stub = Mang->makeNameProper(GV + "$stub",
- Mangler::Private);
- LazyPtr = Mang->makeNameProper(GV + "$lazy_ptr",
- Mangler::Private);
- AnonSymbol = Mang->makeNameProper(GV + "$stub$tmp",
- Mangler::Private);
+ void Init(StringRef GVName, Mangler *Mang, MCContext &Ctx) {
+ assert(!GVName.empty() && "external symbol name shouldn't be empty");
+ if (Stub != 0) return; // Already initialized.
+ // Get the names for the external symbol name.
+ SmallString<128> TmpStr;
+ Mang->getNameWithPrefix(TmpStr, GVName, Mangler::Private);
+ MakeSymbols(TmpStr, Ctx);
+ }
+
+ void MakeSymbols(SmallString<128> &TmpStr, MCContext &Ctx) {
+ TmpStr += "$stub";
+ Stub = Ctx.GetOrCreateSymbol(TmpStr.str());
+ TmpStr.erase(TmpStr.end()-5, TmpStr.end()); // Remove $stub
+
+ TmpStr += "$lazy_ptr";
+ LazyPtr = Ctx.GetOrCreateSymbol(TmpStr.str());
+ TmpStr.erase(TmpStr.end()-9, TmpStr.end()); // Remove $lazy_ptr
+
+ TmpStr += "$stub$tmp";
+ AnonSymbol = Ctx.GetOrCreateSymbol(TmpStr.str());
}
};
@@ -224,15 +241,17 @@ namespace {
if (GV->isDeclaration() || GV->isWeakForLinker()) {
// Dynamically-resolved functions need a stub for the function.
FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)];
- FnInfo.Init(GV, Mang);
- O << FnInfo.Stub;
+ FnInfo.Init(GV, Mang, OutContext);
+ FnInfo.Stub->print(O, MAI);
return;
}
}
if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
- FnStubInfo &FnInfo =FnStubs[Mang->makeNameProper(MO.getSymbolName())];
- FnInfo.Init(MO.getSymbolName(), Mang);
- O << FnInfo.Stub;
+ SmallString<128> MangledName;
+ Mang->getNameWithPrefix(MangledName, MO.getSymbolName());
+ FnStubInfo &FnInfo = FnStubs[MangledName.str()];
+ FnInfo.Init(MO.getSymbolName(), Mang, OutContext);
+ FnInfo.Stub->print(O, MAI);
return;
}
}
@@ -550,50 +569,49 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
processDebugLoc(MI, true);
// Check for slwi/srwi mnemonics.
+ bool useSubstituteMnemonic = false;
if (MI->getOpcode() == PPC::RLWINM) {
- bool FoundMnemonic = false;
unsigned char SH = MI->getOperand(2).getImm();
unsigned char MB = MI->getOperand(3).getImm();
unsigned char ME = MI->getOperand(4).getImm();
if (SH <= 31 && MB == 0 && ME == (31-SH)) {
- O << "\tslwi "; FoundMnemonic = true;
+ O << "\tslwi "; useSubstituteMnemonic = true;
}
if (SH <= 31 && MB == (32-SH) && ME == 31) {
- O << "\tsrwi "; FoundMnemonic = true;
+ O << "\tsrwi "; useSubstituteMnemonic = true;
SH = 32-SH;
}
- if (FoundMnemonic) {
+ if (useSubstituteMnemonic) {
printOperand(MI, 0);
O << ", ";
printOperand(MI, 1);
- O << ", " << (unsigned int)SH << '\n';
- return;
+ O << ", " << (unsigned int)SH;
}
} else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) {
if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
+ useSubstituteMnemonic = true;
O << "\tmr ";
printOperand(MI, 0);
O << ", ";
printOperand(MI, 1);
- O << '\n';
- return;
}
} else if (MI->getOpcode() == PPC::RLDICR) {
unsigned char SH = MI->getOperand(2).getImm();
unsigned char ME = MI->getOperand(3).getImm();
// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
if (63-SH == ME) {
+ useSubstituteMnemonic = true;
O << "\tsldi ";
printOperand(MI, 0);
O << ", ";
printOperand(MI, 1);
- O << ", " << (unsigned int)SH << '\n';
- return;
+ O << ", " << (unsigned int)SH;
}
}
- printInstruction(MI);
-
+ if (!useSubstituteMnemonic)
+ printInstruction(MI);
+
if (VerboseAsm)
EmitComments(*MI);
O << '\n';
@@ -1038,27 +1056,38 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
MCSectionMachO::S_SYMBOL_STUBS |
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
32, SectionKind::getText());
- for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
+ for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
I != E; ++I) {
OutStreamer.SwitchSection(StubSection);
EmitAlignment(4);
const FnStubInfo &Info = I->second;
- O << Info.Stub << ":\n";
+ Info.Stub->print(O, MAI);
+ O << ":\n";
O << "\t.indirect_symbol " << I->getKeyData() << '\n';
O << "\tmflr r0\n";
- O << "\tbcl 20,31," << Info.AnonSymbol << '\n';
- O << Info.AnonSymbol << ":\n";
+ O << "\tbcl 20,31,";
+ Info.AnonSymbol->print(O, MAI);
+ O << '\n';
+ Info.AnonSymbol->print(O, MAI);
+ O << ":\n";
O << "\tmflr r11\n";
- O << "\taddis r11,r11,ha16(" << Info.LazyPtr << "-" << Info.AnonSymbol;
+ O << "\taddis r11,r11,ha16(";
+ Info.LazyPtr->print(O, MAI);
+ O << '-';
+ Info.AnonSymbol->print(O, MAI);
O << ")\n";
O << "\tmtlr r0\n";
O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(";
- O << Info.LazyPtr << "-" << Info.AnonSymbol << ")(r11)\n";
+ Info.LazyPtr->print(O, MAI);
+ O << '-';
+ Info.AnonSymbol->print(O, MAI);
+ O << ")(r11)\n";
O << "\tmtctr r12\n";
O << "\tbctr\n";
OutStreamer.SwitchSection(LSPSection);
- O << Info.LazyPtr << ":\n";
+ Info.LazyPtr->print(O, MAI);
+ O << ":\n";
O << "\t.indirect_symbol " << I->getKeyData() << '\n';
O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
}
@@ -1074,15 +1103,20 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
OutStreamer.SwitchSection(StubSection);
EmitAlignment(4);
const FnStubInfo &Info = I->second;
- O << Info.Stub << ":\n";
+ Info.Stub->print(O, MAI);
+ O << ":\n";
O << "\t.indirect_symbol " << I->getKeyData() << '\n';
- O << "\tlis r11,ha16(" << Info.LazyPtr << ")\n";
+ O << "\tlis r11,ha16(";
+ Info.LazyPtr->print(O, MAI);
+ O << ")\n";
O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(";
- O << Info.LazyPtr << ")(r11)\n";
+ Info.LazyPtr->print(O, MAI);
+ O << ")(r11)\n";
O << "\tmtctr r12\n";
O << "\tbctr\n";
OutStreamer.SwitchSection(LSPSection);
- O << Info.LazyPtr << ":\n";
+ Info.LazyPtr->print(O, MAI);
+ O << ":\n";
O << "\t.indirect_symbol " << I->getKeyData() << '\n';
O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
}
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index e7334b5..32c1879 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -95,7 +95,7 @@ namespace {
// Select - Convert the specified operand from a target-independent to a
// target-specific node if it hasn't already been changed.
- SDNode *Select(SDValue Op);
+ SDNode *Select(SDNode *N);
SDNode *SelectBitfieldInsert(SDNode *N);
@@ -105,7 +105,7 @@ namespace {
/// SelectAddrImm - Returns true if the address N can be represented by
/// a base register plus a signed 16-bit displacement [r+imm].
- bool SelectAddrImm(SDValue Op, SDValue N, SDValue &Disp,
+ bool SelectAddrImm(SDNode *Op, SDValue N, SDValue &Disp,
SDValue &Base) {
return PPCLowering.SelectAddressRegImm(N, Disp, Base, *CurDAG);
}
@@ -113,7 +113,7 @@ namespace {
/// SelectAddrImmOffs - Return true if the operand is valid for a preinc
/// immediate field. Because preinc imms have already been validated, just
/// accept it.
- bool SelectAddrImmOffs(SDValue Op, SDValue N, SDValue &Out) const {
+ bool SelectAddrImmOffs(SDNode *Op, SDValue N, SDValue &Out) const {
Out = N;
return true;
}
@@ -121,14 +121,14 @@ namespace {
/// SelectAddrIdx - Given the specified addressed, check to see if it can be
/// represented as an indexed [r+r] operation. Returns false if it can
/// be represented by [r+imm], which are preferred.
- bool SelectAddrIdx(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectAddrIdx(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index) {
return PPCLowering.SelectAddressRegReg(N, Base, Index, *CurDAG);
}
/// SelectAddrIdxOnly - Given the specified addressed, force it to be
/// represented as an indexed [r+r] operation.
- bool SelectAddrIdxOnly(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectAddrIdxOnly(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index) {
return PPCLowering.SelectAddressRegRegOnly(N, Base, Index, *CurDAG);
}
@@ -136,7 +136,7 @@ namespace {
/// SelectAddrImmShift - Returns true if the address N can be represented by
/// a base register plus a signed 14-bit displacement [r+imm*4]. Suitable
/// for use by STD and friends.
- bool SelectAddrImmShift(SDValue Op, SDValue N, SDValue &Disp,
+ bool SelectAddrImmShift(SDNode *Op, SDValue N, SDValue &Disp,
SDValue &Base) {
return PPCLowering.SelectAddressRegImmShift(N, Disp, Base, *CurDAG);
}
@@ -180,7 +180,7 @@ namespace {
#include "PPCGenDAGISel.inc"
private:
- SDNode *SelectSETCC(SDValue Op);
+ SDNode *SelectSETCC(SDNode *N);
};
}
@@ -635,8 +635,7 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert, int &Other) {
return 0;
}
-SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) {
- SDNode *N = Op.getNode();
+SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
DebugLoc dl = N->getDebugLoc();
unsigned Imm;
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
@@ -756,9 +755,8 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) {
// Select - Convert the specified operand from a target-independent to a
// target-specific node if it hasn't already been changed.
-SDNode *PPCDAGToDAGISel::Select(SDValue Op) {
- SDNode *N = Op.getNode();
- DebugLoc dl = Op.getDebugLoc();
+SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
+ DebugLoc dl = N->getDebugLoc();
if (N->isMachineOpcode())
return NULL; // Already selected.
@@ -841,18 +839,18 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) {
}
case ISD::SETCC:
- return SelectSETCC(Op);
+ return SelectSETCC(N);
case PPCISD::GlobalBaseReg:
return getGlobalBaseReg();
case ISD::FrameIndex: {
int FI = cast<FrameIndexSDNode>(N)->getIndex();
- SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType());
- unsigned Opc = Op.getValueType() == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
+ SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0));
+ unsigned Opc = N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
if (N->hasOneUse())
- return CurDAG->SelectNodeTo(N, Opc, Op.getValueType(), TFI,
+ return CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), TFI,
getSmallIPtrImm(0));
- return CurDAG->getMachineNode(Opc, dl, Op.getValueType(), TFI,
+ return CurDAG->getMachineNode(Opc, dl, N->getValueType(0), TFI,
getSmallIPtrImm(0));
}
@@ -899,7 +897,7 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) {
case ISD::LOAD: {
// Handle preincrement loads.
- LoadSDNode *LD = cast<LoadSDNode>(Op);
+ LoadSDNode *LD = cast<LoadSDNode>(N);
EVT LoadedVT = LD->getMemoryVT();
// Normal loads are handled by code generated from the .td file.
@@ -1092,7 +1090,7 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) {
}
}
- return SelectCode(Op);
+ return SelectCode(N);
}
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index 8fe151a..842f8ee 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -430,9 +430,7 @@ let isCall = 1, PPC970_Unit = 7,
F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,
V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,
LR,CTR,
- CR0,CR1,CR5,CR6,CR7,
- CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ,
- CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN,CARRY] in {
+ CR0,CR1,CR5,CR6,CR7,CARRY] in {
// Convenient aliases for call instructions
let Uses = [RM] in {
def BL_Darwin : IForm<18, 0, 1,
@@ -457,9 +455,7 @@ let isCall = 1, PPC970_Unit = 7,
F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,
V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,
LR,CTR,
- CR0,CR1,CR5,CR6,CR7,
- CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ,
- CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN,CARRY] in {
+ CR0,CR1,CR5,CR6,CR7,CARRY] in {
// Convenient aliases for call instructions
let Uses = [RM] in {
def BL_SVR4 : IForm<18, 0, 1,
diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp
index be6e51e..daf4ec6 100644
--- a/lib/Target/PowerPC/PPCJITInfo.cpp
+++ b/lib/Target/PowerPC/PPCJITInfo.cpp
@@ -308,6 +308,7 @@ extern "C" void *PPCCompilationCallbackC(unsigned *StubCallAddrPlus4,
// Rewrite the stub with an unconditional branch to the target, for any users
// who took the address of the stub.
EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit);
+ sys::Memory::InvalidateInstructionCache(StubCallAddr, 7*4);
// Put the address of the target function to call and the address to return to
// after calling the target function in a place that is easy to get on the
@@ -441,4 +442,5 @@ void PPCJITInfo::relocate(void *Function, MachineRelocation *MR,
void PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit);
+ sys::Memory::InvalidateInstructionCache(Old, 7*4);
}
diff --git a/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
index c87879b..ee6deb5 100644
--- a/lib/Target/PowerPC/PPCMCAsmInfo.cpp
+++ b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
@@ -22,6 +22,7 @@ PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) {
if (!is64Bit)
Data64bitsDirective = 0; // We can't emit a 64-bit unit in PPC32 mode.
AssemblerDialect = 1; // New-Style mnemonics.
+ SupportsDebugInformation= true; // Debug information.
}
PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
diff --git a/lib/Target/PowerPC/README.txt b/lib/Target/PowerPC/README.txt
index f5e50fc..060d6a5 100644
--- a/lib/Target/PowerPC/README.txt
+++ b/lib/Target/PowerPC/README.txt
@@ -7,6 +7,39 @@ TODO:
===-------------------------------------------------------------------------===
+On PPC64, this:
+
+long f2 (long x) { return 0xfffffff000000000UL; }
+long f3 (long x) { return 0x1ffffffffUL; }
+
+could compile into:
+
+_f2:
+ li r3,-1
+ rldicr r3,r3,0,27
+ blr
+_f3:
+ li r3,-1
+ rldicl r3,r3,0,31
+ blr
+
+we produce:
+
+_f2:
+ lis r2, 4095
+ ori r2, r2, 65535
+ sldi r3, r2, 36
+ blr
+_f3:
+ li r2, 1
+ sldi r2, r2, 32
+ oris r2, r2, 65535
+ ori r3, r2, 65535
+ blr
+
+
+===-------------------------------------------------------------------------===
+
Support 'update' load/store instructions. These are cracked on the G5, but are
still a codesize win.
diff --git a/lib/Target/README.txt b/lib/Target/README.txt
index a6e05fa..69da35f 100644
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -282,19 +282,6 @@ this requires TBAA.
//===---------------------------------------------------------------------===//
-This should be optimized to one 'and' and one 'or', from PR4216:
-
-define i32 @test_bitfield(i32 %bf.prev.low) nounwind ssp {
-entry:
- %bf.prev.lo.cleared10 = or i32 %bf.prev.low, 32962 ; <i32> [#uses=1]
- %0 = and i32 %bf.prev.low, -65536 ; <i32> [#uses=1]
- %1 = and i32 %bf.prev.lo.cleared10, 40186 ; <i32> [#uses=1]
- %2 = or i32 %1, %0 ; <i32> [#uses=1]
- ret i32 %2
-}
-
-//===---------------------------------------------------------------------===//
-
This isn't recognized as bswap by instcombine (yes, it really is bswap):
unsigned long reverse(unsigned v) {
@@ -1661,38 +1648,9 @@ would delete the or instruction for us.
//===---------------------------------------------------------------------===//
-FunctionAttrs is not marking this function as readnone (just readonly):
-$ clang t.c -emit-llvm -S -o - -O0 | opt -mem2reg -S -functionattrs
-
-int t(int a, int b, int c) {
- int *p;
- if (a)
- p = &a;
- else
- p = &c;
- return *p;
-}
-
-This is because we codegen this to:
-
-define i32 @t(i32 %a, i32 %b, i32 %c) nounwind readonly ssp {
-entry:
- %a.addr = alloca i32 ; <i32*> [#uses=3]
- %c.addr = alloca i32 ; <i32*> [#uses=2]
-...
-
-if.end:
- %p.0 = phi i32* [ %a.addr, %if.then ], [ %c.addr, %if.else ]
- %tmp2 = load i32* %p.0 ; <i32> [#uses=1]
- ret i32 %tmp2
-}
-
-And functionattrs doesn't realize that the p.0 load points to function local
-memory.
-
-Also, functionattrs doesn't know about memcpy/memset. This function should be
-marked readnone, since it only twiddles local memory, but functionattrs doesn't
-handle memset/memcpy/memmove aggressively:
+functionattrs doesn't know much about memcpy/memset. This function should be
+marked readnone rather than readonly, since it only twiddles local memory, but
+functionattrs doesn't handle memset/memcpy/memmove aggressively:
struct X { int *p; int *q; };
int foo() {
diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
index b41917e..e1b3299 100644
--- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp
+++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
@@ -43,11 +43,11 @@ public:
TM(tm) {
}
- SDNode *Select(SDValue Op);
+ SDNode *Select(SDNode *N);
// Complex Pattern Selectors.
- bool SelectADDRrr(SDValue Op, SDValue N, SDValue &R1, SDValue &R2);
- bool SelectADDRri(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectADDRrr(SDNode *Op, SDValue N, SDValue &R1, SDValue &R2);
+ bool SelectADDRri(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Offset);
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
@@ -87,7 +87,7 @@ SDNode* SparcDAGToDAGISel::getGlobalBaseReg() {
return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
}
-bool SparcDAGToDAGISel::SelectADDRri(SDValue Op, SDValue Addr,
+bool SparcDAGToDAGISel::SelectADDRri(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Offset) {
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
@@ -128,7 +128,7 @@ bool SparcDAGToDAGISel::SelectADDRri(SDValue Op, SDValue Addr,
return true;
}
-bool SparcDAGToDAGISel::SelectADDRrr(SDValue Op, SDValue Addr,
+bool SparcDAGToDAGISel::SelectADDRrr(SDNode *Op, SDValue Addr,
SDValue &R1, SDValue &R2) {
if (Addr.getOpcode() == ISD::FrameIndex) return false;
if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
@@ -152,8 +152,7 @@ bool SparcDAGToDAGISel::SelectADDRrr(SDValue Op, SDValue Addr,
return true;
}
-SDNode *SparcDAGToDAGISel::Select(SDValue Op) {
- SDNode *N = Op.getNode();
+SDNode *SparcDAGToDAGISel::Select(SDNode *N) {
DebugLoc dl = N->getDebugLoc();
if (N->isMachineOpcode())
return NULL; // Already selected.
@@ -199,7 +198,7 @@ SDNode *SparcDAGToDAGISel::Select(SDValue Op) {
}
}
- return SelectCode(Op);
+ return SelectCode(N);
}
@@ -213,8 +212,8 @@ SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op,
switch (ConstraintCode) {
default: return true;
case 'm': // memory
- if (!SelectADDRrr(Op, Op, Op0, Op1))
- SelectADDRri(Op, Op, Op0, Op1);
+ if (!SelectADDRrr(Op.getNode(), Op, Op0, Op1))
+ SelectADDRri(Op.getNode(), Op, Op0, Op1);
break;
}
diff --git a/lib/Target/SubtargetFeature.cpp b/lib/Target/SubtargetFeature.cpp
index 590574e..7cc4fd1 100644
--- a/lib/Target/SubtargetFeature.cpp
+++ b/lib/Target/SubtargetFeature.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Target/SubtargetFeature.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/StringExtras.h"
#include <algorithm>
@@ -355,7 +356,7 @@ void SubtargetFeatures::print(raw_ostream &OS) const {
/// dump - Dump feature info.
///
void SubtargetFeatures::dump() const {
- print(errs());
+ print(dbgs());
}
/// getDefaultSubtargetFeatures - Return a string listing
diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index d64611d..7096c0e 100644
--- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -128,23 +128,23 @@ namespace {
#include "SystemZGenDAGISel.inc"
private:
- bool SelectAddrRI12Only(SDValue Op, SDValue& Addr,
+ bool SelectAddrRI12Only(SDNode *Op, SDValue& Addr,
SDValue &Base, SDValue &Disp);
- bool SelectAddrRI12(SDValue Op, SDValue& Addr,
+ bool SelectAddrRI12(SDNode *Op, SDValue& Addr,
SDValue &Base, SDValue &Disp,
bool is12BitOnly = false);
- bool SelectAddrRI(SDValue Op, SDValue& Addr,
+ bool SelectAddrRI(SDNode *Op, SDValue& Addr,
SDValue &Base, SDValue &Disp);
- bool SelectAddrRRI12(SDValue Op, SDValue Addr,
+ bool SelectAddrRRI12(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index);
- bool SelectAddrRRI20(SDValue Op, SDValue Addr,
+ bool SelectAddrRRI20(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index);
- bool SelectLAAddr(SDValue Op, SDValue Addr,
+ bool SelectLAAddr(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index);
- SDNode *Select(SDValue Op);
+ SDNode *Select(SDNode *Node);
- bool TryFoldLoad(SDValue P, SDValue N,
+ bool TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Disp, SDValue &Index);
bool MatchAddress(SDValue N, SystemZRRIAddressMode &AM,
@@ -367,12 +367,12 @@ void SystemZDAGToDAGISel::getAddressOperands(const SystemZRRIAddressMode &AM,
/// Returns true if the address can be represented by a base register plus
/// an unsigned 12-bit displacement [r+imm].
-bool SystemZDAGToDAGISel::SelectAddrRI12Only(SDValue Op, SDValue& Addr,
+bool SystemZDAGToDAGISel::SelectAddrRI12Only(SDNode *Op, SDValue& Addr,
SDValue &Base, SDValue &Disp) {
return SelectAddrRI12(Op, Addr, Base, Disp, /*is12BitOnly*/true);
}
-bool SystemZDAGToDAGISel::SelectAddrRI12(SDValue Op, SDValue& Addr,
+bool SystemZDAGToDAGISel::SelectAddrRI12(SDNode *Op, SDValue& Addr,
SDValue &Base, SDValue &Disp,
bool is12BitOnly) {
SystemZRRIAddressMode AM20(/*isRI*/true), AM12(/*isRI*/true);
@@ -422,7 +422,7 @@ bool SystemZDAGToDAGISel::SelectAddrRI12(SDValue Op, SDValue& Addr,
/// Returns true if the address can be represented by a base register plus
/// a signed 20-bit displacement [r+imm].
-bool SystemZDAGToDAGISel::SelectAddrRI(SDValue Op, SDValue& Addr,
+bool SystemZDAGToDAGISel::SelectAddrRI(SDNode *Op, SDValue& Addr,
SDValue &Base, SDValue &Disp) {
SystemZRRIAddressMode AM(/*isRI*/true);
bool Done = false;
@@ -465,7 +465,7 @@ bool SystemZDAGToDAGISel::SelectAddrRI(SDValue Op, SDValue& Addr,
/// Returns true if the address can be represented by a base register plus
/// index register plus an unsigned 12-bit displacement [base + idx + imm].
-bool SystemZDAGToDAGISel::SelectAddrRRI12(SDValue Op, SDValue Addr,
+bool SystemZDAGToDAGISel::SelectAddrRRI12(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index) {
SystemZRRIAddressMode AM20, AM12;
bool Done = false;
@@ -514,7 +514,7 @@ bool SystemZDAGToDAGISel::SelectAddrRRI12(SDValue Op, SDValue Addr,
/// Returns true if the address can be represented by a base register plus
/// index register plus a signed 20-bit displacement [base + idx + imm].
-bool SystemZDAGToDAGISel::SelectAddrRRI20(SDValue Op, SDValue Addr,
+bool SystemZDAGToDAGISel::SelectAddrRRI20(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index) {
SystemZRRIAddressMode AM;
bool Done = false;
@@ -558,7 +558,7 @@ bool SystemZDAGToDAGISel::SelectAddrRRI20(SDValue Op, SDValue Addr,
/// SelectLAAddr - it calls SelectAddr and determines if the maximal addressing
/// mode it matches can be cost effectively emitted as an LA/LAY instruction.
-bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Op, SDValue Addr,
+bool SystemZDAGToDAGISel::SelectLAAddr(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index) {
SystemZRRIAddressMode AM;
@@ -591,11 +591,11 @@ bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Op, SDValue Addr,
return false;
}
-bool SystemZDAGToDAGISel::TryFoldLoad(SDValue P, SDValue N,
+bool SystemZDAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Disp, SDValue &Index) {
if (ISD::isNON_EXTLoad(N.getNode()) &&
N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), P.getNode(), P.getNode()))
+ IsLegalAndProfitableToFold(N.getNode(), P, P))
return SelectAddrRRI20(P, N.getOperand(1), Base, Disp, Index);
return false;
}
@@ -612,10 +612,9 @@ void SystemZDAGToDAGISel::InstructionSelect() {
CurDAG->RemoveDeadNodes();
}
-SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
- SDNode *Node = Op.getNode();
+SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
EVT NVT = Node->getValueType(0);
- DebugLoc dl = Op.getDebugLoc();
+ DebugLoc dl = Node->getDebugLoc();
unsigned Opcode = Node->getOpcode();
// Dump information about the Node being selected
@@ -643,20 +642,20 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
EVT ResVT;
bool is32Bit = false;
switch (NVT.getSimpleVT().SimpleTy) {
- default: assert(0 && "Unsupported VT!");
- case MVT::i32:
- Opc = SystemZ::SDIVREM32r; MOpc = SystemZ::SDIVREM32m;
- ResVT = MVT::v2i64;
- is32Bit = true;
- break;
- case MVT::i64:
- Opc = SystemZ::SDIVREM64r; MOpc = SystemZ::SDIVREM64m;
- ResVT = MVT::v2i64;
- break;
+ default: assert(0 && "Unsupported VT!");
+ case MVT::i32:
+ Opc = SystemZ::SDIVREM32r; MOpc = SystemZ::SDIVREM32m;
+ ResVT = MVT::v2i64;
+ is32Bit = true;
+ break;
+ case MVT::i64:
+ Opc = SystemZ::SDIVREM64r; MOpc = SystemZ::SDIVREM64m;
+ ResVT = MVT::v2i64;
+ break;
}
SDValue Tmp0, Tmp1, Tmp2;
- bool foldedLoad = TryFoldLoad(Op, N1, Tmp0, Tmp1, Tmp2);
+ bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2);
// Prepare the dividend
SDNode *Dividend;
@@ -677,16 +676,16 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
SDValue DivVal = SDValue(Dividend, 0);
if (foldedLoad) {
SDValue Ops[] = { DivVal, Tmp0, Tmp1, Tmp2, N1.getOperand(0) };
- Result = CurDAG->getMachineNode(MOpc, dl, ResVT,
+ Result = CurDAG->getMachineNode(MOpc, dl, ResVT, MVT::Other,
Ops, array_lengthof(Ops));
// Update the chain.
- ReplaceUses(N1.getValue(1), SDValue(Result, 0));
+ ReplaceUses(N1.getValue(1), SDValue(Result, 1));
} else {
Result = CurDAG->getMachineNode(Opc, dl, ResVT, SDValue(Dividend, 0), N1);
}
// Copy the division (odd subreg) result, if it is needed.
- if (!Op.getValue(0).use_empty()) {
+ if (!SDValue(Node, 0).use_empty()) {
unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd);
SDNode *Div = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG,
dl, NVT,
@@ -694,14 +693,14 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
CurDAG->getTargetConstant(SubRegIdx,
MVT::i32));
- ReplaceUses(Op.getValue(0), SDValue(Div, 0));
+ ReplaceUses(SDValue(Node, 0), SDValue(Div, 0));
DEBUG(errs().indent(Indent-2) << "=> ";
Result->dump(CurDAG);
errs() << "\n");
}
// Copy the remainder (even subreg) result, if it is needed.
- if (!Op.getValue(1).use_empty()) {
+ if (!SDValue(Node, 1).use_empty()) {
unsigned SubRegIdx = (is32Bit ? subreg_even32 : subreg_even);
SDNode *Rem = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG,
dl, NVT,
@@ -709,7 +708,7 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
CurDAG->getTargetConstant(SubRegIdx,
MVT::i32));
- ReplaceUses(Op.getValue(1), SDValue(Rem, 0));
+ ReplaceUses(SDValue(Node, 1), SDValue(Rem, 0));
DEBUG(errs().indent(Indent-2) << "=> ";
Result->dump(CurDAG);
errs() << "\n");
@@ -729,22 +728,22 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
bool is32Bit = false;
switch (NVT.getSimpleVT().SimpleTy) {
- default: assert(0 && "Unsupported VT!");
- case MVT::i32:
- Opc = SystemZ::UDIVREM32r; MOpc = SystemZ::UDIVREM32m;
- ClrOpc = SystemZ::MOV64Pr0_even;
- ResVT = MVT::v2i32;
- is32Bit = true;
- break;
- case MVT::i64:
- Opc = SystemZ::UDIVREM64r; MOpc = SystemZ::UDIVREM64m;
- ClrOpc = SystemZ::MOV128r0_even;
- ResVT = MVT::v2i64;
- break;
+ default: assert(0 && "Unsupported VT!");
+ case MVT::i32:
+ Opc = SystemZ::UDIVREM32r; MOpc = SystemZ::UDIVREM32m;
+ ClrOpc = SystemZ::MOV64Pr0_even;
+ ResVT = MVT::v2i32;
+ is32Bit = true;
+ break;
+ case MVT::i64:
+ Opc = SystemZ::UDIVREM64r; MOpc = SystemZ::UDIVREM64m;
+ ClrOpc = SystemZ::MOV128r0_even;
+ ResVT = MVT::v2i64;
+ break;
}
SDValue Tmp0, Tmp1, Tmp2;
- bool foldedLoad = TryFoldLoad(Op, N1, Tmp0, Tmp1, Tmp2);
+ bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2);
// Prepare the dividend
SDNode *Dividend = N0.getNode();
@@ -767,37 +766,37 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
SDNode *Result;
if (foldedLoad) {
SDValue Ops[] = { DivVal, Tmp0, Tmp1, Tmp2, N1.getOperand(0) };
- Result = CurDAG->getMachineNode(MOpc, dl,ResVT,
+ Result = CurDAG->getMachineNode(MOpc, dl, ResVT, MVT::Other,
Ops, array_lengthof(Ops));
// Update the chain.
- ReplaceUses(N1.getValue(1), SDValue(Result, 0));
+ ReplaceUses(N1.getValue(1), SDValue(Result, 1));
} else {
Result = CurDAG->getMachineNode(Opc, dl, ResVT, DivVal, N1);
}
// Copy the division (odd subreg) result, if it is needed.
- if (!Op.getValue(0).use_empty()) {
+ if (!SDValue(Node, 0).use_empty()) {
unsigned SubRegIdx = (is32Bit ? subreg_odd32 : subreg_odd);
SDNode *Div = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG,
dl, NVT,
SDValue(Result, 0),
CurDAG->getTargetConstant(SubRegIdx,
MVT::i32));
- ReplaceUses(Op.getValue(0), SDValue(Div, 0));
+ ReplaceUses(SDValue(Node, 0), SDValue(Div, 0));
DEBUG(errs().indent(Indent-2) << "=> ";
Result->dump(CurDAG);
errs() << "\n");
}
// Copy the remainder (even subreg) result, if it is needed.
- if (!Op.getValue(1).use_empty()) {
+ if (!SDValue(Node, 1).use_empty()) {
unsigned SubRegIdx = (is32Bit ? subreg_even32 : subreg_even);
SDNode *Rem = CurDAG->getMachineNode(TargetInstrInfo::EXTRACT_SUBREG,
dl, NVT,
SDValue(Result, 0),
CurDAG->getTargetConstant(SubRegIdx,
MVT::i32));
- ReplaceUses(Op.getValue(1), SDValue(Rem, 0));
+ ReplaceUses(SDValue(Node, 1), SDValue(Rem, 0));
DEBUG(errs().indent(Indent-2) << "=> ";
Result->dump(CurDAG);
errs() << "\n");
@@ -812,11 +811,11 @@ SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
}
// Select the default instruction
- SDNode *ResNode = SelectCode(Op);
+ SDNode *ResNode = SelectCode(Node);
DEBUG(errs().indent(Indent-2) << "=> ";
- if (ResNode == NULL || ResNode == Op.getNode())
- Op.getNode()->dump(CurDAG);
+ if (ResNode == NULL || ResNode == Node)
+ Node->dump(CurDAG);
else
ResNode->dump(CurDAG);
errs() << "\n";
diff --git a/lib/Target/Target.cpp b/lib/Target/Target.cpp
index cddf49e..f5c969a 100644
--- a/lib/Target/Target.cpp
+++ b/lib/Target/Target.cpp
@@ -34,7 +34,7 @@ char *LLVMCopyStringRepOfTargetData(LLVMTargetDataRef TD) {
}
LLVMByteOrdering LLVMByteOrder(LLVMTargetDataRef TD) {
- return unwrap(TD)->isLittleEndian();
+ return unwrap(TD)->isLittleEndian() ? LLVMLittleEndian : LLVMBigEndian;
}
unsigned LLVMPointerSize(LLVMTargetDataRef TD) {
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index f887523..70e8008 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -21,11 +21,13 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mangler.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
using namespace llvm;
@@ -492,16 +494,15 @@ getELFKindForNamedSection(const char *Name, SectionKind K) {
}
-static unsigned
-getELFSectionType(const char *Name, SectionKind K) {
+static unsigned getELFSectionType(StringRef Name, SectionKind K) {
- if (strcmp(Name, ".init_array") == 0)
+ if (Name == ".init_array")
return MCSectionELF::SHT_INIT_ARRAY;
- if (strcmp(Name, ".fini_array") == 0)
+ if (Name == ".fini_array")
return MCSectionELF::SHT_FINI_ARRAY;
- if (strcmp(Name, ".preinit_array") == 0)
+ if (Name == ".preinit_array")
return MCSectionELF::SHT_PREINIT_ARRAY;
if (K.isBSS() || K.isThreadBSS())
@@ -577,10 +578,16 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
// into a 'uniqued' section name, create and return the section now.
if (GV->isWeakForLinker()) {
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
- std::string Name = Mang->makeNameProper(GV->getNameStr());
-
- return getELFSection((Prefix+Name).c_str(),
- getELFSectionType((Prefix+Name).c_str(), Kind),
+ SmallString<128> Name, MangledName;
+ Name.append(Prefix, Prefix+strlen(Prefix));
+ Mang->getNameWithPrefix(Name, GV, false);
+
+ raw_svector_ostream OS(MangledName);
+ MCSymbol::printMangledName(Name, OS, 0);
+ OS.flush();
+
+ return getELFSection(MangledName.str(),
+ getELFSectionType(MangledName.str(), Kind),
getELFSectionFlags(Kind),
Kind);
}
@@ -922,7 +929,7 @@ const MCSection *
TargetLoweringObjectFileMachO::getSectionForConstant(SectionKind Kind) const {
// If this constant requires a relocation, we have to put it in the data
// segment, not in the text segment.
- if (Kind.isDataRel())
+ if (Kind.isDataRel() || Kind.isReadOnlyWithRel())
return ConstDataSection;
if (Kind.isMergeableConst4())
@@ -983,7 +990,7 @@ TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() {
const MCSection *TargetLoweringObjectFileCOFF::
-getCOFFSection(const char *Name, bool isDirective, SectionKind Kind) const {
+getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const {
// Create the map if it doesn't already exist.
if (UniquingMap == 0)
UniquingMap = new MachOUniqueMapTy();
@@ -1078,8 +1085,9 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
// into a 'uniqued' section name, create and return the section now.
if (GV->isWeakForLinker()) {
const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind);
- std::string Name = Mang->makeNameProper(GV->getNameStr());
- return getCOFFSection((Prefix+Name).c_str(), false, Kind);
+ SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
+ Mang->getNameWithPrefix(Name, GV, false);
+ return getCOFFSection(Name.str(), false, Kind);
}
if (Kind.isText())
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index c357b4d..c4ae5d2 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Target/TargetAsmParser.h"
#include "X86.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
@@ -15,6 +16,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCParsedAsmOperand.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmParser.h"
@@ -46,7 +48,7 @@ private:
/// @name Auto-generated Match Functions
/// {
- bool MatchInstruction(SmallVectorImpl<X86Operand> &Operands,
+ bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCInst &Inst);
/// MatchRegisterName - Match the given string to a register name, or 0 if
@@ -59,7 +61,8 @@ public:
X86ATTAsmParser(const Target &T, MCAsmParser &_Parser)
: TargetAsmParser(T), Parser(_Parser) {}
- virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst);
+ virtual bool ParseInstruction(const StringRef &Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands);
virtual bool ParseDirective(AsmToken DirectiveID);
};
@@ -71,7 +74,7 @@ namespace {
/// X86Operand - Instances of this class represent a parsed X86 machine
/// instruction.
-struct X86Operand {
+struct X86Operand : public MCParsedAsmOperand {
enum {
Token,
Register,
@@ -400,10 +403,11 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
return false;
}
-bool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) {
- SmallVector<X86Operand, 8> Operands;
+bool X86ATTAsmParser::
+ParseInstruction(const StringRef &Name, SMLoc NameLoc,
+ SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- Operands.push_back(X86Operand::CreateToken(Name));
+ Operands.push_back(new X86Operand(X86Operand::CreateToken(Name)));
SMLoc Loc = getLexer().getTok().getLoc();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
@@ -411,31 +415,27 @@ bool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) {
// Parse '*' modifier.
if (getLexer().is(AsmToken::Star)) {
getLexer().Lex(); // Eat the star.
- Operands.push_back(X86Operand::CreateToken("*"));
+ Operands.push_back(new X86Operand(X86Operand::CreateToken("*")));
}
// Read the first operand.
- Operands.push_back(X86Operand());
- if (ParseOperand(Operands.back()))
+ X86Operand Op;
+ if (ParseOperand(Op))
return true;
+ Operands.push_back(new X86Operand(Op));
+
while (getLexer().is(AsmToken::Comma)) {
getLexer().Lex(); // Eat the comma.
// Parse and remember the operand.
- Operands.push_back(X86Operand());
- if (ParseOperand(Operands.back()))
+ if (ParseOperand(Op))
return true;
+ Operands.push_back(new X86Operand(Op));
}
}
- if (!MatchInstruction(Operands, Inst))
- return false;
-
- // FIXME: We should give nicer diagnostics about the exact failure.
-
- Error(Loc, "unrecognized instruction");
- return true;
+ return false;
}
bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index b88063f..70c6dd0 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -201,6 +201,7 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
/// jump tables, constant pools, global address and external symbols, all of
/// which print to a label with various suffixes for relocation types etc.
void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
+ SmallString<128> TempNameStr;
switch (MO.getType()) {
default: llvm_unreachable("unknown symbol type!");
case MachineOperand::MO_JumpTableIndex:
@@ -236,41 +237,38 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
- SmallString<128> NameStr;
- Mang->getNameWithPrefix(NameStr, GV, true);
- NameStr += "$non_lazy_ptr";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str());
+ Mang->getNameWithPrefix(TempNameStr, GV, true);
+ TempNameStr += "$non_lazy_ptr";
+ MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
if (StubSym == 0) {
- NameStr.clear();
- Mang->getNameWithPrefix(NameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+ TempNameStr.clear();
+ Mang->getNameWithPrefix(TempNameStr, GV, false);
+ StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
}
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
- SmallString<128> NameStr;
- Mang->getNameWithPrefix(NameStr, GV, true);
- NameStr += "$non_lazy_ptr";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str());
+ Mang->getNameWithPrefix(TempNameStr, GV, true);
+ TempNameStr += "$non_lazy_ptr";
+ MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(Sym);
if (StubSym == 0) {
- NameStr.clear();
- Mang->getNameWithPrefix(NameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+ TempNameStr.clear();
+ Mang->getNameWithPrefix(TempNameStr, GV, false);
+ StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
}
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
- SmallString<128> NameStr;
- Mang->getNameWithPrefix(NameStr, GV, true);
- NameStr += "$stub";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str());
+ Mang->getNameWithPrefix(TempNameStr, GV, true);
+ TempNameStr += "$stub";
+ MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
if (StubSym == 0) {
- NameStr.clear();
- Mang->getNameWithPrefix(NameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+ TempNameStr.clear();
+ Mang->getNameWithPrefix(TempNameStr, GV, false);
+ StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
}
}
@@ -285,24 +283,32 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
break;
}
case MachineOperand::MO_ExternalSymbol: {
- std::string Name = Mang->makeNameProper(MO.getSymbolName());
+ const MCSymbol *SymToPrint;
if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
- Name += "$stub";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(StringRef(Name));
+ Mang->getNameWithPrefix(TempNameStr,
+ StringRef(MO.getSymbolName())+"$stub");
+ const MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
if (StubSym == 0) {
- Name.erase(Name.end()-5, Name.end());
- StubSym = OutContext.GetOrCreateSymbol(StringRef(Name));
+ TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end());
+ StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
}
+ SymToPrint = StubSym;
+ } else {
+ Mang->getNameWithPrefix(TempNameStr, MO.getSymbolName());
+ SymToPrint = OutContext.GetOrCreateSymbol(TempNameStr.str());
}
// If the name begins with a dollar-sign, enclose it in parens. We do this
// to avoid having it look like an integer immediate to the assembler.
- if (Name[0] == '$')
- O << '(' << Name << ')';
- else
- O << Name;
+ if (SymToPrint->getName()[0] != '$')
+ SymToPrint->print(O, MAI);
+ else {
+ O << '(';
+ SymToPrint->print(O, MAI);
+ O << '(';
+ }
break;
}
}
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
index 1015b69..9ee118c 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
@@ -25,6 +25,7 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Mangler.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Analysis/DebugInfo.h"
using namespace llvm;
@@ -399,6 +400,14 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
OutMI.setOpcode(X86::MOVZX32rm16);
lower_subreg32(&OutMI, 0);
break;
+ case X86::MOV16r0:
+ OutMI.setOpcode(X86::MOV32r0);
+ lower_subreg32(&OutMI, 0);
+ break;
+ case X86::MOV64r0:
+ OutMI.setOpcode(X86::MOV32r0);
+ lower_subreg32(&OutMI, 0);
+ break;
}
}
@@ -412,6 +421,25 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
case TargetInstrInfo::GC_LABEL:
printLabel(MI);
return;
+ case TargetInstrInfo::DEBUG_VALUE: {
+ if (!VerboseAsm)
+ return;
+ O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
+ // cast away const; DIetc do not take const operands for some reason
+ DIVariable V((MDNode*)(MI->getOperand(2).getMetadata()));
+ O << V.getName();
+ O << " <- ";
+ if (MI->getOperand(0).getType()==MachineOperand::MO_Register)
+ printOperand(MI, 0);
+ else {
+ assert(MI->getOperand(0).getType()==MachineOperand::MO_Immediate);
+ int64_t imm = MI->getOperand(0).getImm();
+ O << '[' << ((imm<0) ? "EBP" : "ESP+") << imm << ']';
+ }
+ O << "+";
+ printOperand(MI, 1);
+ return;
+ }
case TargetInstrInfo::INLINEASM:
printInlineAsm(MI);
return;
diff --git a/lib/Target/X86/README-SSE.txt b/lib/Target/X86/README-SSE.txt
index 71ad51c..0f3e44b 100644
--- a/lib/Target/X86/README-SSE.txt
+++ b/lib/Target/X86/README-SSE.txt
@@ -916,3 +916,23 @@ cheaper to do fld1 than load from a constant pool for example, so
"load, add 1.0, store" is better done in the fp stack, etc.
//===---------------------------------------------------------------------===//
+
+The X86 backend should be able to if-convert SSE comparisons like "ucomisd" to
+"cmpsd". For example, this code:
+
+double d1(double x) { return x == x ? x : x + x; }
+
+Compiles into:
+
+_d1:
+ ucomisd %xmm0, %xmm0
+ jnp LBB1_2
+ addsd %xmm0, %xmm0
+ ret
+LBB1_2:
+ ret
+
+Also, the 'ret's should be shared. This is PR6032.
+
+//===---------------------------------------------------------------------===//
+
diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt
index afd9f53..aa7bb3d 100644
--- a/lib/Target/X86/README.txt
+++ b/lib/Target/X86/README.txt
@@ -530,7 +530,7 @@ We should inline lrintf and probably other libc functions.
//===---------------------------------------------------------------------===//
-Start using the flags more. For example, compile:
+Use the FLAGS values from arithmetic instructions more. For example, compile:
int add_zf(int *x, int y, int a, int b) {
if ((*x += y) == 0)
@@ -554,31 +554,8 @@ _add_zf:
movl %ecx, %eax
ret
-and:
-
-int add_zf(int *x, int y, int a, int b) {
- if ((*x + y) < 0)
- return a;
- else
- return b;
-}
-
-to:
-
-add_zf:
- addl (%rdi), %esi
- movl %edx, %eax
- cmovns %ecx, %eax
- ret
-
-instead of:
-
-_add_zf:
- addl (%rdi), %esi
- testl %esi, %esi
- cmovs %edx, %ecx
- movl %ecx, %eax
- ret
+As another example, compile function f2 in test/CodeGen/X86/cmp-test.ll
+without a test instruction.
//===---------------------------------------------------------------------===//
@@ -685,55 +662,6 @@ Though this probably isn't worth it.
//===---------------------------------------------------------------------===//
-We need to teach the codegen to convert two-address INC instructions to LEA
-when the flags are dead (likewise dec). For example, on X86-64, compile:
-
-int foo(int A, int B) {
- return A+1;
-}
-
-to:
-
-_foo:
- leal 1(%edi), %eax
- ret
-
-instead of:
-
-_foo:
- incl %edi
- movl %edi, %eax
- ret
-
-Another example is:
-
-;; X's live range extends beyond the shift, so the register allocator
-;; cannot coalesce it with Y. Because of this, a copy needs to be
-;; emitted before the shift to save the register value before it is
-;; clobbered. However, this copy is not needed if the register
-;; allocator turns the shift into an LEA. This also occurs for ADD.
-
-; Check that the shift gets turned into an LEA.
-; RUN: llvm-as < %s | llc -march=x86 -x86-asm-syntax=intel | \
-; RUN: not grep {mov E.X, E.X}
-
-@G = external global i32 ; <i32*> [#uses=3]
-
-define i32 @test1(i32 %X, i32 %Y) {
- %Z = add i32 %X, %Y ; <i32> [#uses=1]
- volatile store i32 %Y, i32* @G
- volatile store i32 %Z, i32* @G
- ret i32 %X
-}
-
-define i32 @test2(i32 %X) {
- %Z = add i32 %X, 1 ; <i32> [#uses=1]
- volatile store i32 %Z, i32* @G
- ret i32 %X
-}
-
-//===---------------------------------------------------------------------===//
-
Sometimes it is better to codegen subtractions from a constant (e.g. 7-x) with
a neg instead of a sub instruction. Consider:
@@ -854,11 +782,6 @@ __Z11no_overflowjj:
//===---------------------------------------------------------------------===//
-Re-materialize MOV32r0 etc. with xor instead of changing them to moves if the
-condition register is dead. xor reg reg is shorter than mov reg, #0.
-
-//===---------------------------------------------------------------------===//
-
The following code:
bb114.preheader: ; preds = %cond_next94
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
index a6e1ca3..7919559 100644
--- a/lib/Target/X86/X86.td
+++ b/lib/Target/X86/X86.td
@@ -23,6 +23,7 @@ include "llvm/Target/Target.td"
def FeatureCMOV : SubtargetFeature<"cmov","HasCMov", "true",
"Enable conditional move instructions">;
+
def FeatureMMX : SubtargetFeature<"mmx","X86SSELevel", "MMX",
"Enable MMX instructions">;
def FeatureSSE1 : SubtargetFeature<"sse", "X86SSELevel", "SSE1",
@@ -66,6 +67,9 @@ def FeatureFMA3 : SubtargetFeature<"fma3", "HasFMA3", "true",
"Enable three-operand fused multiple-add">;
def FeatureFMA4 : SubtargetFeature<"fma4", "HasFMA4", "true",
"Enable four-operand fused multiple-add">;
+def FeatureVectorUAMem : SubtargetFeature<"vector-unaligned-mem",
+ "HasVectorUAMem", "true",
+ "Allow unaligned memory operands on vector/SIMD instructions">;
//===----------------------------------------------------------------------===//
// X86 processors supported.
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index 4892e17..828e872 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -135,7 +135,7 @@ bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
IsPIC = TM.getRelocationModel() == Reloc::PIC_;
do {
- DEBUG(errs() << "JITTing function '"
+ DEBUG(dbgs() << "JITTing function '"
<< MF.getFunction()->getName() << "'\n");
MCE.startFunction(MF);
for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
@@ -477,7 +477,7 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
const TargetInstrDesc *Desc) {
- DEBUG(errs() << MI);
+ DEBUG(dbgs() << MI);
MCE.processDebugLoc(MI.getDebugLoc(), true);
@@ -618,11 +618,11 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
const MachineOperand &MO = MI.getOperand(CurOp++);
- DEBUG(errs() << "RawFrm CurOp " << CurOp << "\n");
- DEBUG(errs() << "isMBB " << MO.isMBB() << "\n");
- DEBUG(errs() << "isGlobal " << MO.isGlobal() << "\n");
- DEBUG(errs() << "isSymbol " << MO.isSymbol() << "\n");
- DEBUG(errs() << "isImm " << MO.isImm() << "\n");
+ DEBUG(dbgs() << "RawFrm CurOp " << CurOp << "\n");
+ DEBUG(dbgs() << "isMBB " << MO.isMBB() << "\n");
+ DEBUG(dbgs() << "isGlobal " << MO.isGlobal() << "\n");
+ DEBUG(dbgs() << "isSymbol " << MO.isSymbol() << "\n");
+ DEBUG(dbgs() << "isImm " << MO.isImm() << "\n");
if (MO.isMBB()) {
emitPCRelativeBlockAddress(MO.getMBB());
@@ -843,7 +843,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
if (!Desc->isVariadic() && CurOp != NumOps) {
#ifndef NDEBUG
- errs() << "Cannot encode all operands of: " << MI << "\n";
+ dbgs() << "Cannot encode all operands of: " << MI << "\n";
#endif
llvm_unreachable(0);
}
@@ -1082,9 +1082,9 @@ public:
}
if (!OK) {
- errs() << "couldn't convert inst '";
+ dbgs() << "couldn't convert inst '";
MI.dump();
- errs() << "' to machine instr:\n";
+ dbgs() << "' to machine instr:\n";
Instr->dump();
}
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 431c120..7e02d59 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -786,8 +786,8 @@ bool X86FastISel::X86SelectCmp(Instruction *I) {
bool X86FastISel::X86SelectZExt(Instruction *I) {
// Handle zero-extension from i1 to i8, which is common.
- if (I->getType() == Type::getInt8Ty(I->getContext()) &&
- I->getOperand(0)->getType() == Type::getInt1Ty(I->getContext())) {
+ if (I->getType()->isInteger(8) &&
+ I->getOperand(0)->getType()->isInteger(1)) {
unsigned ResultReg = getRegForValue(I->getOperand(0));
if (ResultReg == 0) return false;
// Set the high bits to zero.
@@ -948,7 +948,7 @@ bool X86FastISel::X86SelectBranch(Instruction *I) {
bool X86FastISel::X86SelectShift(Instruction *I) {
unsigned CReg = 0, OpReg = 0, OpImm = 0;
const TargetRegisterClass *RC = NULL;
- if (I->getType() == Type::getInt8Ty(I->getContext())) {
+ if (I->getType()->isInteger(8)) {
CReg = X86::CL;
RC = &X86::GR8RegClass;
switch (I->getOpcode()) {
@@ -957,7 +957,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
case Instruction::Shl: OpReg = X86::SHL8rCL; OpImm = X86::SHL8ri; break;
default: return false;
}
- } else if (I->getType() == Type::getInt16Ty(I->getContext())) {
+ } else if (I->getType()->isInteger(16)) {
CReg = X86::CX;
RC = &X86::GR16RegClass;
switch (I->getOpcode()) {
@@ -966,7 +966,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
case Instruction::Shl: OpReg = X86::SHL16rCL; OpImm = X86::SHL16ri; break;
default: return false;
}
- } else if (I->getType() == Type::getInt32Ty(I->getContext())) {
+ } else if (I->getType()->isInteger(32)) {
CReg = X86::ECX;
RC = &X86::GR32RegClass;
switch (I->getOpcode()) {
@@ -975,7 +975,7 @@ bool X86FastISel::X86SelectShift(Instruction *I) {
case Instruction::Shl: OpReg = X86::SHL32rCL; OpImm = X86::SHL32ri; break;
default: return false;
}
- } else if (I->getType() == Type::getInt64Ty(I->getContext())) {
+ } else if (I->getType()->isInteger(64)) {
CReg = X86::RCX;
RC = &X86::GR64RegClass;
switch (I->getOpcode()) {
@@ -1230,8 +1230,8 @@ bool X86FastISel::X86SelectCall(Instruction *I) {
CC != CallingConv::X86_FastCall)
return false;
- // On X86, -tailcallopt changes the fastcc ABI. FastISel doesn't
- // handle this for now.
+ // fastcc with -tailcallopt is intended to provide a guaranteed
+ // tail call optimization. Fastisel doesn't know how to do that.
if (CC == CallingConv::Fast && PerformTailCallOpt)
return false;
diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp
index 044bd4b..503ac14 100644
--- a/lib/Target/X86/X86FloatingPoint.cpp
+++ b/lib/Target/X86/X86FloatingPoint.cpp
@@ -75,12 +75,12 @@ namespace {
unsigned StackTop; // The current top of the FP stack.
void dumpStack() const {
- errs() << "Stack contents:";
+ dbgs() << "Stack contents:";
for (unsigned i = 0; i != StackTop; ++i) {
- errs() << " FP" << Stack[i];
+ dbgs() << " FP" << Stack[i];
assert(RegMap[Stack[i]] == i && "Stack[] doesn't match RegMap[]!");
}
- errs() << "\n";
+ dbgs() << "\n";
}
private:
/// isStackEmpty - Return true if the FP stack is empty.
@@ -246,7 +246,7 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
PrevMI = prior(I);
++NumFP; // Keep track of # of pseudo instrs
- DEBUG(errs() << "\nFPInst:\t" << *MI);
+ DEBUG(dbgs() << "\nFPInst:\t" << *MI);
// Get dead variables list now because the MI pointer may be deleted as part
// of processing!
@@ -273,7 +273,7 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
for (unsigned i = 0, e = DeadRegs.size(); i != e; ++i) {
unsigned Reg = DeadRegs[i];
if (Reg >= X86::FP0 && Reg <= X86::FP6) {
- DEBUG(errs() << "Register FP#" << Reg-X86::FP0 << " is dead!\n");
+ DEBUG(dbgs() << "Register FP#" << Reg-X86::FP0 << " is dead!\n");
freeStackSlotAfter(I, Reg-X86::FP0);
}
}
@@ -282,13 +282,13 @@ bool FPS::processBasicBlock(MachineFunction &MF, MachineBasicBlock &BB) {
DEBUG(
MachineBasicBlock::iterator PrevI(PrevMI);
if (I == PrevI) {
- errs() << "Just deleted pseudo instruction\n";
+ dbgs() << "Just deleted pseudo instruction\n";
} else {
MachineBasicBlock::iterator Start = I;
// Rewind to first instruction newly inserted.
while (Start != BB.begin() && prior(Start) != PrevI) --Start;
- errs() << "Inserted instructions:\n\t";
- Start->print(errs(), &MF.getTarget());
+ dbgs() << "Inserted instructions:\n\t";
+ Start->print(dbgs(), &MF.getTarget());
while (++Start != llvm::next(I)) {}
}
dumpStack();
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index cb82383..e2a53d1 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -113,37 +113,37 @@ namespace {
}
void dump() {
- errs() << "X86ISelAddressMode " << this << '\n';
- errs() << "Base.Reg ";
+ dbgs() << "X86ISelAddressMode " << this << '\n';
+ dbgs() << "Base.Reg ";
if (Base.Reg.getNode() != 0)
Base.Reg.getNode()->dump();
else
- errs() << "nul";
- errs() << " Base.FrameIndex " << Base.FrameIndex << '\n'
+ dbgs() << "nul";
+ dbgs() << " Base.FrameIndex " << Base.FrameIndex << '\n'
<< " Scale" << Scale << '\n'
<< "IndexReg ";
if (IndexReg.getNode() != 0)
IndexReg.getNode()->dump();
else
- errs() << "nul";
- errs() << " Disp " << Disp << '\n'
+ dbgs() << "nul";
+ dbgs() << " Disp " << Disp << '\n'
<< "GV ";
if (GV)
GV->dump();
else
- errs() << "nul";
- errs() << " CP ";
+ dbgs() << "nul";
+ dbgs() << " CP ";
if (CP)
CP->dump();
else
- errs() << "nul";
- errs() << '\n'
+ dbgs() << "nul";
+ dbgs() << '\n'
<< "ES ";
if (ES)
- errs() << ES;
+ dbgs() << ES;
else
- errs() << "nul";
- errs() << " JT" << JT << " Align" << Align << '\n';
+ dbgs() << "nul";
+ dbgs() << " JT" << JT << " Align" << Align << '\n';
}
};
}
@@ -190,7 +190,7 @@ namespace {
#include "X86GenDAGISel.inc"
private:
- SDNode *Select(SDValue N);
+ SDNode *Select(SDNode *N);
SDNode *SelectAtomic64(SDNode *Node, unsigned Opc);
SDNode *SelectAtomicLoadAdd(SDNode *Node, EVT NVT);
@@ -201,19 +201,19 @@ namespace {
bool MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
unsigned Depth);
bool MatchAddressBase(SDValue N, X86ISelAddressMode &AM);
- bool SelectAddr(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment);
- bool SelectLEAAddr(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectLEAAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp);
- bool SelectTLSADDRAddr(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp);
- bool SelectScalarSSELoad(SDValue Op, SDValue Pred,
+ bool SelectScalarSSELoad(SDNode *Op, SDValue Pred,
SDValue N, SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment,
SDValue &InChain, SDValue &OutChain);
- bool TryFoldLoad(SDValue P, SDValue N,
+ bool TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment);
@@ -310,6 +310,11 @@ bool X86DAGToDAGISel::IsLegalAndProfitableToFold(SDNode *N, SDNode *U,
if (U == Root)
switch (U->getOpcode()) {
default: break;
+ case X86ISD::ADD:
+ case X86ISD::SUB:
+ case X86ISD::AND:
+ case X86ISD::XOR:
+ case X86ISD::OR:
case ISD::ADD:
case ISD::ADDC:
case ISD::ADDE:
@@ -675,12 +680,12 @@ void X86DAGToDAGISel::InstructionSelect() {
// Codegen the basic block.
#ifndef NDEBUG
- DEBUG(errs() << "===== Instruction selection begins:\n");
+ DEBUG(dbgs() << "===== Instruction selection begins:\n");
Indent = 0;
#endif
SelectRoot(*CurDAG);
#ifndef NDEBUG
- DEBUG(errs() << "===== Instruction selection ends:\n");
+ DEBUG(dbgs() << "===== Instruction selection ends:\n");
#endif
CurDAG->RemoveDeadNodes();
@@ -850,7 +855,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
bool is64Bit = Subtarget->is64Bit();
DebugLoc dl = N.getDebugLoc();
DEBUG({
- errs() << "MatchAddress: ";
+ dbgs() << "MatchAddress: ";
AM.dump();
});
// Limit recursion.
@@ -1268,7 +1273,7 @@ bool X86DAGToDAGISel::MatchAddressBase(SDValue N, X86ISelAddressMode &AM) {
/// SelectAddr - returns true if it is able pattern match an addressing mode.
/// It returns the operands which make up the maximal addressing mode it can
/// match by reference.
-bool X86DAGToDAGISel::SelectAddr(SDValue Op, SDValue N, SDValue &Base,
+bool X86DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index,
SDValue &Disp, SDValue &Segment) {
X86ISelAddressMode AM;
@@ -1291,7 +1296,7 @@ bool X86DAGToDAGISel::SelectAddr(SDValue Op, SDValue N, SDValue &Base,
/// SelectScalarSSELoad - Match a scalar SSE load. In particular, we want to
/// match a load whose top elements are either undef or zeros. The load flavor
/// is derived from the type of N, which is either v4f32 or v2f64.
-bool X86DAGToDAGISel::SelectScalarSSELoad(SDValue Op, SDValue Pred,
+bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Op, SDValue Pred,
SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index,
SDValue &Disp, SDValue &Segment,
@@ -1302,7 +1307,7 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDValue Op, SDValue Pred,
if (ISD::isNON_EXTLoad(InChain.getNode()) &&
InChain.getValue(0).hasOneUse() &&
N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), Pred.getNode(), Op.getNode())) {
+ IsLegalAndProfitableToFold(N.getNode(), Pred.getNode(), Op)) {
LoadSDNode *LD = cast<LoadSDNode>(InChain);
if (!SelectAddr(Op, LD->getBasePtr(), Base, Scale, Index, Disp, Segment))
return false;
@@ -1333,7 +1338,7 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDValue Op, SDValue Pred,
/// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing
/// mode it matches can be cost effectively emitted as an LEA instruction.
-bool X86DAGToDAGISel::SelectLEAAddr(SDValue Op, SDValue N,
+bool X86DAGToDAGISel::SelectLEAAddr(SDNode *Op, SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp) {
X86ISelAddressMode AM;
@@ -1395,10 +1400,10 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDValue Op, SDValue N,
}
/// SelectTLSADDRAddr - This is only run on TargetGlobalTLSAddress nodes.
-bool X86DAGToDAGISel::SelectTLSADDRAddr(SDValue Op, SDValue N, SDValue &Base,
+bool X86DAGToDAGISel::SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index,
SDValue &Disp) {
- assert(Op.getOpcode() == X86ISD::TLSADDR);
+ assert(Op->getOpcode() == X86ISD::TLSADDR);
assert(N.getOpcode() == ISD::TargetGlobalTLSAddress);
const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
@@ -1421,13 +1426,13 @@ bool X86DAGToDAGISel::SelectTLSADDRAddr(SDValue Op, SDValue N, SDValue &Base,
}
-bool X86DAGToDAGISel::TryFoldLoad(SDValue P, SDValue N,
+bool X86DAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment) {
if (ISD::isNON_EXTLoad(N.getNode()) &&
N.hasOneUse() &&
- IsLegalAndProfitableToFold(N.getNode(), P.getNode(), P.getNode()))
+ IsLegalAndProfitableToFold(N.getNode(), P, P))
return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp, Segment);
return false;
}
@@ -1454,7 +1459,7 @@ SDNode *X86DAGToDAGISel::SelectAtomic64(SDNode *Node, unsigned Opc) {
SDValue In2L = Node->getOperand(2);
SDValue In2H = Node->getOperand(3);
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
- if (!SelectAddr(In1, In1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
+ if (!SelectAddr(In1.getNode(), In1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
return NULL;
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = cast<MemSDNode>(Node)->getMemOperand();
@@ -1480,7 +1485,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {
SDValue Ptr = Node->getOperand(1);
SDValue Val = Node->getOperand(2);
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
- if (!SelectAddr(Ptr, Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
+ if (!SelectAddr(Ptr.getNode(), Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
return 0;
bool isInc = false, isDec = false, isSub = false, isCN = false;
@@ -1678,8 +1683,7 @@ static bool HasNoSignedComparisonUses(SDNode *N) {
return true;
}
-SDNode *X86DAGToDAGISel::Select(SDValue N) {
- SDNode *Node = N.getNode();
+SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
EVT NVT = Node->getValueType(0);
unsigned Opc, MOpc;
unsigned Opcode = Node->getOpcode();
@@ -1687,9 +1691,9 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
#ifndef NDEBUG
DEBUG({
- errs() << std::string(Indent, ' ') << "Selecting: ";
+ dbgs() << std::string(Indent, ' ') << "Selecting: ";
Node->dump(CurDAG);
- errs() << '\n';
+ dbgs() << '\n';
});
Indent += 2;
#endif
@@ -1697,9 +1701,9 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
if (Node->isMachineOpcode()) {
#ifndef NDEBUG
DEBUG({
- errs() << std::string(Indent-2, ' ') << "== ";
+ dbgs() << std::string(Indent-2, ' ') << "== ";
Node->dump(CurDAG);
- errs() << '\n';
+ dbgs() << '\n';
});
Indent -= 2;
#endif
@@ -1767,10 +1771,10 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
}
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
- bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
+ bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
// Multiply is commmutative.
if (!foldedLoad) {
- foldedLoad = TryFoldLoad(N, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
+ foldedLoad = TryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
if (foldedLoad)
std::swap(N0, N1);
}
@@ -1793,21 +1797,21 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
}
// Copy the low half of the result, if it is needed.
- if (!N.getValue(0).use_empty()) {
+ if (!SDValue(Node, 0).use_empty()) {
SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
LoReg, NVT, InFlag);
InFlag = Result.getValue(2);
- ReplaceUses(N.getValue(0), Result);
+ ReplaceUses(SDValue(Node, 0), Result);
#ifndef NDEBUG
DEBUG({
- errs() << std::string(Indent-2, ' ') << "=> ";
+ dbgs() << std::string(Indent-2, ' ') << "=> ";
Result.getNode()->dump(CurDAG);
- errs() << '\n';
+ dbgs() << '\n';
});
#endif
}
// Copy the high half of the result, if it is needed.
- if (!N.getValue(1).use_empty()) {
+ if (!SDValue(Node, 1).use_empty()) {
SDValue Result;
if (HiReg == X86::AH && Subtarget->is64Bit()) {
// Prevent use of AH in a REX instruction by referencing AX instead.
@@ -1826,12 +1830,12 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
HiReg, NVT, InFlag);
InFlag = Result.getValue(2);
}
- ReplaceUses(N.getValue(1), Result);
+ ReplaceUses(SDValue(Node, 1), Result);
#ifndef NDEBUG
DEBUG({
- errs() << std::string(Indent-2, ' ') << "=> ";
+ dbgs() << std::string(Indent-2, ' ') << "=> ";
Result.getNode()->dump(CurDAG);
- errs() << '\n';
+ dbgs() << '\n';
});
#endif
}
@@ -1869,7 +1873,6 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
unsigned LoReg, HiReg, ClrReg;
unsigned ClrOpcode, SExtOpcode;
- EVT ClrVT = NVT;
switch (NVT.getSimpleVT().SimpleTy) {
default: llvm_unreachable("Unsupported VT!");
case MVT::i8:
@@ -1879,7 +1882,7 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
break;
case MVT::i16:
LoReg = X86::AX; HiReg = X86::DX;
- ClrOpcode = X86::MOV32r0; ClrReg = X86::EDX; ClrVT = MVT::i32;
+ ClrOpcode = X86::MOV16r0; ClrReg = X86::DX;
SExtOpcode = X86::CWD;
break;
case MVT::i32:
@@ -1889,13 +1892,13 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
break;
case MVT::i64:
LoReg = X86::RAX; ClrReg = HiReg = X86::RDX;
- ClrOpcode = ~0U; // NOT USED.
+ ClrOpcode = X86::MOV64r0;
SExtOpcode = X86::CQO;
break;
}
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
- bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
+ bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4);
bool signBitIsZero = CurDAG->SignBitIsZero(N0);
SDValue InFlag;
@@ -1903,7 +1906,7 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
// Special case for div8, just use a move with zero extension to AX to
// clear the upper 8 bits (AH).
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, Move, Chain;
- if (TryFoldLoad(N, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
+ if (TryFoldLoad(Node, N0, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, N0.getOperand(0) };
Move =
SDValue(CurDAG->getMachineNode(X86::MOVZX16rm8, dl, MVT::i16,
@@ -1928,24 +1931,8 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
SDValue(CurDAG->getMachineNode(SExtOpcode, dl, MVT::Flag, InFlag),0);
} else {
// Zero out the high part, effectively zero extending the input.
- SDValue ClrNode;
-
- if (NVT.getSimpleVT() == MVT::i64) {
- ClrNode = SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, MVT::i32),
- 0);
- // We just did a 32-bit clear, insert it into a 64-bit register to
- // clear the whole 64-bit reg.
- SDValue Zero = CurDAG->getTargetConstant(0, MVT::i64);
- SDValue SubRegNo =
- CurDAG->getTargetConstant(X86::SUBREG_32BIT, MVT::i32);
- ClrNode =
- SDValue(CurDAG->getMachineNode(TargetInstrInfo::SUBREG_TO_REG, dl,
- MVT::i64, Zero, ClrNode, SubRegNo),
- 0);
- } else {
- ClrNode = SDValue(CurDAG->getMachineNode(ClrOpcode, dl, ClrVT), 0);
- }
-
+ SDValue ClrNode =
+ SDValue(CurDAG->getMachineNode(ClrOpcode, dl, NVT), 0);
InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, ClrReg,
ClrNode, InFlag).getValue(1);
}
@@ -1966,21 +1953,21 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
}
// Copy the division (low) result, if it is needed.
- if (!N.getValue(0).use_empty()) {
+ if (!SDValue(Node, 0).use_empty()) {
SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
LoReg, NVT, InFlag);
InFlag = Result.getValue(2);
- ReplaceUses(N.getValue(0), Result);
+ ReplaceUses(SDValue(Node, 0), Result);
#ifndef NDEBUG
DEBUG({
- errs() << std::string(Indent-2, ' ') << "=> ";
+ dbgs() << std::string(Indent-2, ' ') << "=> ";
Result.getNode()->dump(CurDAG);
- errs() << '\n';
+ dbgs() << '\n';
});
#endif
}
// Copy the remainder (high) result, if it is needed.
- if (!N.getValue(1).use_empty()) {
+ if (!SDValue(Node, 1).use_empty()) {
SDValue Result;
if (HiReg == X86::AH && Subtarget->is64Bit()) {
// Prevent use of AH in a REX instruction by referencing AX instead.
@@ -2000,12 +1987,12 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
HiReg, NVT, InFlag);
InFlag = Result.getValue(2);
}
- ReplaceUses(N.getValue(1), Result);
+ ReplaceUses(SDValue(Node, 1), Result);
#ifndef NDEBUG
DEBUG({
- errs() << std::string(Indent-2, ' ') << "=> ";
+ dbgs() << std::string(Indent-2, ' ') << "=> ";
Result.getNode()->dump(CurDAG);
- errs() << '\n';
+ dbgs() << '\n';
});
#endif
}
@@ -2124,16 +2111,16 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) {
}
}
- SDNode *ResNode = SelectCode(N);
+ SDNode *ResNode = SelectCode(Node);
#ifndef NDEBUG
DEBUG({
- errs() << std::string(Indent-2, ' ') << "=> ";
- if (ResNode == NULL || ResNode == N.getNode())
- N.getNode()->dump(CurDAG);
+ dbgs() << std::string(Indent-2, ' ') << "=> ";
+ if (ResNode == NULL || ResNode == Node)
+ Node->dump(CurDAG);
else
ResNode->dump(CurDAG);
- errs() << '\n';
+ dbgs() << '\n';
});
Indent -= 2;
#endif
@@ -2150,7 +2137,7 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
case 'v': // not offsetable ??
default: return true;
case 'm': // memory
- if (!SelectAddr(Op, Op, Op0, Op1, Op2, Op3, Op4))
+ if (!SelectAddr(Op.getNode(), Op, Op0, Op1, Op2, Op3, Op4))
return true;
break;
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index c722fbf..228ec9f 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -978,6 +978,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
setTargetDAGCombine(ISD::SHL);
setTargetDAGCombine(ISD::SRA);
setTargetDAGCombine(ISD::SRL);
+ setTargetDAGCombine(ISD::OR);
setTargetDAGCombine(ISD::STORE);
setTargetDAGCombine(ISD::MEMBARRIER);
setTargetDAGCombine(ISD::ZERO_EXTEND);
@@ -2077,10 +2078,10 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
assert(((Callee.getOpcode() == ISD::Register &&
(cast<RegisterSDNode>(Callee)->getReg() == X86::EAX ||
- cast<RegisterSDNode>(Callee)->getReg() == X86::R9)) ||
+ cast<RegisterSDNode>(Callee)->getReg() == X86::R11)) ||
Callee.getOpcode() == ISD::TargetExternalSymbol ||
Callee.getOpcode() == ISD::TargetGlobalAddress) &&
- "Expecting an global address, external symbol, or register");
+ "Expecting a global address, external symbol, or scratch register");
return DAG.getNode(X86ISD::TC_RETURN, dl,
NodeTys, &Ops[0], Ops.size());
@@ -5610,13 +5611,21 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC,
// because a TEST instruction will be better.
bool NonFlagUse = false;
for (SDNode::use_iterator UI = Op.getNode()->use_begin(),
- UE = Op.getNode()->use_end(); UI != UE; ++UI)
- if (UI->getOpcode() != ISD::BRCOND &&
- UI->getOpcode() != ISD::SELECT &&
- UI->getOpcode() != ISD::SETCC) {
+ UE = Op.getNode()->use_end(); UI != UE; ++UI) {
+ SDNode *User = *UI;
+ unsigned UOpNo = UI.getOperandNo();
+ if (User->getOpcode() == ISD::TRUNCATE && User->hasOneUse()) {
+ // Look pass truncate.
+ UOpNo = User->use_begin().getOperandNo();
+ User = *User->use_begin();
+ }
+ if (User->getOpcode() != ISD::BRCOND &&
+ User->getOpcode() != ISD::SETCC &&
+ (User->getOpcode() != ISD::SELECT || UOpNo != 0)) {
NonFlagUse = true;
break;
}
+ }
if (!NonFlagUse)
break;
}
@@ -5680,6 +5689,56 @@ SDValue X86TargetLowering::EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC,
return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op0, Op1);
}
+/// LowerToBT - Result of 'and' is compared against zero. Turn it into a BT node
+/// if it's possible.
+static SDValue LowerToBT(SDValue Op0, ISD::CondCode CC,
+ DebugLoc dl, SelectionDAG &DAG) {
+ SDValue LHS, RHS;
+ if (Op0.getOperand(1).getOpcode() == ISD::SHL) {
+ if (ConstantSDNode *Op010C =
+ dyn_cast<ConstantSDNode>(Op0.getOperand(1).getOperand(0)))
+ if (Op010C->getZExtValue() == 1) {
+ LHS = Op0.getOperand(0);
+ RHS = Op0.getOperand(1).getOperand(1);
+ }
+ } else if (Op0.getOperand(0).getOpcode() == ISD::SHL) {
+ if (ConstantSDNode *Op000C =
+ dyn_cast<ConstantSDNode>(Op0.getOperand(0).getOperand(0)))
+ if (Op000C->getZExtValue() == 1) {
+ LHS = Op0.getOperand(1);
+ RHS = Op0.getOperand(0).getOperand(1);
+ }
+ } else if (Op0.getOperand(1).getOpcode() == ISD::Constant) {
+ ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op0.getOperand(1));
+ SDValue AndLHS = Op0.getOperand(0);
+ if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) {
+ LHS = AndLHS.getOperand(0);
+ RHS = AndLHS.getOperand(1);
+ }
+ }
+
+ if (LHS.getNode()) {
+ // If LHS is i8, promote it to i16 with any_extend. There is no i8 BT
+ // instruction. Since the shift amount is in-range-or-undefined, we know
+ // that doing a bittest on the i16 value is ok. We extend to i32 because
+ // the encoding for the i16 version is larger than the i32 version.
+ if (LHS.getValueType() == MVT::i8)
+ LHS = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS);
+
+ // If the operand types disagree, extend the shift amount to match. Since
+ // BT ignores high bits (like shifts) we can use anyextend.
+ if (LHS.getValueType() != RHS.getValueType())
+ RHS = DAG.getNode(ISD::ANY_EXTEND, dl, LHS.getValueType(), RHS);
+
+ SDValue BT = DAG.getNode(X86ISD::BT, dl, MVT::i32, LHS, RHS);
+ unsigned Cond = CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B;
+ return DAG.getNode(X86ISD::SETCC, dl, MVT::i8,
+ DAG.getConstant(Cond, MVT::i8), BT);
+ }
+
+ return SDValue();
+}
+
SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer");
SDValue Op0 = Op.getOperand(0);
@@ -5687,6 +5746,7 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
DebugLoc dl = Op.getDebugLoc();
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
+ // Optimize to BT if possible.
// Lower (X & (1 << N)) == 0 to BT(X, N).
// Lower ((X >>u N) & 1) != 0 to BT(X, N).
// Lower ((X >>s N) & 1) != 0 to BT(X, N).
@@ -5695,48 +5755,9 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
Op1.getOpcode() == ISD::Constant &&
cast<ConstantSDNode>(Op1)->getZExtValue() == 0 &&
(CC == ISD::SETEQ || CC == ISD::SETNE)) {
- SDValue LHS, RHS;
- if (Op0.getOperand(1).getOpcode() == ISD::SHL) {
- if (ConstantSDNode *Op010C =
- dyn_cast<ConstantSDNode>(Op0.getOperand(1).getOperand(0)))
- if (Op010C->getZExtValue() == 1) {
- LHS = Op0.getOperand(0);
- RHS = Op0.getOperand(1).getOperand(1);
- }
- } else if (Op0.getOperand(0).getOpcode() == ISD::SHL) {
- if (ConstantSDNode *Op000C =
- dyn_cast<ConstantSDNode>(Op0.getOperand(0).getOperand(0)))
- if (Op000C->getZExtValue() == 1) {
- LHS = Op0.getOperand(1);
- RHS = Op0.getOperand(0).getOperand(1);
- }
- } else if (Op0.getOperand(1).getOpcode() == ISD::Constant) {
- ConstantSDNode *AndRHS = cast<ConstantSDNode>(Op0.getOperand(1));
- SDValue AndLHS = Op0.getOperand(0);
- if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) {
- LHS = AndLHS.getOperand(0);
- RHS = AndLHS.getOperand(1);
- }
- }
-
- if (LHS.getNode()) {
- // If LHS is i8, promote it to i16 with any_extend. There is no i8 BT
- // instruction. Since the shift amount is in-range-or-undefined, we know
- // that doing a bittest on the i16 value is ok. We extend to i32 because
- // the encoding for the i16 version is larger than the i32 version.
- if (LHS.getValueType() == MVT::i8)
- LHS = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, LHS);
-
- // If the operand types disagree, extend the shift amount to match. Since
- // BT ignores high bits (like shifts) we can use anyextend.
- if (LHS.getValueType() != RHS.getValueType())
- RHS = DAG.getNode(ISD::ANY_EXTEND, dl, LHS.getValueType(), RHS);
-
- SDValue BT = DAG.getNode(X86ISD::BT, dl, MVT::i32, LHS, RHS);
- unsigned Cond = CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B;
- return DAG.getNode(X86ISD::SETCC, dl, MVT::i8,
- DAG.getConstant(Cond, MVT::i8), BT);
- }
+ SDValue NewSetCC = LowerToBT(Op0, CC, dl, DAG);
+ if (NewSetCC.getNode())
+ return NewSetCC;
}
bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
@@ -5936,6 +5957,23 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
}
if (addTest) {
+ // Look pass the truncate.
+ if (Cond.getOpcode() == ISD::TRUNCATE)
+ Cond = Cond.getOperand(0);
+
+ // We know the result of AND is compared against zero. Try to match
+ // it to BT.
+ if (Cond.getOpcode() == ISD::AND && Cond.hasOneUse()) {
+ SDValue NewSetCC = LowerToBT(Cond, ISD::SETNE, dl, DAG);
+ if (NewSetCC.getNode()) {
+ CC = NewSetCC.getOperand(0);
+ Cond = NewSetCC.getOperand(1);
+ addTest = false;
+ }
+ }
+ }
+
+ if (addTest) {
CC = DAG.getConstant(X86::COND_NE, MVT::i8);
Cond = EmitTest(Cond, X86::COND_NE, DAG);
}
@@ -6093,6 +6131,23 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
}
if (addTest) {
+ // Look pass the truncate.
+ if (Cond.getOpcode() == ISD::TRUNCATE)
+ Cond = Cond.getOperand(0);
+
+ // We know the result of AND is compared against zero. Try to match
+ // it to BT.
+ if (Cond.getOpcode() == ISD::AND && Cond.hasOneUse()) {
+ SDValue NewSetCC = LowerToBT(Cond, ISD::SETNE, dl, DAG);
+ if (NewSetCC.getNode()) {
+ CC = NewSetCC.getOperand(0);
+ Cond = NewSetCC.getOperand(1);
+ addTest = false;
+ }
+ }
+ }
+
+ if (addTest) {
CC = DAG.getConstant(X86::COND_NE, MVT::i8);
Cond = EmitTest(Cond, X86::COND_NE, DAG);
}
@@ -7524,8 +7579,7 @@ bool X86TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
bool X86TargetLowering::isZExtFree(const Type *Ty1, const Type *Ty2) const {
// x86-64 implicitly zero-extends 32-bit results in 64-bit registers.
- return Ty1 == Type::getInt32Ty(Ty1->getContext()) &&
- Ty2 == Type::getInt64Ty(Ty1->getContext()) && Subtarget->is64Bit();
+ return Ty1->isInteger(64) && Ty2->isInteger(64) && Subtarget->is64Bit();
}
bool X86TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
@@ -7749,7 +7803,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
for (int i=0; i < 2 + X86AddrNumOperands; ++i)
argOpers[i] = &bInstr->getOperand(i+2);
- // x86 address has 4 operands: base, index, scale, and displacement
+ // x86 address has 5 operands: base, index, scale, displacement, and segment.
int lastAddrIndx = X86AddrNumOperands - 1; // [0,3]
unsigned t1 = F->getRegInfo().createVirtualRegister(RC);
@@ -7777,14 +7831,16 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
BuildMI(newMBB, dl, TII->get(X86::PHI), dest2Oper.getReg())
.addReg(t2).addMBB(thisMBB).addReg(t4).addMBB(newMBB);
- unsigned tt1 = F->getRegInfo().createVirtualRegister(RC);
- unsigned tt2 = F->getRegInfo().createVirtualRegister(RC);
+ // The subsequent operations should be using the destination registers of
+ //the PHI instructions.
if (invSrc) {
- MIB = BuildMI(newMBB, dl, TII->get(NotOpc), tt1).addReg(t1);
- MIB = BuildMI(newMBB, dl, TII->get(NotOpc), tt2).addReg(t2);
+ t1 = F->getRegInfo().createVirtualRegister(RC);
+ t2 = F->getRegInfo().createVirtualRegister(RC);
+ MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t1).addReg(dest1Oper.getReg());
+ MIB = BuildMI(newMBB, dl, TII->get(NotOpc), t2).addReg(dest2Oper.getReg());
} else {
- tt1 = t1;
- tt2 = t2;
+ t1 = dest1Oper.getReg();
+ t2 = dest2Oper.getReg();
}
int valArgIndx = lastAddrIndx + 1;
@@ -7798,7 +7854,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
else
MIB = BuildMI(newMBB, dl, TII->get(immOpcL), t5);
if (regOpcL != X86::MOV32rr)
- MIB.addReg(tt1);
+ MIB.addReg(t1);
(*MIB).addOperand(*argOpers[valArgIndx]);
assert(argOpers[valArgIndx + 1]->isReg() ==
argOpers[valArgIndx]->isReg());
@@ -7809,7 +7865,7 @@ X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
else
MIB = BuildMI(newMBB, dl, TII->get(immOpcH), t6);
if (regOpcH != X86::MOV32rr)
- MIB.addReg(tt2);
+ MIB.addReg(t2);
(*MIB).addOperand(*argOpers[valArgIndx + 1]);
MIB = BuildMI(newMBB, dl, TII->get(copyOpc), X86::EAX);
@@ -9108,6 +9164,64 @@ static SDValue PerformShiftCombine(SDNode* N, SelectionDAG &DAG,
return SDValue();
}
+static SDValue PerformOrCombine(SDNode *N, SelectionDAG &DAG,
+ const X86Subtarget *Subtarget) {
+ EVT VT = N->getValueType(0);
+ if (VT != MVT::i64 || !Subtarget->is64Bit())
+ return SDValue();
+
+ // fold (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c)
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ if (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SHL)
+ std::swap(N0, N1);
+ if (N0.getOpcode() != ISD::SHL || N1.getOpcode() != ISD::SRL)
+ return SDValue();
+
+ SDValue ShAmt0 = N0.getOperand(1);
+ if (ShAmt0.getValueType() != MVT::i8)
+ return SDValue();
+ SDValue ShAmt1 = N1.getOperand(1);
+ if (ShAmt1.getValueType() != MVT::i8)
+ return SDValue();
+ if (ShAmt0.getOpcode() == ISD::TRUNCATE)
+ ShAmt0 = ShAmt0.getOperand(0);
+ if (ShAmt1.getOpcode() == ISD::TRUNCATE)
+ ShAmt1 = ShAmt1.getOperand(0);
+
+ DebugLoc DL = N->getDebugLoc();
+ unsigned Opc = X86ISD::SHLD;
+ SDValue Op0 = N0.getOperand(0);
+ SDValue Op1 = N1.getOperand(0);
+ if (ShAmt0.getOpcode() == ISD::SUB) {
+ Opc = X86ISD::SHRD;
+ std::swap(Op0, Op1);
+ std::swap(ShAmt0, ShAmt1);
+ }
+
+ if (ShAmt1.getOpcode() == ISD::SUB) {
+ SDValue Sum = ShAmt1.getOperand(0);
+ if (ConstantSDNode *SumC = dyn_cast<ConstantSDNode>(Sum)) {
+ if (SumC->getSExtValue() == 64 &&
+ ShAmt1.getOperand(1) == ShAmt0)
+ return DAG.getNode(Opc, DL, VT,
+ Op0, Op1,
+ DAG.getNode(ISD::TRUNCATE, DL,
+ MVT::i8, ShAmt0));
+ }
+ } else if (ConstantSDNode *ShAmt1C = dyn_cast<ConstantSDNode>(ShAmt1)) {
+ ConstantSDNode *ShAmt0C = dyn_cast<ConstantSDNode>(ShAmt0);
+ if (ShAmt0C &&
+ ShAmt0C->getSExtValue() + ShAmt1C->getSExtValue() == 64)
+ return DAG.getNode(Opc, DL, VT,
+ N0.getOperand(0), N1.getOperand(0),
+ DAG.getNode(ISD::TRUNCATE, DL,
+ MVT::i8, ShAmt0));
+ }
+
+ return SDValue();
+}
+
/// PerformSTORECombine - Do target-specific dag combines on STORE nodes.
static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
const X86Subtarget *Subtarget) {
@@ -9370,6 +9484,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
case ISD::SHL:
case ISD::SRA:
case ISD::SRL: return PerformShiftCombine(N, DAG, Subtarget);
+ case ISD::OR: return PerformOrCombine(N, DAG, Subtarget);
case ISD::STORE: return PerformSTORECombine(N, DAG, Subtarget);
case X86ISD::FXOR:
case X86ISD::FOR: return PerformFORCombine(N, DAG);
@@ -9423,7 +9538,7 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
std::string AsmStr = IA->getAsmString();
// TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a"
- std::vector<std::string> AsmPieces;
+ SmallVector<StringRef, 4> AsmPieces;
SplitString(AsmStr, AsmPieces, "\n"); // ; as separator?
switch (AsmPieces.size()) {
@@ -9445,7 +9560,7 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
return LowerToBSwap(CI);
}
// rorw $$8, ${0:w} --> llvm.bswap.i16
- if (CI->getType() == Type::getInt16Ty(CI->getContext()) &&
+ if (CI->getType()->isInteger(16) &&
AsmPieces.size() == 3 &&
AsmPieces[0] == "rorw" &&
AsmPieces[1] == "$$8," &&
@@ -9455,12 +9570,12 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
}
break;
case 3:
- if (CI->getType() == Type::getInt64Ty(CI->getContext()) &&
+ if (CI->getType()->isInteger(64) &&
Constraints.size() >= 2 &&
Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" &&
Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") {
// bswap %eax / bswap %edx / xchgl %eax, %edx -> llvm.bswap.i64
- std::vector<std::string> Words;
+ SmallVector<StringRef, 4> Words;
SplitString(AsmPieces[0], Words, " \t");
if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") {
Words.clear();
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 65fbbda..08e1dd1 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -1106,13 +1106,13 @@ def OR64rm : RI<0x0B, MRMSrcMem , (outs GR64:$dst),
def OR64ri8 : RIi8<0x83, MRM1r, (outs GR64:$dst),
(ins GR64:$src1, i64i8imm:$src2),
"or{q}\t{$src2, $dst|$dst, $src2}",
- [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2)),
- (implicit EFLAGS)]>;
+ [(set GR64:$dst, (or GR64:$src1, i64immSExt8:$src2)),
+ (implicit EFLAGS)]>;
def OR64ri32 : RIi32<0x81, MRM1r, (outs GR64:$dst),
(ins GR64:$src1, i64i32imm:$src2),
"or{q}\t{$src2, $dst|$dst, $src2}",
- [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2)),
- (implicit EFLAGS)]>;
+ [(set GR64:$dst, (or GR64:$src1, i64immSExt32:$src2)),
+ (implicit EFLAGS)]>;
} // isTwoAddress
def OR64mr : RI<0x09, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
@@ -1598,17 +1598,21 @@ def SLDT64m : RI<0x00, MRM0m, (outs i16mem:$dst), (ins),
// Alias Instructions
//===----------------------------------------------------------------------===//
-// Alias instructions that map movr0 to xor. Use xorl instead of xorq; it's
-// equivalent due to implicit zero-extending, and it sometimes has a smaller
-// encoding.
+// We want to rewrite MOV64r0 in terms of MOV32r0, because it's sometimes a
+// smaller encoding, but doing so at isel time interferes with rematerialization
+// in the current register allocator. For now, this is rewritten when the
+// instruction is lowered to an MCInst.
// FIXME: AddedComplexity gives this a higher priority than MOV64ri32. Remove
// when we have a better way to specify isel priority.
-let AddedComplexity = 1 in
-def : Pat<(i64 0),
- (SUBREG_TO_REG (i64 0), (MOV32r0), x86_subreg_32bit)>;
-
-
-// Materialize i64 constant where top 32-bits are zero.
+let Defs = [EFLAGS],
+ AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
+def MOV64r0 : I<0x31, MRMInitReg, (outs GR64:$dst), (ins),
+ "",
+ [(set GR64:$dst, 0)]>;
+
+// Materialize i64 constant where top 32-bits are zero. This could theoretically
+// use MOV32ri with a SUBREG_TO_REG to represent the zero-extension, however
+// that would make it more difficult to rematerialize.
let AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in
def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
"", [(set GR64:$dst, i64immZExt32:$src)]>;
@@ -1683,6 +1687,7 @@ def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
"cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB;
+let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
"cmpxchg16b\t$dst", []>, TB;
@@ -1962,6 +1967,17 @@ def : Pat<(add GR64:$src1, 0x0000000080000000),
def : Pat<(store (add (loadi64 addr:$dst), 0x00000000800000000), addr:$dst),
(SUB64mi32 addr:$dst, 0xffffffff80000000)>;
+// Use a 32-bit and with implicit zero-extension instead of a 64-bit and if it
+// has an immediate with at least 32 bits of leading zeros, to avoid needing to
+// materialize that immediate in a register first.
+def : Pat<(and GR64:$src, i64immZExt32:$imm),
+ (SUBREG_TO_REG
+ (i64 0),
+ (AND32ri
+ (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit),
+ imm:$imm),
+ x86_subreg_32bit)>;
+
// r & (2^32-1) ==> movz
def : Pat<(and GR64:$src, 0x00000000FFFFFFFF),
(MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, x86_subreg_32bit))>;
@@ -2028,7 +2044,7 @@ def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)),
(EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)),
x86_subreg_8bit_hi))>,
Requires<[In64BitMode]>;
-def : Pat<(srl_su GR16:$src, (i8 8)),
+def : Pat<(srl GR16:$src, (i8 8)),
(EXTRACT_SUBREG
(MOVZX32_NOREXrr8
(EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
@@ -2098,24 +2114,7 @@ def : Pat<(sra GR64:$src1, (and CL:$amt, 63)),
def : Pat<(store (sra (loadi64 addr:$dst), (and CL:$amt, 63)), addr:$dst),
(SAR64mCL addr:$dst)>;
-// (or (x >> c) | (y << (64 - c))) ==> (shrd64 x, y, c)
-def : Pat<(or (srl GR64:$src1, CL:$amt),
- (shl GR64:$src2, (sub 64, CL:$amt))),
- (SHRD64rrCL GR64:$src1, GR64:$src2)>;
-
-def : Pat<(store (or (srl (loadi64 addr:$dst), CL:$amt),
- (shl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
- (SHRD64mrCL addr:$dst, GR64:$src2)>;
-
-def : Pat<(or (srl GR64:$src1, (i8 (trunc RCX:$amt))),
- (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
- (SHRD64rrCL GR64:$src1, GR64:$src2)>;
-
-def : Pat<(store (or (srl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
- (shl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
- addr:$dst),
- (SHRD64mrCL addr:$dst, GR64:$src2)>;
-
+// Double shift patterns
def : Pat<(shrd GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
(SHRD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
@@ -2123,24 +2122,6 @@ def : Pat<(store (shrd (loadi64 addr:$dst), (i8 imm:$amt1),
GR64:$src2, (i8 imm:$amt2)), addr:$dst),
(SHRD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
-// (or (x << c) | (y >> (64 - c))) ==> (shld64 x, y, c)
-def : Pat<(or (shl GR64:$src1, CL:$amt),
- (srl GR64:$src2, (sub 64, CL:$amt))),
- (SHLD64rrCL GR64:$src1, GR64:$src2)>;
-
-def : Pat<(store (or (shl (loadi64 addr:$dst), CL:$amt),
- (srl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
- (SHLD64mrCL addr:$dst, GR64:$src2)>;
-
-def : Pat<(or (shl GR64:$src1, (i8 (trunc RCX:$amt))),
- (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
- (SHLD64rrCL GR64:$src1, GR64:$src2)>;
-
-def : Pat<(store (or (shl (loadi64 addr:$dst), (i8 (trunc RCX:$amt))),
- (srl GR64:$src2, (i8 (trunc (sub 64, RCX:$amt))))),
- addr:$dst),
- (SHLD64mrCL addr:$dst, GR64:$src2)>;
-
def : Pat<(shld GR64:$src1, (i8 imm:$amt1), GR64:$src2, (i8 imm:$amt2)),
(SHLD64rri8 GR64:$src1, GR64:$src2, (i8 imm:$amt1))>;
@@ -2148,6 +2129,19 @@ def : Pat<(store (shld (loadi64 addr:$dst), (i8 imm:$amt1),
GR64:$src2, (i8 imm:$amt2)), addr:$dst),
(SHLD64mri8 addr:$dst, GR64:$src2, (i8 imm:$amt1))>;
+// (or x1, x2) -> (add x1, x2) if two operands are known not to share bits.
+let AddedComplexity = 5 in { // Try this before the selecting to OR
+def : Pat<(parallel (or_is_add GR64:$src1, i64immSExt8:$src2),
+ (implicit EFLAGS)),
+ (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
+def : Pat<(parallel (or_is_add GR64:$src1, i64immSExt32:$src2),
+ (implicit EFLAGS)),
+ (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
+def : Pat<(parallel (or_is_add GR64:$src1, GR64:$src2),
+ (implicit EFLAGS)),
+ (ADD64rr GR64:$src1, GR64:$src2)>;
+} // AddedComplexity
+
// X86 specific add which produces a flag.
def : Pat<(addc GR64:$src1, GR64:$src2),
(ADD64rr GR64:$src1, GR64:$src2)>;
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index e555cd1..7b39fb3 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -28,6 +28,7 @@
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
@@ -711,6 +712,62 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI,
}
}
+bool
+X86InstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SubIdx) const {
+ switch (MI.getOpcode()) {
+ default: break;
+ case X86::MOVSX16rr8:
+ case X86::MOVZX16rr8:
+ case X86::MOVSX32rr8:
+ case X86::MOVZX32rr8:
+ case X86::MOVSX64rr8:
+ case X86::MOVZX64rr8:
+ if (!TM.getSubtarget<X86Subtarget>().is64Bit())
+ // It's not always legal to reference the low 8-bit of the larger
+ // register in 32-bit mode.
+ return false;
+ case X86::MOVSX32rr16:
+ case X86::MOVZX32rr16:
+ case X86::MOVSX64rr16:
+ case X86::MOVZX64rr16:
+ case X86::MOVSX64rr32:
+ case X86::MOVZX64rr32: {
+ if (MI.getOperand(0).getSubReg() || MI.getOperand(1).getSubReg())
+ // Be conservative.
+ return false;
+ SrcReg = MI.getOperand(1).getReg();
+ DstReg = MI.getOperand(0).getReg();
+ switch (MI.getOpcode()) {
+ default:
+ llvm_unreachable(0);
+ break;
+ case X86::MOVSX16rr8:
+ case X86::MOVZX16rr8:
+ case X86::MOVSX32rr8:
+ case X86::MOVZX32rr8:
+ case X86::MOVSX64rr8:
+ case X86::MOVZX64rr8:
+ SubIdx = 1;
+ break;
+ case X86::MOVSX32rr16:
+ case X86::MOVZX32rr16:
+ case X86::MOVSX64rr16:
+ case X86::MOVZX64rr16:
+ SubIdx = 3;
+ break;
+ case X86::MOVSX64rr32:
+ case X86::MOVZX64rr32:
+ SubIdx = 4;
+ break;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
/// isFrameOperand - Return true and the FrameIndex if the specified
/// operand and follow operands form a reference to the stack frame.
bool X86InstrInfo::isFrameOperand(const MachineInstr *MI, unsigned int Op,
@@ -1018,12 +1075,16 @@ void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB,
switch (Opc) {
default: break;
case X86::MOV8r0:
- case X86::MOV32r0: {
+ case X86::MOV16r0:
+ case X86::MOV32r0:
+ case X86::MOV64r0: {
if (!isSafeToClobberEFLAGS(MBB, I)) {
switch (Opc) {
default: break;
case X86::MOV8r0: Opc = X86::MOV8ri; break;
+ case X86::MOV16r0: Opc = X86::MOV16ri; break;
case X86::MOV32r0: Opc = X86::MOV32ri; break;
+ case X86::MOV64r0: Opc = X86::MOV64ri; break;
}
Clone = false;
}
@@ -2290,8 +2351,12 @@ X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
OpcodeTablePtr = &RegOp2MemOpTable2Addr;
isTwoAddrFold = true;
} else if (i == 0) { // If operand 0
- if (MI->getOpcode() == X86::MOV32r0)
+ if (MI->getOpcode() == X86::MOV64r0)
+ NewMI = MakeM0Inst(*this, X86::MOV64mi32, MOs, MI);
+ else if (MI->getOpcode() == X86::MOV32r0)
NewMI = MakeM0Inst(*this, X86::MOV32mi, MOs, MI);
+ else if (MI->getOpcode() == X86::MOV16r0)
+ NewMI = MakeM0Inst(*this, X86::MOV16mi, MOs, MI);
else if (MI->getOpcode() == X86::MOV8r0)
NewMI = MakeM0Inst(*this, X86::MOV8mi, MOs, MI);
if (NewMI)
@@ -2354,7 +2419,7 @@ X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
// No fusion
if (PrintFailedFusing)
- errs() << "We failed to fuse operand " << i << " in " << *MI;
+ dbgs() << "We failed to fuse operand " << i << " in " << *MI;
return NULL;
}
@@ -2559,7 +2624,9 @@ bool X86InstrInfo::canFoldMemoryOperand(const MachineInstr *MI,
} else if (OpNum == 0) { // If operand 0
switch (Opc) {
case X86::MOV8r0:
+ case X86::MOV16r0:
case X86::MOV32r0:
+ case X86::MOV64r0:
return true;
default: break;
}
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
index b83441d..0ab85f4 100644
--- a/lib/Target/X86/X86InstrInfo.h
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -448,6 +448,16 @@ public:
unsigned &SrcReg, unsigned &DstReg,
unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
+ /// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
+ /// extension instruction. That is, it's like a copy where it's legal for the
+ /// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
+ /// true, then it's expected the pre-extension value is available as a subreg
+ /// of the result register. This also returns the sub-register index in
+ /// SubIdx.
+ virtual bool isCoalescableExtInstr(const MachineInstr &MI,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SubIdx) const;
+
unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const;
/// isLoadFromStackSlotPostFE - Check for post-frame ptr elimination
/// stack locations as well. This uses a heuristic so it isn't
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 4d922a5..396cb53 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -160,15 +160,21 @@ def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET,
[SDNPHasChain, SDNPOptInFlag]>;
-def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags>;
+def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags,
+ [SDNPCommutative]>;
def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>;
-def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags>;
-def X86umul_flag : SDNode<"X86ISD::UMUL", SDTUnaryArithWithFlags>;
+def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags,
+ [SDNPCommutative]>;
+def X86umul_flag : SDNode<"X86ISD::UMUL", SDTUnaryArithWithFlags,
+ [SDNPCommutative]>;
def X86inc_flag : SDNode<"X86ISD::INC", SDTUnaryArithWithFlags>;
def X86dec_flag : SDNode<"X86ISD::DEC", SDTUnaryArithWithFlags>;
-def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags>;
-def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags>;
-def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags>;
+def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags,
+ [SDNPCommutative]>;
+def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags,
+ [SDNPCommutative]>;
+def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags,
+ [SDNPCommutative]>;
def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
@@ -487,6 +493,21 @@ def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{
return N->hasOneUse();
}]>;
+// Treat an 'or' node is as an 'add' if the or'ed bits are known to be zero.
+def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
+ if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
+ return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue());
+ else {
+ unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits();
+ APInt Mask = APInt::getAllOnesValue(BitWidth);
+ APInt KnownZero0, KnownOne0;
+ CurDAG->ComputeMaskedBits(N->getOperand(0), Mask, KnownZero0, KnownOne0, 0);
+ APInt KnownZero1, KnownOne1;
+ CurDAG->ComputeMaskedBits(N->getOperand(1), Mask, KnownZero1, KnownOne1, 0);
+ return (~KnownZero0 & ~KnownZero1) == 0;
+ }
+}]>;
+
// 'shld' and 'shrd' instruction patterns. Note that even though these have
// the srl and shl in their patterns, the C++ code must still check for them,
// because predicates are tested before children nodes are explored.
@@ -3700,18 +3721,21 @@ let Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1,
def MOV8r0 : I<0x30, MRMInitReg, (outs GR8 :$dst), (ins),
"xor{b}\t$dst, $dst",
[(set GR8:$dst, 0)]>;
+
+// We want to rewrite MOV16r0 in terms of MOV32r0, because it's a smaller
+// encoding and avoids a partial-register update sometimes, but doing so
+// at isel time interferes with rematerialization in the current register
+// allocator. For now, this is rewritten when the instruction is lowered
+// to an MCInst.
+def MOV16r0 : I<0x31, MRMInitReg, (outs GR16:$dst), (ins),
+ "",
+ [(set GR16:$dst, 0)]>, OpSize;
def MOV32r0 : I<0x31, MRMInitReg, (outs GR32:$dst), (ins),
"xor{l}\t$dst, $dst",
[(set GR32:$dst, 0)]>;
}
-// Use xorl instead of xorw since we don't care about the high 16 bits,
-// it's smaller, and it avoids a partial-register update.
-let AddedComplexity = 1 in
-def : Pat<(i16 0),
- (EXTRACT_SUBREG (MOV32r0), x86_subreg_16bit)>;
-
//===----------------------------------------------------------------------===//
// Thread Local Storage Instructions
//
@@ -3792,7 +3816,7 @@ def LCMPXCHG32 : I<0xB1, MRMDestMem, (outs), (ins i32mem:$ptr, GR32:$swap),
[(X86cas addr:$ptr, GR32:$swap, 4)]>, TB, LOCK;
}
let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in {
-def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i32mem:$ptr),
+def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$ptr),
"lock\n\t"
"cmpxchg8b\t$ptr",
[(X86cas8 addr:$ptr)]>, TB, LOCK;
@@ -3858,6 +3882,7 @@ def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
"cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB;
+let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
"cmpxchg8b\t$dst", []>, TB;
@@ -4466,7 +4491,7 @@ def : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))),
(EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)),
x86_subreg_8bit_hi)>,
Requires<[In32BitMode]>;
-def : Pat<(srl_su GR16:$src, (i8 8)),
+def : Pat<(srl GR16:$src, (i8 8)),
(EXTRACT_SUBREG
(MOVZX32rr8
(EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
@@ -4640,6 +4665,28 @@ def : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
def : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
(SETB_C32r)>;
+// (or x1, x2) -> (add x1, x2) if two operands are known not to share bits.
+let AddedComplexity = 5 in { // Try this before the selecting to OR
+def : Pat<(parallel (or_is_add GR16:$src1, imm:$src2),
+ (implicit EFLAGS)),
+ (ADD16ri GR16:$src1, imm:$src2)>;
+def : Pat<(parallel (or_is_add GR32:$src1, imm:$src2),
+ (implicit EFLAGS)),
+ (ADD32ri GR32:$src1, imm:$src2)>;
+def : Pat<(parallel (or_is_add GR16:$src1, i16immSExt8:$src2),
+ (implicit EFLAGS)),
+ (ADD16ri8 GR16:$src1, i16immSExt8:$src2)>;
+def : Pat<(parallel (or_is_add GR32:$src1, i32immSExt8:$src2),
+ (implicit EFLAGS)),
+ (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>;
+def : Pat<(parallel (or_is_add GR16:$src1, GR16:$src2),
+ (implicit EFLAGS)),
+ (ADD16rr GR16:$src1, GR16:$src2)>;
+def : Pat<(parallel (or_is_add GR32:$src1, GR32:$src2),
+ (implicit EFLAGS)),
+ (ADD32rr GR32:$src1, GR32:$src2)>;
+} // AddedComplexity
+
//===----------------------------------------------------------------------===//
// EFLAGS-defining Patterns
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index b26e508..94b9b55 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -131,11 +131,13 @@ def alignedloadv2i64 : PatFrag<(ops node:$ptr),
// Like 'load', but uses special alignment checks suitable for use in
// memory operands in most SSE instructions, which are required to
-// be naturally aligned on some targets but not on others.
-// FIXME: Actually implement support for targets that don't require the
-// alignment. This probably wants a subtarget predicate.
+// be naturally aligned on some targets but not on others. If the subtarget
+// allows unaligned accesses, match any load, though this may require
+// setting a feature bit in the processor (on startup, for example).
+// Opteron 10h and later implement such a feature.
def memop : PatFrag<(ops node:$ptr), (load node:$ptr), [{
- return cast<LoadSDNode>(N)->getAlignment() >= 16;
+ return Subtarget->hasVectorUAMem()
+ || cast<LoadSDNode>(N)->getAlignment() >= 16;
}]>;
def memopfsf32 : PatFrag<(ops node:$ptr), (f32 (memop node:$ptr))>;
diff --git a/lib/Target/X86/X86JITInfo.cpp b/lib/Target/X86/X86JITInfo.cpp
index c69cc83..f363903 100644
--- a/lib/Target/X86/X86JITInfo.cpp
+++ b/lib/Target/X86/X86JITInfo.cpp
@@ -348,7 +348,7 @@ X86CompilationCallback2(intptr_t *StackPtr, intptr_t RetAddr) {
#endif
#if 0
- DEBUG(errs() << "In callback! Addr=" << (void*)RetAddr
+ DEBUG(dbgs() << "In callback! Addr=" << (void*)RetAddr
<< " ESP=" << (void*)StackPtr
<< ": Resolving call to function: "
<< TheVM->getFunctionReferencedName((void*)RetAddr) << "\n");
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index d96aafd..9bd96af 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -591,6 +591,15 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int FrameIndex = MI.getOperand(i).getIndex();
unsigned BasePtr;
+ // DEBUG_VALUE has a special representation, and is only robust enough to
+ // represent SP(or BP) +- offset addressing modes. We rewrite the
+ // FrameIndex to be a constant; implicitly positive constants are relative
+ // to ESP and negative ones to EBP.
+ if (MI.getOpcode()==TargetInstrInfo::DEBUG_VALUE) {
+ MI.getOperand(i).ChangeToImmediate(getFrameIndexOffset(MF, FrameIndex));
+ return 0;
+ }
+
if (needsStackRealignment(MF))
BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr);
else
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index 75cdbad..2039be7 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -286,6 +286,7 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &FS,
, HasFMA3(false)
, HasFMA4(false)
, IsBTMemSlow(false)
+ , HasVectorUAMem(false)
, DarwinVers(0)
, stackAlignment(8)
// FIXME: this is a known good value for Yonah. How about others?
@@ -317,7 +318,7 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &FS,
if (Is64Bit)
HasX86_64 = true;
- DEBUG(errs() << "Subtarget features: SSELevel " << X86SSELevel
+ DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel
<< ", 3DNowLevel " << X863DNowLevel
<< ", 64bit " << HasX86_64 << "\n");
assert((!Is64Bit || HasX86_64) &&
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index ef6dbaf..618dd10 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -78,6 +78,10 @@ protected:
/// IsBTMemSlow - True if BT (bit test) of memory instructions are slow.
bool IsBTMemSlow;
+ /// HasVectorUAMem - True if SIMD operations can have unaligned memory operands.
+ /// This may require setting a feature bit in the processor.
+ bool HasVectorUAMem;
+
/// DarwinVers - Nonzero if this is a darwin platform: the numeric
/// version of the platform, e.g. 8 = 10.4 (Tiger), 9 = 10.5 (Leopard), etc.
unsigned char DarwinVers; // Is any darwin-x86 platform.
@@ -142,6 +146,7 @@ public:
bool hasFMA3() const { return HasFMA3; }
bool hasFMA4() const { return HasFMA4; }
bool isBTMemSlow() const { return IsBTMemSlow; }
+ bool hasVectorUAMem() const { return HasVectorUAMem; }
bool isTargetDarwin() const { return TargetType == isDarwin; }
bool isTargetELF() const { return TargetType == isELF; }
@@ -169,7 +174,7 @@ public:
p = "e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128-n8:16:32:64";
else if (isTargetDarwin())
p = "e-p:32:32-f64:32:64-i64:32:64-f80:128:128-n8:16:32";
- else if (isTargetCygMing() || isTargetWindows())
+ else if (isTargetMingw() || isTargetWindows())
p = "e-p:32:32-f64:64:64-i64:64:64-f80:128:128-n8:16:32";
else
p = "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32";
diff --git a/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/lib/Target/XCore/XCoreISelDAGToDAG.cpp
index da2fb04..383fd91 100644
--- a/lib/Target/XCore/XCoreISelDAGToDAG.cpp
+++ b/lib/Target/XCore/XCoreISelDAGToDAG.cpp
@@ -49,7 +49,7 @@ namespace {
Lowering(*TM.getTargetLowering()),
Subtarget(*TM.getSubtargetImpl()) { }
- SDNode *Select(SDValue Op);
+ SDNode *Select(SDNode *N);
/// getI32Imm - Return a target constant with the specified value, of type
/// i32.
@@ -58,11 +58,11 @@ namespace {
}
// Complex Pattern Selectors.
- bool SelectADDRspii(SDValue Op, SDValue Addr, SDValue &Base,
+ bool SelectADDRspii(SDNode *Op, SDValue Addr, SDValue &Base,
SDValue &Offset);
- bool SelectADDRdpii(SDValue Op, SDValue Addr, SDValue &Base,
+ bool SelectADDRdpii(SDNode *Op, SDValue Addr, SDValue &Base,
SDValue &Offset);
- bool SelectADDRcpii(SDValue Op, SDValue Addr, SDValue &Base,
+ bool SelectADDRcpii(SDNode *Op, SDValue Addr, SDValue &Base,
SDValue &Offset);
virtual void InstructionSelect();
@@ -83,7 +83,7 @@ FunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM) {
return new XCoreDAGToDAGISel(TM);
}
-bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Op, SDValue Addr,
+bool XCoreDAGToDAGISel::SelectADDRspii(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Offset) {
FrameIndexSDNode *FIN = 0;
if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) {
@@ -105,7 +105,7 @@ bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Op, SDValue Addr,
return false;
}
-bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Op, SDValue Addr,
+bool XCoreDAGToDAGISel::SelectADDRdpii(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Offset) {
if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) {
Base = Addr.getOperand(0);
@@ -126,7 +126,7 @@ bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Op, SDValue Addr,
return false;
}
-bool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Op, SDValue Addr,
+bool XCoreDAGToDAGISel::SelectADDRcpii(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Offset) {
if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) {
Base = Addr.getOperand(0);
@@ -156,8 +156,7 @@ void XCoreDAGToDAGISel::InstructionSelect() {
CurDAG->RemoveDeadNodes();
}
-SDNode *XCoreDAGToDAGISel::Select(SDValue Op) {
- SDNode *N = Op.getNode();
+SDNode *XCoreDAGToDAGISel::Select(SDNode *N) {
DebugLoc dl = N->getDebugLoc();
EVT NVT = N->getValueType(0);
if (NVT == MVT::i32) {
@@ -185,7 +184,7 @@ SDNode *XCoreDAGToDAGISel::Select(SDValue Op) {
// FIXME fold addition into the macc instruction
SDValue Zero(CurDAG->getMachineNode(XCore::LDC_ru6, dl, MVT::i32,
CurDAG->getTargetConstant(0, MVT::i32)), 0);
- SDValue Ops[] = { Zero, Zero, Op.getOperand(0), Op.getOperand(1) };
+ SDValue Ops[] = { Zero, Zero, N->getOperand(0), N->getOperand(1) };
SDNode *ResNode = CurDAG->getMachineNode(XCore::MACCS_l4r, dl,
MVT::i32, MVT::i32, Ops, 4);
ReplaceUses(SDValue(N, 0), SDValue(ResNode, 1));
@@ -196,7 +195,7 @@ SDNode *XCoreDAGToDAGISel::Select(SDValue Op) {
// FIXME fold addition into the macc / lmul instruction
SDValue Zero(CurDAG->getMachineNode(XCore::LDC_ru6, dl, MVT::i32,
CurDAG->getTargetConstant(0, MVT::i32)), 0);
- SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
Zero, Zero };
SDNode *ResNode = CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32,
MVT::i32, Ops, 4);
@@ -205,19 +204,19 @@ SDNode *XCoreDAGToDAGISel::Select(SDValue Op) {
return NULL;
}
case XCoreISD::LADD: {
- SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
- Op.getOperand(2) };
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
+ N->getOperand(2) };
return CurDAG->getMachineNode(XCore::LADD_l5r, dl, MVT::i32, MVT::i32,
Ops, 3);
}
case XCoreISD::LSUB: {
- SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
- Op.getOperand(2) };
+ SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
+ N->getOperand(2) };
return CurDAG->getMachineNode(XCore::LSUB_l5r, dl, MVT::i32, MVT::i32,
Ops, 3);
}
// Other cases are autogenerated.
}
}
- return SelectCode(Op);
+ return SelectCode(N);
}
OpenPOWER on IntegriCloud