summaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-03-16 16:51:38 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-03-16 16:51:38 +0000
commit0f448b841684305c051796982f300c9bff959307 (patch)
tree458dd25677a43aef6390ecadb4423817f00e08b0 /lib/Target
parent9e2446b38c94db61b2416c28fee415c03663c11c (diff)
downloadFreeBSD-src-0f448b841684305c051796982f300c9bff959307.zip
FreeBSD-src-0f448b841684305c051796982f300c9bff959307.tar.gz
Update LLVM to r98631.
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARM.td2
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.h5
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp4
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp43
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp7
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp63
-rw-r--r--lib/Target/ARM/ARMISelLowering.h2
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td58
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td72
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td32
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td37
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td112
-rw-r--r--lib/Target/ARM/ARMInstrVFP.td66
-rw-r--r--lib/Target/ARM/ARMLoadStoreOptimizer.cpp245
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp1
-rw-r--r--lib/Target/ARM/ARMSubtarget.h12
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.cpp18
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.h12
-rw-r--r--lib/Target/ARM/AsmParser/Makefile2
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp56
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.h6
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp5
-rw-r--r--lib/Target/ARM/AsmPrinter/Makefile2
-rw-r--r--lib/Target/ARM/Thumb1InstrInfo.cpp2
-rw-r--r--lib/Target/ARM/Thumb1RegisterInfo.cpp10
-rw-r--r--lib/Target/ARM/Thumb2SizeReduction.cpp51
-rw-r--r--lib/Target/Alpha/AlphaInstrInfo.td4
-rw-r--r--lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp10
-rw-r--r--lib/Target/Alpha/AsmPrinter/Makefile2
-rw-r--r--lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp10
-rw-r--r--lib/Target/Blackfin/AsmPrinter/Makefile2
-rw-r--r--lib/Target/CBackend/CBackend.cpp5
-rw-r--r--lib/Target/CellSPU/AsmPrinter/Makefile2
-rw-r--r--lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp10
-rw-r--r--lib/Target/CellSPU/CellSDKIntrinsics.td8
-rw-r--r--lib/Target/CellSPU/SPU64InstrInfo.td9
-rw-r--r--lib/Target/CellSPU/SPUInstrInfo.td60
-rw-r--r--lib/Target/CellSPU/SPUOperands.td11
-rw-r--r--lib/Target/CellSPU/SPURegisterInfo.cpp20
-rw-r--r--lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp10
-rw-r--r--lib/Target/MBlaze/AsmPrinter/Makefile2
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp10
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp5
-rw-r--r--lib/Target/MSP430/AsmPrinter/Makefile2
-rw-r--r--lib/Target/Mangler.cpp91
-rw-r--r--lib/Target/Mips/AsmPrinter/Makefile2
-rw-r--r--lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp10
-rw-r--r--lib/Target/PIC16/AsmPrinter/Makefile2
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp22
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h3
-rw-r--r--lib/Target/PowerPC/AsmPrinter/Makefile2
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp114
-rw-r--r--lib/Target/PowerPC/PPCCodeEmitter.cpp6
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp10
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp26
-rw-r--r--lib/Target/README.txt24
-rw-r--r--lib/Target/Sparc/AsmPrinter/Makefile2
-rw-r--r--lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp10
-rw-r--r--lib/Target/SystemZ/AsmPrinter/Makefile2
-rw-r--r--lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp14
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp44
-rw-r--r--lib/Target/X86/AsmParser/Makefile2
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp9
-rw-r--r--lib/Target/X86/AsmPrinter/Makefile2
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp97
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.h9
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.cpp121
-rw-r--r--lib/Target/X86/CMakeLists.txt1
-rw-r--r--lib/Target/X86/Disassembler/Makefile2
-rw-r--r--lib/Target/X86/TargetInfo/Makefile2
-rw-r--r--lib/Target/X86/X86.h5
-rw-r--r--lib/Target/X86/X86.td3
-rw-r--r--lib/Target/X86/X86AsmBackend.cpp56
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.cpp73
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.h15
-rw-r--r--lib/Target/X86/X86CallingConv.td22
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp10
-rw-r--r--lib/Target/X86/X86FastISel.cpp30
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp37
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp222
-rw-r--r--lib/Target/X86/X86ISelLowering.h9
-rw-r--r--lib/Target/X86/X86Instr64bit.td114
-rw-r--r--lib/Target/X86/X86InstrFPStack.td15
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp17
-rw-r--r--lib/Target/X86/X86InstrInfo.td144
-rw-r--r--lib/Target/X86/X86InstrMMX.td4
-rw-r--r--lib/Target/X86/X86InstrSSE.td4
-rw-r--r--lib/Target/X86/X86JITInfo.cpp7
-rw-r--r--lib/Target/X86/X86MCAsmInfo.cpp7
-rw-r--r--lib/Target/X86/X86MCTargetExpr.cpp48
-rw-r--r--lib/Target/X86/X86MCTargetExpr.h49
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp80
-rw-r--r--lib/Target/X86/X86RegisterInfo.h2
-rw-r--r--lib/Target/X86/X86RegisterInfo.td7
-rw-r--r--lib/Target/X86/X86Subtarget.cpp7
-rw-r--r--lib/Target/X86/X86Subtarget.h1
-rw-r--r--lib/Target/X86/X86TargetObjectFile.cpp21
-rw-r--r--lib/Target/X86/X86TargetObjectFile.h10
-rw-r--r--lib/Target/XCore/AsmPrinter/Makefile2
-rw-r--r--lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp14
-rw-r--r--lib/Target/XCore/README.txt1
-rw-r--r--lib/Target/XCore/XCoreISelDAGToDAG.cpp23
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp62
-rw-r--r--lib/Target/XCore/XCoreISelLowering.h2
-rw-r--r--lib/Target/XCore/XCoreInstrInfo.cpp7
-rw-r--r--lib/Target/XCore/XCoreMachineFunctionInfo.h4
-rw-r--r--lib/Target/XCore/XCoreRegisterInfo.cpp32
107 files changed, 1723 insertions, 1179 deletions
diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td
index 7033861..bbb1dbd 100644
--- a/lib/Target/ARM/ARM.td
+++ b/lib/Target/ARM/ARM.td
@@ -40,6 +40,8 @@ def FeatureNEON : SubtargetFeature<"neon", "ARMFPUType", "NEON",
"Enable NEON instructions">;
def FeatureThumb2 : SubtargetFeature<"thumb2", "ThumbMode", "Thumb2",
"Enable Thumb2 instructions">;
+def FeatureFP16 : SubtargetFeature<"fp16", "HasFP16", "true",
+ "Enable half-precision floating point">;
//===----------------------------------------------------------------------===//
// ARM Processors supported.
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h
index 0194231..767d5ec 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -58,12 +58,13 @@ namespace ARMII {
Size4Bytes = 3,
Size2Bytes = 4,
- // IndexMode - Unindex, pre-indexed, or post-indexed. Only valid for load
- // and store ops
+ // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
+ // and store ops only. Generic "updating" flag is used for ld/st multiple.
IndexModeShift = 7,
IndexModeMask = 3 << IndexModeShift,
IndexModePre = 1,
IndexModePost = 2,
+ IndexModeUpd = 3,
//===------------------------------------------------------------------===//
// Instruction encoding formats.
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index d9b8323..11e1c48 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -590,6 +590,10 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
AFI->isThumb2Function())
MF.getRegInfo().setPhysRegUsed(ARM::R4);
+ // Spill LR if Thumb1 function uses variable length argument lists.
+ if (AFI->isThumb1OnlyFunction() && AFI->getVarArgsRegSaveSize() > 0)
+ MF.getRegInfo().setPhysRegUsed(ARM::LR);
+
// Don't spill FP if the frame can be eliminated. This is determined
// by scanning the callee-save registers to see if any is used.
const unsigned *CSRegs = getCalleeSavedRegs();
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 108a244..334c820 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -51,6 +51,7 @@ namespace {
const ARMSubtarget *Subtarget;
TargetMachine &TM;
JITCodeEmitter &MCE;
+ MachineModuleInfo *MMI;
const std::vector<MachineConstantPoolEntry> *MCPEs;
const std::vector<MachineJumpTableEntry> *MJTEs;
bool IsPIC;
@@ -182,7 +183,8 @@ bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
IsPIC = TM.getRelocationModel() == Reloc::PIC_;
JTI->Initialize(MF, IsPIC);
- MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
+ MMI = &getAnalysis<MachineModuleInfo>();
+ MCE.setModuleInfo(MMI);
do {
DEBUG(errs() << "JITTing function '"
@@ -436,8 +438,8 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
const MachineOperand &MO0 = MI.getOperand(0);
const MachineOperand &MO1 = MI.getOperand(1);
- assert(MO1.isImm() && ARM_AM::getSOImmVal(MO1.isImm()) != -1 &&
- "Not a valid so_imm value!");
+ assert(MO1.isImm() && ARM_AM::isSOImmTwoPartVal(MO1.getImm()) &&
+ "Not a valid so_imm value!");
unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO1.getImm());
unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO1.getImm());
@@ -563,7 +565,7 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
}
case TargetOpcode::DBG_LABEL:
case TargetOpcode::EH_LABEL:
- MCE.emitLabel(MI.getOperand(0).getImm());
+ MCE.emitLabel(MI.getOperand(0).getMCSymbol());
break;
case TargetOpcode::IMPLICIT_DEF:
case TargetOpcode::KILL:
@@ -925,19 +927,26 @@ static unsigned getAddrModeUPBits(unsigned Mode) {
return Binary;
}
-void ARMCodeEmitter::emitLoadStoreMultipleInstruction(
- const MachineInstr &MI) {
+void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+ bool IsUpdating = (TID.TSFlags & ARMII::IndexModeMask) != 0;
+
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+ // Skip operand 0 of an instruction with base register update.
+ unsigned OpIdx = 0;
+ if (IsUpdating)
+ ++OpIdx;
+
// Set base address operand
- Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
+ Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
// Set addressing mode by modifying bits U(23) and P(24)
- const MachineOperand &MO = MI.getOperand(1);
+ const MachineOperand &MO = MI.getOperand(OpIdx++);
Binary |= getAddrModeUPBits(ARM_AM::getAM4SubMode(MO.getImm()));
// Set bit W(21)
@@ -945,7 +954,7 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(
Binary |= 0x1 << ARMII::W_BitShift;
// Set registers
- for (unsigned i = 5, e = MI.getNumOperands(); i != e; ++i) {
+ for (unsigned i = OpIdx+2, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || MO.isImplicit())
break;
@@ -1322,17 +1331,25 @@ void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(
const MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+ bool IsUpdating = (TID.TSFlags & ARMII::IndexModeMask) != 0;
+
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+ // Skip operand 0 of an instruction with base register update.
+ unsigned OpIdx = 0;
+ if (IsUpdating)
+ ++OpIdx;
+
// Set base address operand
- Binary |= getMachineOpValue(MI, 0) << ARMII::RegRnShift;
+ Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRnShift;
// Set addressing mode by modifying bits U(23) and P(24)
- const MachineOperand &MO = MI.getOperand(1);
+ const MachineOperand &MO = MI.getOperand(OpIdx++);
Binary |= getAddrModeUPBits(ARM_AM::getAM5SubMode(MO.getImm()));
// Set bit W(21)
@@ -1340,11 +1357,11 @@ void ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(
Binary |= 0x1 << ARMII::W_BitShift;
// First register is encoded in Dd.
- Binary |= encodeVFPRd(MI, 5);
+ Binary |= encodeVFPRd(MI, OpIdx+2);
// Number of registers are encoded in offset field.
unsigned NumRegs = 1;
- for (unsigned i = 6, e = MI.getNumOperands(); i != e; ++i) {
+ for (unsigned i = OpIdx+3, e = MI.getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || MO.isImplicit())
break;
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp
index 8fa3c04..1c5bd42 100644
--- a/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -1473,11 +1473,10 @@ bool ARMConstantIslands::UndoLRSpillRestore() {
bool MadeChange = false;
for (unsigned i = 0, e = PushPopMIs.size(); i != e; ++i) {
MachineInstr *MI = PushPopMIs[i];
- // First two operands are predicates, the third is a zero since there
- // is no writeback.
+ // First two operands are predicates.
if (MI->getOpcode() == ARM::tPOP_RET &&
- MI->getOperand(3).getReg() == ARM::PC &&
- MI->getNumExplicitOperands() == 4) {
+ MI->getOperand(2).getReg() == ARM::PC &&
+ MI->getNumExplicitOperands() == 3) {
BuildMI(MI->getParent(), MI->getDebugLoc(), TII->get(ARM::tBX_RET));
MI->eraseFromParent();
MadeChange = true;
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 3dd0313..8f20843 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -130,7 +130,7 @@ void ARMTargetLowering::addQRTypeForNEON(EVT VT) {
static TargetLoweringObjectFile *createTLOF(TargetMachine &TM) {
if (TM.getSubtarget<ARMSubtarget>().isTargetDarwin())
- return new ARMMachOTargetObjectFile();
+ return new TargetLoweringObjectFileMachO();
return new ARMElfTargetObjectFile();
}
@@ -426,12 +426,20 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
setOperationAction(ISD::FPOW, MVT::f64, Expand);
setOperationAction(ISD::FPOW, MVT::f32, Expand);
- // int <-> fp are custom expanded into bit_convert + ARMISD ops.
- if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) {
- setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
- setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
- setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
- setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+ // Various VFP goodness
+ if (!UseSoftFloat && !Subtarget->isThumb1Only()) {
+ // int <-> fp are custom expanded into bit_convert + ARMISD ops.
+ if (Subtarget->hasVFP2()) {
+ setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
+ setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
+ setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+ }
+ // Special handling for half-precision FP.
+ if (Subtarget->hasVFP3() && Subtarget->hasFP16()) {
+ setOperationAction(ISD::FP16_TO_FP32, MVT::f32, Custom);
+ setOperationAction(ISD::FP32_TO_FP16, MVT::i32, Custom);
+ }
}
// We have target-specific dag combine patterns for the following nodes:
@@ -491,6 +499,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::FTOUI: return "ARMISD::FTOUI";
case ARMISD::SITOF: return "ARMISD::SITOF";
case ARMISD::UITOF: return "ARMISD::UITOF";
+ case ARMISD::F16_TO_F32: return "ARMISD::F16_TO_F32";
+ case ARMISD::F32_TO_F16: return "ARMISD::F32_TO_F16";
case ARMISD::SRL_FLAG: return "ARMISD::SRL_FLAG";
case ARMISD::SRA_FLAG: return "ARMISD::SRA_FLAG";
@@ -1972,8 +1982,21 @@ SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) {
static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) {
DebugLoc dl = Op.getDebugLoc();
- unsigned Opc =
- Op.getOpcode() == ISD::FP_TO_SINT ? ARMISD::FTOSI : ARMISD::FTOUI;
+ unsigned Opc;
+
+ switch (Op.getOpcode()) {
+ default:
+ assert(0 && "Invalid opcode!");
+ case ISD::FP32_TO_FP16:
+ Opc = ARMISD::F32_TO_F16;
+ break;
+ case ISD::FP_TO_SINT:
+ Opc = ARMISD::FTOSI;
+ break;
+ case ISD::FP_TO_UINT:
+ Opc = ARMISD::FTOUI;
+ break;
+ }
Op = DAG.getNode(Opc, dl, MVT::f32, Op.getOperand(0));
return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
}
@@ -1981,8 +2004,21 @@ static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) {
static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
EVT VT = Op.getValueType();
DebugLoc dl = Op.getDebugLoc();
- unsigned Opc =
- Op.getOpcode() == ISD::SINT_TO_FP ? ARMISD::SITOF : ARMISD::UITOF;
+ unsigned Opc;
+
+ switch (Op.getOpcode()) {
+ default:
+ assert(0 && "Invalid opcode!");
+ case ISD::FP16_TO_FP32:
+ Opc = ARMISD::F16_TO_F32;
+ break;
+ case ISD::SINT_TO_FP:
+ Opc = ARMISD::SITOF;
+ break;
+ case ISD::UINT_TO_FP:
+ Opc = ARMISD::UITOF;
+ break;
+ }
Op = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, Op.getOperand(0));
return DAG.getNode(Opc, dl, VT, Op);
@@ -3042,8 +3078,10 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex);
case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG, Subtarget);
+ case ISD::FP16_TO_FP32:
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
+ case ISD::FP32_TO_FP16:
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
@@ -4411,6 +4449,9 @@ ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
break;
}
}
+ if (StringRef("{cc}").equals_lower(Constraint))
+ return std::make_pair(0U, ARM::CCRRegisterClass);
+
return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
}
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index f8f8adc..d7b2ba3 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -59,6 +59,8 @@ namespace llvm {
FTOUI, // FP to uint within a FP register.
SITOF, // sint to FP within a FP register.
UITOF, // uint to FP within a FP register.
+ F16_TO_F32, // Half FP to single FP within a FP register.
+ F32_TO_F16, // Single FP to half FP within a FP register.
SRL_FLAG, // V,Flag = srl_flag X -> srl X, 1 + save carry out.
SRA_FLAG, // V,Flag = sra_flag X -> sra X, 1 + save carry out.
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 76595fa..258a96b 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -112,6 +112,7 @@ class IndexMode<bits<2> val> {
def IndexModeNone : IndexMode<0>;
def IndexModePre : IndexMode<1>;
def IndexModePost : IndexMode<2>;
+def IndexModeUpd : IndexMode<3>;
// Instruction execution domain.
class Domain<bits<2> val> {
@@ -144,6 +145,23 @@ def s_cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 CPSR))> {
let PrintMethod = "printSBitModifierOperand";
}
+// ARM special operands for disassembly only.
+//
+
+def cps_opt : Operand<i32> {
+ let PrintMethod = "printCPSOptionOperand";
+}
+
+def msr_mask : Operand<i32> {
+ let PrintMethod = "printMSRMaskOperand";
+}
+
+// A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
+// The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
+def neg_zero : Operand<i32> {
+ let PrintMethod = "printNegZeroOperand";
+}
+
//===----------------------------------------------------------------------===//
// ARM Instruction templates.
@@ -835,18 +853,18 @@ class AI3stdpo<dag oops, dag iops, Format f, InstrItinClass itin,
// addrmode4 instructions
-class AXI4ld<dag oops, dag iops, Format f, InstrItinClass itin,
- string asm, list<dag> pattern>
- : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, itin,
- asm, "", pattern> {
+class AXI4ld<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : XI<oops, iops, AddrMode4, Size4Bytes, im, f, itin,
+ asm, cstr, pattern> {
let Inst{20} = 1; // L bit
let Inst{22} = 0; // S bit
let Inst{27-25} = 0b100;
}
-class AXI4st<dag oops, dag iops, Format f, InstrItinClass itin,
- string asm, list<dag> pattern>
- : XI<oops, iops, AddrMode4, Size4Bytes, IndexModeNone, f, itin,
- asm, "", pattern> {
+class AXI4st<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : XI<oops, iops, AddrMode4, Size4Bytes, im, f, itin,
+ asm, cstr, pattern> {
let Inst{20} = 0; // L bit
let Inst{22} = 0; // S bit
let Inst{27-25} = 0b100;
@@ -980,9 +998,9 @@ class T1JTI<dag oops, dag iops, InstrItinClass itin,
// Two-address instructions
class T1It<dag oops, dag iops, InstrItinClass itin,
- string asm, list<dag> pattern>
+ string asm, string cstr, list<dag> pattern>
: Thumb1I<oops, iops, AddrModeNone, Size2Bytes, itin,
- asm, "$lhs = $dst", pattern>;
+ asm, cstr, pattern>;
// Thumb1 instruction that can either be predicated or set CPSR.
class Thumb1sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
@@ -1179,6 +1197,10 @@ class T2Ix2<dag oops, dag iops, InstrItinClass itin,
string opc, string asm, list<dag> pattern>
: Thumb2I<oops, iops, AddrModeNone, Size8Bytes, itin, opc, asm, "", pattern>;
+// Two-address instructions
+class T2XIt<dag oops, dag iops, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, cstr, pattern>;
// T2Iidxldst - Thumb2 indexed load / store instructions.
class T2Iidxldst<bit signed, bits<2> opcod, bit load, bit pre,
@@ -1293,10 +1315,10 @@ class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
}
// Load / store multiple
-class AXDI5<dag oops, dag iops, InstrItinClass itin,
- string asm, list<dag> pattern>
- : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
- VFPLdStMulFrm, itin, asm, "", pattern> {
+class AXDI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : VFPXI<oops, iops, AddrMode5, Size4Bytes, im,
+ VFPLdStMulFrm, itin, asm, cstr, pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
let Inst{27-25} = 0b110;
let Inst{11-8} = 0b1011;
@@ -1305,10 +1327,10 @@ class AXDI5<dag oops, dag iops, InstrItinClass itin,
let Dom = VFPNeonDomain.Value;
}
-class AXSI5<dag oops, dag iops, InstrItinClass itin,
- string asm, list<dag> pattern>
- : VFPXI<oops, iops, AddrMode5, Size4Bytes, IndexModeNone,
- VFPLdStMulFrm, itin, asm, "", pattern> {
+class AXSI5<dag oops, dag iops, IndexMode im, InstrItinClass itin,
+ string asm, string cstr, list<dag> pattern>
+ : VFPXI<oops, iops, AddrMode5, Size4Bytes, im,
+ VFPLdStMulFrm, itin, asm, cstr, pattern> {
// TODO: Mark the instructions with the appropriate subtarget info.
let Inst{27-25} = 0b110;
let Inst{11-8} = 0b1010;
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index af82a5f..3fc37da 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -378,7 +378,7 @@ def am3offset : Operand<i32>,
def addrmode4 : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrMode4", []> {
let PrintMethod = "printAddrMode4Operand";
- let MIOperandInfo = (ops GPR, i32imm);
+ let MIOperandInfo = (ops GPR:$addr, i32imm);
}
// addrmode5 := reg +/- imm8*4
@@ -386,7 +386,7 @@ def addrmode4 : Operand<i32>,
def addrmode5 : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrMode5", []> {
let PrintMethod = "printAddrMode5Operand";
- let MIOperandInfo = (ops GPR, i32imm);
+ let MIOperandInfo = (ops GPR:$base, i32imm);
}
// addrmode6 := reg with optional writeback
@@ -710,7 +710,7 @@ def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val",
// opt{5} = changemode from Inst{17}
// opt{8-6} = AIF from Inst{8-6}
// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
-def CPS : AXI<(outs),(ins i32imm:$opt), MiscFrm, NoItinerary, "cps${opt:cps}",
+def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM]> {
let Inst{31-28} = 0b1111;
@@ -721,9 +721,12 @@ def CPS : AXI<(outs),(ins i32imm:$opt), MiscFrm, NoItinerary, "cps${opt:cps}",
// Preload signals the memory system of possible future data/instruction access.
// These are for disassembly only.
+//
+// A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
+// The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
multiclass APreLoad<bit data, bit read, string opc> {
- def i : AXI<(outs), (ins GPR:$base, i32imm:$imm), MiscFrm, NoItinerary,
+ def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary,
!strconcat(opc, "\t[$base, $imm]"), []> {
let Inst{31-26} = 0b111101;
let Inst{25} = 0; // 0 for immediate form
@@ -903,10 +906,11 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
// FIXME: Should pc be an implicit operand like PICADD, etc?
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1 in
- def LDM_RET : AXI4ld<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
- []>;
+ def LDM_RET : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeUpd, LdStMulFrm, IIC_Br,
+ "ldm${addr:submode}${p}\t$addr, $dsts",
+ "$addr.addr = $wb", []>;
// On non-Darwin platforms R9 is callee-saved.
let isCall = 1,
@@ -1341,17 +1345,31 @@ def STRHT: AI3sthpo<(outs GPR:$base_wb),
// Load / store multiple Instructions.
//
-let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
-def LDM : AXI4ld<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
- []>;
-
-let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
-def STM : AXI4st<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
- []>;
+let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
+def LDM : AXI4ld<(outs), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeNone, LdStMulFrm, IIC_iLoadm,
+ "ldm${addr:submode}${p}\t$addr, $dsts", "", []>;
+
+def LDM_UPD : AXI4ld<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeUpd, LdStMulFrm, IIC_iLoadm,
+ "ldm${addr:submode}${p}\t$addr, $dsts",
+ "$addr.addr = $wb", []>;
+} // mayLoad, hasExtraDefRegAllocReq
+
+let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
+def STM : AXI4st<(outs), (ins addrmode4:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IndexModeNone, LdStMulFrm, IIC_iStorem,
+ "stm${addr:submode}${p}\t$addr, $srcs", "", []>;
+
+def STM_UPD : AXI4st<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IndexModeUpd, LdStMulFrm, IIC_iStorem,
+ "stm${addr:submode}${p}\t$addr, $srcs",
+ "$addr.addr = $wb", []>;
+} // mayStore, hasExtraSrcRegAllocReq
//===----------------------------------------------------------------------===//
// Move Instructions.
@@ -2844,29 +2862,29 @@ def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr",
let Inst{7-4} = 0b0000;
}
-def MSR : ABI<0b0001, (outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr",
- "\tcpsr${mask:msr}, $src",
+def MSR : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
+ "msr", "\tcpsr$mask, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0010;
let Inst{7-4} = 0b0000;
}
-def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, i32imm:$mask), NoItinerary,"msr",
- "\tcpsr${mask:msr}, $a",
+def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
+ "msr", "\tcpsr$mask, $a",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0010;
let Inst{7-4} = 0b0000;
}
-def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, i32imm:$mask),NoItinerary,"msr",
- "\tspsr${mask:msr}, $src",
+def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, msr_mask:$mask), NoItinerary,
+ "msr", "\tspsr$mask, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0110;
let Inst{7-4} = 0b0000;
}
-def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a, i32imm:$mask),NoItinerary,"msr",
- "\tspsr${mask:msr}, $a",
+def MSRsysi : ABI<0b0011, (outs), (ins so_imm:$a, msr_mask:$mask), NoItinerary,
+ "msr", "\tspsr$mask, $a",
[/* For disassembly only; pattern left blank */]> {
let Inst{23-20} = 0b0110;
let Inst{7-4} = 0b0000;
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td
index 7c44a2f..8fee6fa 100644
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -98,16 +98,6 @@ def NEONfmin : SDNode<"ARMISD::FMIN", SDTARMFMAX>;
// NEON operand definitions
//===----------------------------------------------------------------------===//
-// addrmode_neonldstm := reg
-//
-/* TODO: Take advantage of vldm.
-def addrmode_neonldstm : Operand<i32>,
- ComplexPattern<i32, 2, "SelectAddrModeNeonLdStM", []> {
- let PrintMethod = "printAddrNeonLdStMOperand";
- let MIOperandInfo = (ops GPR, i32imm);
-}
-*/
-
def h8imm : Operand<i8> {
let PrintMethod = "printHex8ImmOperand";
}
@@ -125,26 +115,6 @@ def h64imm : Operand<i64> {
// NEON load / store instructions
//===----------------------------------------------------------------------===//
-/* TODO: Take advantage of vldm.
-let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
-def VLDMD : NI<(outs),
- (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
- IIC_fpLoadm, "vldm", "${addr:submode} ${addr:base}, $dst1", []> {
- let Inst{27-25} = 0b110;
- let Inst{20} = 1;
- let Inst{11-9} = 0b101;
-}
-
-def VLDMS : NI<(outs),
- (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
- IIC_fpLoadm, "vldm", "${addr:submode} ${addr:base}, $dst1", []> {
- let Inst{27-25} = 0b110;
- let Inst{20} = 1;
- let Inst{11-9} = 0b101;
-}
-}
-*/
-
// Use vldmia to load a Q register as a D register pair.
def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), IIC_fpLoadm,
"vldmia", "$addr, ${dst:dregpair}",
@@ -2738,7 +2708,7 @@ def : Pat<(v2f64 (insertelt QPR:$src1, DPR:$src2, imm:$src3)),
def : Pat<(v2f32 (scalar_to_vector SPR:$src)),
(INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), SPR:$src, arm_ssubreg_0)>;
-def : Pat<(v2f64 (scalar_to_vector DPR:$src)),
+def : Pat<(v2f64 (scalar_to_vector (f64 DPR:$src))),
(INSERT_SUBREG (v2f64 (IMPLICIT_DEF)), DPR:$src, arm_dsubreg_0)>;
def : Pat<(v4f32 (scalar_to_vector SPR:$src)),
(INSERT_SUBREG (v4f32 (IMPLICIT_DEF)), SPR:$src, arm_ssubreg_0)>;
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index 786dd65..37c9fc5 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -201,7 +201,7 @@ def tBKPT : T1I<(outs), (ins i32imm:$val), NoItinerary, "bkpt\t$val",
//
// The opt{4-0} and opt{5} sub-fields are to accommodate 32-bit Thumb and ARM
// CPS which has more options.
-def tCPS : T1I<(outs), (ins i32imm:$opt), NoItinerary, "cps${opt:cps}",
+def tCPS : T1I<(outs), (ins cps_opt:$opt), NoItinerary, "cps$opt",
[/* For disassembly only; pattern left blank */]>,
T1Misc<0b0110011>;
@@ -290,8 +290,8 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
// FIXME: remove when we have a way to marking a MI with these properties.
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1 in
-def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
- "pop${p}\t$wb", []>,
+def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$dsts, variable_ops), IIC_Br,
+ "pop${p}\t$dsts", []>,
T1Misc<{1,1,0,?,?,?,?}>;
let isCall = 1,
@@ -539,28 +539,37 @@ def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
//
// These requires base address to be written back or one of the loaded regs.
-let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
+let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
def tLDM : T1I<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
+ (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops),
IIC_iLoadm,
- "ldm${addr:submode}${p}\t$addr, $wb", []>,
+ "ldm${addr:submode}${p}\t$addr, $dsts", []>,
T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53
+def tLDM_UPD : T1It<(outs tGPR:$wb),
+ (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops),
+ IIC_iLoadm,
+ "ldm${addr:submode}${p}\t$addr, $dsts",
+ "$addr.addr = $wb", []>,
+ T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53
+} // mayLoad, hasExtraDefRegAllocReq
+
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
-def tSTM : T1I<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_iStorem,
- "stm${addr:submode}${p}\t$addr, $wb", []>,
+def tSTM_UPD : T1It<(outs tGPR:$wb),
+ (ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops),
+ IIC_iStorem,
+ "stm${addr:submode}${p}\t$addr, $srcs",
+ "$addr.addr = $wb", []>,
T1Encoding<{1,1,0,0,0,?}>; // A6.2 & A8.6.189
let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
-def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
- "pop${p}\t$wb", []>,
+def tPOP : T1I<(outs), (ins pred:$p, reglist:$dsts, variable_ops), IIC_Br,
+ "pop${p}\t$dsts", []>,
T1Misc<{1,1,0,?,?,?,?}>;
let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in
-def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
- "push${p}\t$wb", []>,
+def tPUSH : T1I<(outs), (ins pred:$p, reglist:$srcs, variable_ops), IIC_Br,
+ "push${p}\t$srcs", []>,
T1Misc<{0,1,0,?,?,?,?}>;
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 2fc7d2f..ab9e926 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -150,6 +150,10 @@ def t2addrmode_imm8s4 : Operand<i32>,
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}
+def t2am_imm8s4_offset : Operand<i32> {
+ let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
+}
+
// t2addrmode_so_reg := reg + (reg << imm2)
def t2addrmode_so_reg : Operand<i32>,
ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
@@ -903,7 +907,7 @@ let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs GPR:$dst1, GPR:$dst2),
(ins t2addrmode_imm8s4:$addr),
IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>;
-def t2LDRDpci : T2Ii8s4<?, ?, 1, (outs GPR:$dst1, GPR:$dst2),
+def t2LDRDpci : T2Ii8s4<1, 0, 1, (outs GPR:$dst1, GPR:$dst2),
(ins i32imm:$addr), IIC_iLoadi,
"ldrd", "\t$dst1, $addr", []> {
let Inst{19-16} = 0b1111; // Rn
@@ -1105,14 +1109,34 @@ def t2STRT : T2IstT<0b10, "strt">;
def t2STRBT : T2IstT<0b00, "strbt">;
def t2STRHT : T2IstT<0b01, "strht">;
-// FIXME: ldrd / strd pre / post variants
+// ldrd / strd pre / post variants
+// For disassembly only.
+
+def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$dst1, GPR:$dst2),
+ (ins GPR:$base, t2am_imm8s4_offset:$imm), NoItinerary,
+ "ldrd", "\t$dst1, $dst2, [$base, $imm]!", []>;
+
+def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$dst1, GPR:$dst2),
+ (ins GPR:$base, t2am_imm8s4_offset:$imm), NoItinerary,
+ "ldrd", "\t$dst1, $dst2, [$base], $imm", []>;
+
+def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs),
+ (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
+ NoItinerary, "strd", "\t$src1, $src2, [$base, $imm]!", []>;
+
+def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs),
+ (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm),
+ NoItinerary, "strd", "\t$src1, $src2, [$base], $imm", []>;
// T2Ipl (Preload Data/Instruction) signals the memory system of possible future
// data/instruction access. These are for disassembly only.
+//
+// A8.6.117, A8.6.118. Different instructions are generated for #0 and #-0.
+// The neg_zero operand translates -0 to -1, -1 to -2, ..., etc.
multiclass T2Ipl<bit instr, bit write, string opc> {
- def i12 : T2I<(outs), (ins t2addrmode_imm12:$addr), IIC_iLoadi, opc,
- "\t$addr", []> {
+ def i12 : T2I<(outs), (ins GPR:$base, i32imm:$imm), IIC_iLoadi, opc,
+ "\t[$base, $imm]", []> {
let Inst{31-25} = 0b1111100;
let Inst{24} = instr;
let Inst{23} = 1; // U = 1
@@ -1122,8 +1146,8 @@ multiclass T2Ipl<bit instr, bit write, string opc> {
let Inst{15-12} = 0b1111;
}
- def i8 : T2I<(outs), (ins t2addrmode_imm8:$addr), IIC_iLoadi, opc,
- "\t$addr", []> {
+ def i8 : T2I<(outs), (ins GPR:$base, neg_zero:$imm), IIC_iLoadi, opc,
+ "\t[$base, $imm]", []> {
let Inst{31-25} = 0b1111100;
let Inst{24} = instr;
let Inst{23} = 0; // U = 0
@@ -1134,9 +1158,8 @@ multiclass T2Ipl<bit instr, bit write, string opc> {
let Inst{11-8} = 0b1100;
}
- // A8.6.118 #0 and #-0 differs. Translates -0 to -1, -1 to -2, ..., etc.
- def pci : T2I<(outs), (ins GPR:$base, i32imm:$imm), IIC_iLoadi, opc,
- "\t[pc, ${imm:negzero}]", []> {
+ def pci : T2I<(outs), (ins GPR:$base, neg_zero:$imm), IIC_iLoadi, opc,
+ "\t[pc, $imm]", []> {
let Inst{31-25} = 0b1111100;
let Inst{24} = instr;
let Inst{23} = ?; // add = (U == 1)
@@ -1181,29 +1204,56 @@ defm t2PLI : T2Ipl<1, 0, "pli">;
// Load / store multiple Instructions.
//
-let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
-def t2LDM : T2XI<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
+let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
+def t2LDM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops), IIC_iLoadm,
+ "ldm${addr:submode}${p}${addr:wide}\t$addr, $dsts", []> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-25} = 0b00;
+ let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
+ let Inst{22} = 0;
+ let Inst{21} = 0; // The W bit.
+ let Inst{20} = 1; // Load
+}
+
+def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops), IIC_iLoadm,
+ "ldm${addr:submode}${p}${addr:wide}\t$addr, $dsts",
+ "$addr.addr = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{22} = 0;
- let Inst{21} = ?; // The W bit.
+ let Inst{21} = 1; // The W bit.
let Inst{20} = 1; // Load
}
+} // mayLoad, hasExtraDefRegAllocReq
+
+let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
+def t2STM : T2XI<(outs), (ins addrmode4:$addr, pred:$p,
+ reglist:$srcs, variable_ops), IIC_iStorem,
+ "stm${addr:submode}${p}${addr:wide}\t$addr, $srcs", []> {
+ let Inst{31-27} = 0b11101;
+ let Inst{26-25} = 0b00;
+ let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
+ let Inst{22} = 0;
+ let Inst{21} = 0; // The W bit.
+ let Inst{20} = 0; // Store
+}
-let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
-def t2STM : T2XI<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []> {
+def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IIC_iStorem,
+ "stm${addr:submode}${p}${addr:wide}\t$addr, $srcs",
+ "$addr.addr = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{22} = 0;
- let Inst{21} = ?; // The W bit.
+ let Inst{21} = 1; // The W bit.
let Inst{20} = 0; // Store
}
+} // mayStore, hasExtraSrcRegAllocReq
//===----------------------------------------------------------------------===//
// Move Instructions.
@@ -2136,7 +2186,7 @@ def t2MOVCCror : T2I_movcc_sh<0b11, (outs GPR:$dst),
// memory barriers protect the atomic sequences
let hasSideEffects = 1 in {
def t2Int_MemBarrierV7 : AInoP<(outs), (ins),
- Pseudo, NoItinerary,
+ ThumbFrm, NoItinerary,
"dmb", "",
[(ARMMemBarrierV7)]>,
Requires<[IsThumb2]> {
@@ -2146,7 +2196,7 @@ def t2Int_MemBarrierV7 : AInoP<(outs), (ins),
}
def t2Int_SyncBarrierV7 : AInoP<(outs), (ins),
- Pseudo, NoItinerary,
+ ThumbFrm, NoItinerary,
"dsb", "",
[(ARMSyncBarrierV7)]>,
Requires<[IsThumb2]> {
@@ -2351,15 +2401,15 @@ let Defs =
// FIXME: Should pc be an implicit operand like PICADD, etc?
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1 in
- def t2LDM_RET : T2XI<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
- IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb",
- []> {
+ def t2LDM_RET : T2XIt<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
+ reglist:$dsts, variable_ops), IIC_Br,
+ "ldm${addr:submode}${p}${addr:wide}\t$addr, $dsts",
+ "$addr.addr = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{22} = 0;
- let Inst{21} = ?; // The W bit.
+ let Inst{21} = 1; // The W bit.
let Inst{20} = 1; // Load
}
@@ -2469,7 +2519,7 @@ def t2BXJ : T2I<(outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func",
// opt{5} = changemode from Inst{17}
// opt{8-6} = AIF from Inst{8-6}
// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
-def t2CPS : T2XI<(outs),(ins i32imm:$opt), NoItinerary, "cps${opt:cps}",
+def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
@@ -2638,8 +2688,8 @@ def t2MRSsys : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
}
// Rn = Inst{19-16}
-def t2MSR : T2I<(outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr",
- "\tcpsr${mask:msr}, $src",
+def t2MSR : T2I<(outs), (ins GPR:$src, msr_mask:$mask), NoItinerary, "msr",
+ "\tcpsr$mask, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
@@ -2650,8 +2700,8 @@ def t2MSR : T2I<(outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr",
}
// Rn = Inst{19-16}
-def t2MSRsys : T2I<(outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr",
- "\tspsr${mask:msr}, $src",
+def t2MSRsys : T2I<(outs), (ins GPR:$src, msr_mask:$mask), NoItinerary, "msr",
+ "\tspsr$mask, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td
index cad24c4..4d1d48a 100644
--- a/lib/Target/ARM/ARMInstrVFP.td
+++ b/lib/Target/ARM/ARMInstrVFP.td
@@ -25,6 +25,8 @@ def arm_ftoui : SDNode<"ARMISD::FTOUI", SDT_FTOI>;
def arm_ftosi : SDNode<"ARMISD::FTOSI", SDT_FTOI>;
def arm_sitof : SDNode<"ARMISD::SITOF", SDT_ITOF>;
def arm_uitof : SDNode<"ARMISD::UITOF", SDT_ITOF>;
+def arm_f16tof32 : SDNode<"ARMISD::F16_TO_F32", SDT_ITOF>;
+def arm_f32tof16 : SDNode<"ARMISD::F32_TO_F16", SDT_FTOI>;
def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInFlag,SDNPOutFlag]>;
def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutFlag]>;
def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0",SDT_CMPFP0, [SDNPOutFlag]>;
@@ -77,33 +79,61 @@ def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
//
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
-def VLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
- variable_ops), IIC_fpLoadm,
- "vldm${addr:submode}${p}\t${addr:base}, $wb",
- []> {
+def VLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dsts,
+ variable_ops), IndexModeNone, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}, $dsts", "", []> {
let Inst{20} = 1;
}
-def VLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
- variable_ops), IIC_fpLoadm,
- "vldm${addr:submode}${p}\t${addr:base}, $wb",
- []> {
+def VLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dsts,
+ variable_ops), IndexModeNone, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}, $dsts", "", []> {
+ let Inst{20} = 1;
+}
+
+def VLDMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeUpd, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}, $dsts",
+ "$addr.base = $wb", []> {
+ let Inst{20} = 1;
+}
+
+def VLDMS_UPD : AXSI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
+ reglist:$dsts, variable_ops),
+ IndexModeUpd, IIC_fpLoadm,
+ "vldm${addr:submode}${p}\t${addr:base}, $dsts",
+ "$addr.base = $wb", []> {
let Inst{20} = 1;
}
} // mayLoad, hasExtraDefRegAllocReq
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
-def VSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
- variable_ops), IIC_fpStorem,
- "vstm${addr:submode}${p}\t${addr:base}, $wb",
- []> {
+def VSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$srcs,
+ variable_ops), IndexModeNone, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}, $srcs", "", []> {
+ let Inst{20} = 0;
+}
+
+def VSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$srcs,
+ variable_ops), IndexModeNone, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}, $srcs", "", []> {
let Inst{20} = 0;
}
-def VSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
- variable_ops), IIC_fpStorem,
- "vstm${addr:submode}${p}\t${addr:base}, $wb",
- []> {
+def VSTMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IndexModeUpd, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}, $srcs",
+ "$addr.base = $wb", []> {
+ let Inst{20} = 0;
+}
+
+def VSTMS_UPD : AXSI5<(outs GPR:$wb), (ins addrmode5:$addr, pred:$p,
+ reglist:$srcs, variable_ops),
+ IndexModeUpd, IIC_fpStorem,
+ "vstm${addr:submode}${p}\t${addr:base}, $srcs",
+ "$addr.base = $wb", []> {
let Inst{20} = 0;
}
} // mayStore, hasExtraSrcRegAllocReq
@@ -229,11 +259,11 @@ def VCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm,
def VCVTBSH : ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
/* FIXME */ IIC_fpCVTDS, "vcvtb", ".f32.f16\t$dst, $a",
- [/* For disassembly only; pattern left blank */]>;
+ [(set SPR:$dst, (f32 (arm_f32tof16 SPR:$a)))]>;
def VCVTBHS : ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
/* FIXME */ IIC_fpCVTDS, "vcvtb", ".f16.f32\t$dst, $a",
- [/* For disassembly only; pattern left blank */]>;
+ [(set SPR:$dst, (arm_f16tof32 SPR:$a))]>;
def VCVTTSH : ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
/* FIXME */ IIC_fpCVTDS, "vcvtt", ".f32.f16\t$dst, $a",
diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
index 19f1e3b..8fbcf45 100644
--- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
+++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -243,8 +243,9 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
BaseKill = true; // New base is always killed right its use.
}
- bool isDPR = Opcode == ARM::VLDRD || Opcode == ARM::VSTRD;
- bool isDef = isi32Load(Opcode) || Opcode == ARM::VLDRS || Opcode == ARM::VLDRD;
+ bool isDPR = (Opcode == ARM::VLDRD || Opcode == ARM::VSTRD);
+ bool isDef = (isi32Load(Opcode) || Opcode == ARM::VLDRS ||
+ Opcode == ARM::VLDRD);
Opcode = getLoadStoreMultipleOpcode(Opcode);
MachineInstrBuilder MIB = (isAM4)
? BuildMI(MBB, MBBI, dl, TII->get(Opcode))
@@ -254,7 +255,6 @@ ARMLoadStoreOpt::MergeOps(MachineBasicBlock &MBB,
.addReg(Base, getKillRegState(BaseKill))
.addImm(ARM_AM::getAM5Opc(Mode, false, isDPR ? NumRegs<<1 : NumRegs))
.addImm(Pred).addReg(PredReg);
- MIB.addReg(0); // Add optional writeback (0 for now).
for (unsigned i = 0; i != NumRegs; ++i)
MIB = MIB.addReg(Regs[i].first, getDefRegState(isDef)
| getKillRegState(Regs[i].second));
@@ -443,7 +443,7 @@ static inline unsigned getLSMultipleTransferSize(MachineInstr *MI) {
case ARM::STM:
case ARM::t2LDM:
case ARM::t2STM:
- return (MI->getNumOperands() - 5) * 4;
+ return (MI->getNumOperands() - 4) * 4;
case ARM::VLDMS:
case ARM::VSTMS:
case ARM::VLDMD:
@@ -452,6 +452,21 @@ static inline unsigned getLSMultipleTransferSize(MachineInstr *MI) {
}
}
+static unsigned getUpdatingLSMultipleOpcode(unsigned Opc) {
+ switch (Opc) {
+ case ARM::LDM: return ARM::LDM_UPD;
+ case ARM::STM: return ARM::STM_UPD;
+ case ARM::t2LDM: return ARM::t2LDM_UPD;
+ case ARM::t2STM: return ARM::t2STM_UPD;
+ case ARM::VLDMS: return ARM::VLDMS_UPD;
+ case ARM::VLDMD: return ARM::VLDMD_UPD;
+ case ARM::VSTMS: return ARM::VSTMS_UPD;
+ case ARM::VSTMD: return ARM::VSTMD_UPD;
+ default: llvm_unreachable("Unhandled opcode!");
+ }
+ return 0;
+}
+
/// MergeBaseUpdateLSMultiple - Fold proceeding/trailing inc/dec of base
/// register into the LDM/STM/VLDM{D|S}/VSTM{D|S} op when possible:
///
@@ -470,117 +485,119 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &I) {
MachineInstr *MI = MBBI;
unsigned Base = MI->getOperand(0).getReg();
+ bool BaseKill = MI->getOperand(0).isKill();
unsigned Bytes = getLSMultipleTransferSize(MI);
unsigned PredReg = 0;
ARMCC::CondCodes Pred = llvm::getInstrPredicate(MI, PredReg);
int Opcode = MI->getOpcode();
- bool isAM4 = Opcode == ARM::LDM || Opcode == ARM::t2LDM ||
- Opcode == ARM::STM || Opcode == ARM::t2STM;
+ DebugLoc dl = MI->getDebugLoc();
+ bool isAM4 = (Opcode == ARM::LDM || Opcode == ARM::t2LDM ||
+ Opcode == ARM::STM || Opcode == ARM::t2STM);
- if (isAM4) {
- if (ARM_AM::getAM4WBFlag(MI->getOperand(1).getImm()))
- return false;
+ bool DoMerge = false;
+ ARM_AM::AMSubMode Mode = ARM_AM::ia;
+ unsigned Offset = 0;
- // Can't use the updating AM4 sub-mode if the base register is also a dest
+ if (isAM4) {
+ // Can't use an updating ld/st if the base register is also a dest
// register. e.g. ldmdb r0!, {r0, r1, r2}. The behavior is undefined.
for (unsigned i = 3, e = MI->getNumOperands(); i != e; ++i) {
if (MI->getOperand(i).getReg() == Base)
return false;
}
+ assert(!ARM_AM::getAM4WBFlag(MI->getOperand(1).getImm()));
+ Mode = ARM_AM::getAM4SubMode(MI->getOperand(1).getImm());
+ } else {
+ // VLDM{D|S}, VSTM{D|S} addressing mode 5 ops.
+ assert(!ARM_AM::getAM5WBFlag(MI->getOperand(1).getImm()));
+ Mode = ARM_AM::getAM5SubMode(MI->getOperand(1).getImm());
+ Offset = ARM_AM::getAM5Offset(MI->getOperand(1).getImm());
+ }
- ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(1).getImm());
- if (MBBI != MBB.begin()) {
- MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
+ // Try merging with the previous instruction.
+ if (MBBI != MBB.begin()) {
+ MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
+ if (isAM4) {
if (Mode == ARM_AM::ia &&
isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::db, true));
- MI->getOperand(4).setReg(Base);
- MI->getOperand(4).setIsDef();
- MBB.erase(PrevMBBI);
- return true;
- } else if (Mode == ARM_AM::ib &&
+ DoMerge = true;
+ Mode = ARM_AM::db;
+ } else if (isAM4 && Mode == ARM_AM::ib &&
isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::da, true));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- MBB.erase(PrevMBBI);
- return true;
+ DoMerge = true;
+ Mode = ARM_AM::da;
+ }
+ } else {
+ if (Mode == ARM_AM::ia &&
+ isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
+ Mode = ARM_AM::db;
+ DoMerge = true;
}
}
+ if (DoMerge)
+ MBB.erase(PrevMBBI);
+ }
- if (MBBI != MBB.end()) {
- MachineBasicBlock::iterator NextMBBI = llvm::next(MBBI);
+ // Try merging with the next instruction.
+ if (!DoMerge && MBBI != MBB.end()) {
+ MachineBasicBlock::iterator NextMBBI = llvm::next(MBBI);
+ if (isAM4) {
if ((Mode == ARM_AM::ia || Mode == ARM_AM::ib) &&
isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- if (NextMBBI == I) {
- Advance = true;
- ++I;
- }
- MBB.erase(NextMBBI);
- return true;
+ DoMerge = true;
} else if ((Mode == ARM_AM::da || Mode == ARM_AM::db) &&
isMatchingDecrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- if (NextMBBI == I) {
- Advance = true;
- ++I;
- }
- MBB.erase(NextMBBI);
- return true;
+ DoMerge = true;
}
- }
- } else {
- // VLDM{D|S}, VSTM{D|S} addressing mode 5 ops.
- if (ARM_AM::getAM5WBFlag(MI->getOperand(1).getImm()))
- return false;
-
- ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MI->getOperand(1).getImm());
- unsigned Offset = ARM_AM::getAM5Offset(MI->getOperand(1).getImm());
- if (MBBI != MBB.begin()) {
- MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
+ } else {
if (Mode == ARM_AM::ia &&
- isMatchingDecrement(PrevMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::db, true, Offset));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- MBB.erase(PrevMBBI);
- return true;
+ isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
+ DoMerge = true;
}
}
-
- if (MBBI != MBB.end()) {
- MachineBasicBlock::iterator NextMBBI = llvm::next(MBBI);
- if (Mode == ARM_AM::ia &&
- isMatchingIncrement(NextMBBI, Base, Bytes, 0, Pred, PredReg)) {
- MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::ia, true, Offset));
- MI->getOperand(4).setReg(Base); // WB to base
- MI->getOperand(4).setIsDef();
- if (NextMBBI == I) {
- Advance = true;
- ++I;
- }
- MBB.erase(NextMBBI);
+ if (DoMerge) {
+ if (NextMBBI == I) {
+ Advance = true;
+ ++I;
}
- return true;
+ MBB.erase(NextMBBI);
}
}
- return false;
+ if (!DoMerge)
+ return false;
+
+ unsigned NewOpc = getUpdatingLSMultipleOpcode(Opcode);
+ MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(NewOpc))
+ .addReg(Base, getDefRegState(true)) // WB base register
+ .addReg(Base, getKillRegState(BaseKill));
+ if (isAM4) {
+ // [t2]LDM_UPD, [t2]STM_UPD
+ MIB.addImm(ARM_AM::getAM4ModeImm(Mode, true))
+ .addImm(Pred).addReg(PredReg);
+ } else {
+ // VLDM[SD}_UPD, VSTM[SD]_UPD
+ MIB.addImm(ARM_AM::getAM5Opc(Mode, true, Offset))
+ .addImm(Pred).addReg(PredReg);
+ }
+ // Transfer the rest of operands.
+ for (unsigned OpNum = 4, e = MI->getNumOperands(); OpNum != e; ++OpNum)
+ MIB.addOperand(MI->getOperand(OpNum));
+ // Transfer memoperands.
+ (*MIB).setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
+
+ MBB.erase(MBBI);
+ return true;
}
static unsigned getPreIndexedLoadStoreOpcode(unsigned Opc) {
switch (Opc) {
case ARM::LDR: return ARM::LDR_PRE;
case ARM::STR: return ARM::STR_PRE;
- case ARM::VLDRS: return ARM::VLDMS;
- case ARM::VLDRD: return ARM::VLDMD;
- case ARM::VSTRS: return ARM::VSTMS;
- case ARM::VSTRD: return ARM::VSTMD;
+ case ARM::VLDRS: return ARM::VLDMS_UPD;
+ case ARM::VLDRD: return ARM::VLDMD_UPD;
+ case ARM::VSTRS: return ARM::VSTMS_UPD;
+ case ARM::VSTRD: return ARM::VSTMD_UPD;
case ARM::t2LDRi8:
case ARM::t2LDRi12:
return ARM::t2LDR_PRE;
@@ -596,10 +613,10 @@ static unsigned getPostIndexedLoadStoreOpcode(unsigned Opc) {
switch (Opc) {
case ARM::LDR: return ARM::LDR_POST;
case ARM::STR: return ARM::STR_POST;
- case ARM::VLDRS: return ARM::VLDMS;
- case ARM::VLDRD: return ARM::VLDMD;
- case ARM::VSTRS: return ARM::VSTMS;
- case ARM::VSTRD: return ARM::VSTMD;
+ case ARM::VLDRS: return ARM::VLDMS_UPD;
+ case ARM::VLDRD: return ARM::VLDMD_UPD;
+ case ARM::VSTRS: return ARM::VSTMS_UPD;
+ case ARM::VSTRD: return ARM::VSTMD_UPD;
case ARM::t2LDRi8:
case ARM::t2LDRi12:
return ARM::t2LDR_POST;
@@ -624,14 +641,14 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB,
unsigned Bytes = getLSMultipleTransferSize(MI);
int Opcode = MI->getOpcode();
DebugLoc dl = MI->getDebugLoc();
- bool isAM5 = Opcode == ARM::VLDRD || Opcode == ARM::VLDRS ||
- Opcode == ARM::VSTRD || Opcode == ARM::VSTRS;
- bool isAM2 = Opcode == ARM::LDR || Opcode == ARM::STR;
+ bool isAM5 = (Opcode == ARM::VLDRD || Opcode == ARM::VLDRS ||
+ Opcode == ARM::VSTRD || Opcode == ARM::VSTRS);
+ bool isAM2 = (Opcode == ARM::LDR || Opcode == ARM::STR);
if (isAM2 && ARM_AM::getAM2Offset(MI->getOperand(3).getImm()) != 0)
return false;
- else if (isAM5 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0)
+ if (isAM5 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0)
return false;
- else if (isT2i32Load(Opcode) || isT2i32Store(Opcode))
+ if (isT2i32Load(Opcode) || isT2i32Store(Opcode))
if (MI->getOperand(2).getImm() != 0)
return false;
@@ -648,33 +665,35 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB,
unsigned NewOpc = 0;
// AM2 - 12 bits, thumb2 - 8 bits.
unsigned Limit = isAM5 ? 0 : (isAM2 ? 0x1000 : 0x100);
+
+ // Try merging with the previous instruction.
if (MBBI != MBB.begin()) {
MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
if (isMatchingDecrement(PrevMBBI, Base, Bytes, Limit, Pred, PredReg)) {
DoMerge = true;
AddSub = ARM_AM::sub;
- NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
} else if (!isAM5 &&
isMatchingIncrement(PrevMBBI, Base, Bytes, Limit,Pred,PredReg)) {
DoMerge = true;
- NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
}
- if (DoMerge)
+ if (DoMerge) {
+ NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
MBB.erase(PrevMBBI);
+ }
}
+ // Try merging with the next instruction.
if (!DoMerge && MBBI != MBB.end()) {
MachineBasicBlock::iterator NextMBBI = llvm::next(MBBI);
if (!isAM5 &&
isMatchingDecrement(NextMBBI, Base, Bytes, Limit, Pred, PredReg)) {
DoMerge = true;
AddSub = ARM_AM::sub;
- NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
} else if (isMatchingIncrement(NextMBBI, Base, Bytes, Limit,Pred,PredReg)) {
DoMerge = true;
- NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
}
if (DoMerge) {
+ NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
if (NextMBBI == I) {
Advance = true;
++I;
@@ -689,22 +708,25 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB,
bool isDPR = NewOpc == ARM::VLDMD || NewOpc == ARM::VSTMD;
unsigned Offset = 0;
if (isAM5)
- Offset = ARM_AM::getAM5Opc((AddSub == ARM_AM::sub)
- ? ARM_AM::db
- : ARM_AM::ia, true, (isDPR ? 2 : 1));
+ Offset = ARM_AM::getAM5Opc(AddSub == ARM_AM::sub ? ARM_AM::db : ARM_AM::ia,
+ true, (isDPR ? 2 : 1));
else if (isAM2)
Offset = ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift);
else
Offset = AddSub == ARM_AM::sub ? -Bytes : Bytes;
- if (isLd) {
- if (isAM5)
- // VLDMS, VLDMD
- BuildMI(MBB, MBBI, dl, TII->get(NewOpc))
- .addReg(Base, getKillRegState(BaseKill))
- .addImm(Offset).addImm(Pred).addReg(PredReg)
- .addReg(Base, getDefRegState(true)) // WB base register
- .addReg(MI->getOperand(0).getReg(), RegState::Define);
- else if (isAM2)
+
+ if (isAM5) {
+ // VLDM[SD}_UPD, VSTM[SD]_UPD
+ MachineOperand &MO = MI->getOperand(0);
+ BuildMI(MBB, MBBI, dl, TII->get(NewOpc))
+ .addReg(Base, getDefRegState(true)) // WB base register
+ .addReg(Base, getKillRegState(isLd ? BaseKill : false))
+ .addImm(Offset)
+ .addImm(Pred).addReg(PredReg)
+ .addReg(MO.getReg(), (isLd ? getDefRegState(true) :
+ getKillRegState(MO.isKill())));
+ } else if (isLd) {
+ if (isAM2)
// LDR_PRE, LDR_POST,
BuildMI(MBB, MBBI, dl, TII->get(NewOpc), MI->getOperand(0).getReg())
.addReg(Base, RegState::Define)
@@ -716,13 +738,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB,
.addReg(Base).addImm(Offset).addImm(Pred).addReg(PredReg);
} else {
MachineOperand &MO = MI->getOperand(0);
- if (isAM5)
- // VSTMS, VSTMD
- BuildMI(MBB, MBBI, dl, TII->get(NewOpc)).addReg(Base).addImm(Offset)
- .addImm(Pred).addReg(PredReg)
- .addReg(Base, getDefRegState(true)) // WB base register
- .addReg(MO.getReg(), getKillRegState(MO.isKill()));
- else if (isAM2)
+ if (isAM2)
// STR_PRE, STR_POST
BuildMI(MBB, MBBI, dl, TII->get(NewOpc), Base)
.addReg(MO.getReg(), getKillRegState(MO.isKill()))
@@ -910,7 +926,6 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
.addReg(BaseReg, getKillRegState(BaseKill))
.addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia))
.addImm(Pred).addReg(PredReg)
- .addReg(0)
.addReg(EvenReg, getDefRegState(isLd) | getDeadRegState(EvenDeadKill))
.addReg(OddReg, getDefRegState(isLd) | getDeadRegState(OddDeadKill));
++NumLDRD2LDM;
@@ -919,7 +934,6 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB,
.addReg(BaseReg, getKillRegState(BaseKill))
.addImm(ARM_AM::getAM4ModeImm(ARM_AM::ia))
.addImm(Pred).addReg(PredReg)
- .addReg(0)
.addReg(EvenReg,
getKillRegState(EvenDeadKill) | getUndefRegState(EvenUndef))
.addReg(OddReg,
@@ -1157,7 +1171,8 @@ bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
if (MBBI != MBB.begin() &&
(MBBI->getOpcode() == ARM::BX_RET || MBBI->getOpcode() == ARM::tBX_RET)) {
MachineInstr *PrevMI = prior(MBBI);
- if (PrevMI->getOpcode() == ARM::LDM || PrevMI->getOpcode() == ARM::t2LDM) {
+ if (PrevMI->getOpcode() == ARM::LDM_UPD ||
+ PrevMI->getOpcode() == ARM::t2LDM_UPD) {
MachineOperand &MO = PrevMI->getOperand(PrevMI->getNumOperands()-1);
if (MO.getReg() != ARM::LR)
return false;
diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp
index 622034b..2dad7f1 100644
--- a/lib/Target/ARM/ARMSubtarget.cpp
+++ b/lib/Target/ARM/ARMSubtarget.cpp
@@ -41,6 +41,7 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
, PostRAScheduler(false)
, IsR9Reserved(ReserveR9)
, UseMovt(UseMOVT)
+ , HasFP16(false)
, stackAlignment(4)
, CPUString("generic")
, TargetType(isELF) // Default to ELF unless otherwise specified.
diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h
index 6980851..2dc81a4 100644
--- a/lib/Target/ARM/ARMSubtarget.h
+++ b/lib/Target/ARM/ARMSubtarget.h
@@ -66,6 +66,10 @@ protected:
/// imms (including global addresses).
bool UseMovt;
+ /// HasFP16 - True if subtarget supports half-precision FP (We support VFP+HF
+ /// only so far)
+ bool HasFP16;
+
/// stackAlignment - The minimum alignment known to hold of the stack frame on
/// entry to the function and which must be maintained by every function.
unsigned stackAlignment;
@@ -94,9 +98,9 @@ protected:
/// getMaxInlineSizeThreshold - Returns the maximum memset / memcpy size
/// that still makes it profitable to inline the call.
unsigned getMaxInlineSizeThreshold() const {
- // FIXME: For now, we don't lower memcpy's to loads / stores for Thumb.
- // Change this once Thumb ldmia / stmia support is added.
- return isThumb() ? 0 : 64;
+ // FIXME: For now, we don't lower memcpy's to loads / stores for Thumb1.
+ // Change this once Thumb1 ldmia / stmia support is added.
+ return isThumb1Only() ? 0 : 64;
}
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
@@ -116,6 +120,8 @@ protected:
bool useNEONForSinglePrecisionFP() const {
return hasNEON() && UseNEONForSinglePrecisionFP; }
+ bool hasFP16() const { return HasFP16; }
+
bool isTargetDarwin() const { return TargetType == isDarwin; }
bool isTargetELF() const { return TargetType == isELF; }
diff --git a/lib/Target/ARM/ARMTargetObjectFile.cpp b/lib/Target/ARM/ARMTargetObjectFile.cpp
index 7463e30..680d032 100644
--- a/lib/Target/ARM/ARMTargetObjectFile.cpp
+++ b/lib/Target/ARM/ARMTargetObjectFile.cpp
@@ -10,7 +10,6 @@
#include "ARMTargetObjectFile.h"
#include "ARMSubtarget.h"
#include "llvm/MC/MCSectionELF.h"
-#include "llvm/MC/MCSectionMachO.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
@@ -35,20 +34,3 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
SectionKind::getDataRel());
}
}
-
-//===----------------------------------------------------------------------===//
-// Mach-O Target
-//===----------------------------------------------------------------------===//
-
-void ARMMachOTargetObjectFile::Initialize(MCContext &Ctx,
- const TargetMachine &TM) {
- TargetLoweringObjectFileMachO::Initialize(Ctx, TM);
-
- // Exception Handling.
- LSDASection = getMachOSection("__TEXT", "__gcc_except_tab", 0,
- SectionKind::getReadOnlyWithRel());
-}
-
-unsigned ARMMachOTargetObjectFile::getTTypeEncoding() const {
- return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4;
-}
diff --git a/lib/Target/ARM/ARMTargetObjectFile.h b/lib/Target/ARM/ARMTargetObjectFile.h
index 481d7ab..097fc2c 100644
--- a/lib/Target/ARM/ARMTargetObjectFile.h
+++ b/lib/Target/ARM/ARMTargetObjectFile.h
@@ -24,18 +24,6 @@ public:
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
};
-// FIXME: This subclass isn't 100% necessary. It will become obsolete once we
-// can place all LSDAs into the TEXT section. See
-// <rdar://problem/6804645>.
-class ARMMachOTargetObjectFile : public TargetLoweringObjectFileMachO {
-public:
- ARMMachOTargetObjectFile() : TargetLoweringObjectFileMachO() {}
-
- virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
-
- virtual unsigned getTTypeEncoding() const;
-};
-
} // end namespace llvm
#endif
diff --git a/lib/Target/ARM/AsmParser/Makefile b/lib/Target/ARM/AsmParser/Makefile
index 97e5612..841516f 100644
--- a/lib/Target/ARM/AsmParser/Makefile
+++ b/lib/Target/ARM/AsmParser/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMARMAsmParser
# Hack: we need to include 'main' ARM target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 314114c..4db14a3 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -38,6 +38,7 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
@@ -74,9 +75,8 @@ namespace {
public:
explicit ARMAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
- : AsmPrinter(O, TM, Ctx, Streamer, T), AFI(NULL), MCP(NULL) {
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer), AFI(NULL), MCP(NULL) {
Subtarget = &TM.getSubtarget<ARMSubtarget>();
}
@@ -120,8 +120,12 @@ namespace {
void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum);
void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum);
void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum);
+ void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum) {}
void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum);
+ void printCPSOptionOperand(const MachineInstr *MI, int OpNum) {}
+ void printMSRMaskOperand(const MachineInstr *MI, int OpNum) {}
+ void printNegZeroOperand(const MachineInstr *MI, int OpNum) {}
void printPredicateOperand(const MachineInstr *MI, int OpNum);
void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum);
void printSBitModifierOperand(const MachineInstr *MI, int OpNum);
@@ -194,7 +198,7 @@ namespace {
bool isIndirect = Subtarget->isTargetDarwin() &&
Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
if (!isIndirect)
- O << *GetGlobalValueSymbol(GV);
+ O << *Mang->getSymbol(GV);
else {
// FIXME: Remove this when Darwin transition to @GOT like syntax.
MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
@@ -202,11 +206,12 @@ namespace {
MachineModuleInfoMachO &MMIMachO =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
- MCSymbol *&StubSym =
+ MachineModuleInfoImpl::StubValueTy &StubSym =
GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
MMIMachO.getGVStubEntry(Sym);
- if (StubSym == 0)
- StubSym = GetGlobalValueSymbol(GV);
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
}
} else {
assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
@@ -299,7 +304,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
break;
}
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
@@ -311,7 +316,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
(TF & ARMII::MO_HI16))
O << ":upper16:";
- O << *GetGlobalValueSymbol(GV);
+ O << *Mang->getSymbol(GV);
printOffset(MO.getOffset());
@@ -516,8 +521,10 @@ void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
if (MO1.getReg() == ARM::SP) {
// FIXME
bool isLDM = (MI->getOpcode() == ARM::LDM ||
+ MI->getOpcode() == ARM::LDM_UPD ||
MI->getOpcode() == ARM::LDM_RET ||
MI->getOpcode() == ARM::t2LDM ||
+ MI->getOpcode() == ARM::t2LDM_UPD ||
MI->getOpcode() == ARM::t2LDM_RET);
O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
} else
@@ -810,11 +817,10 @@ void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum) {
void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum) {
O << "{";
- // Always skip the first operand, it's the optional (and implicit writeback).
- for (unsigned i = OpNum+1, e = MI->getNumOperands(); i != e; ++i) {
+ for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
if (MI->getOperand(i).isImplicit())
continue;
- if ((int)i != OpNum+1) O << ", ";
+ if ((int)i != OpNum) O << ", ";
printOperand(MI, i);
}
O << "}";
@@ -884,16 +890,16 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
if (UseSet && isNew) {
O << "\t.set\t"
<< *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB) << ','
- << *MBB->getSymbol(OutContext) << '-' << *JTISymbol << '\n';
+ << *MBB->getSymbol() << '-' << *JTISymbol << '\n';
}
O << JTEntryDirective << ' ';
if (UseSet)
O << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB);
else if (TM.getRelocationModel() == Reloc::PIC_)
- O << *MBB->getSymbol(OutContext) << '-' << *JTISymbol;
+ O << *MBB->getSymbol() << '-' << *JTISymbol;
else
- O << *MBB->getSymbol(OutContext);
+ O << *MBB->getSymbol();
if (i != e-1)
O << '\n';
@@ -925,9 +931,9 @@ void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) {
O << MAI->getData16bitsDirective();
if (ByteOffset || HalfWordOffset)
- O << '(' << *MBB->getSymbol(OutContext) << "-" << *JTISymbol << ")/2";
+ O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
else
- O << "\tb.w " << *MBB->getSymbol(OutContext);
+ O << "\tb.w " << *MBB->getSymbol();
if (i != e-1)
O << '\n';
@@ -1123,7 +1129,7 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
// Output non-lazy-pointers for external and common global variables.
MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
-
+
if (!Stubs.empty()) {
// Switch with ".non_lazy_symbol_pointer" directive.
OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
@@ -1132,15 +1138,16 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
// L_foo$stub:
OutStreamer.EmitLabel(Stubs[i].first);
// .indirect_symbol _foo
- MCSymbol *MCSym = Stubs[i].second;
- OutStreamer.EmitSymbolAttribute(MCSym, MCSA_IndirectSymbol);
+ MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
+ OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
- if (MCSym->isUndefined())
+ if (MCSym.getInt())
// External to current translation unit.
OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
else
// Internal to current translation unit.
- OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym, OutContext),
+ OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
+ OutContext),
4/*size*/, 0/*addrspace*/);
}
@@ -1156,8 +1163,9 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
// L_foo$stub:
OutStreamer.EmitLabel(Stubs[i].first);
// .long _foo
- OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second,
- OutContext),
+ OutStreamer.EmitValue(MCSymbolRefExpr::
+ Create(Stubs[i].second.getPointer(),
+ OutContext),
4/*size*/, 0/*addrspace*/);
}
diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
index b7964c9..9a3cbc3 100644
--- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h
@@ -50,7 +50,7 @@ public:
void printAddrMode6Operand(const MCInst *MI, unsigned OpNum);
void printAddrModePCOperand(const MCInst *MI, unsigned OpNum,
const char *Modifier = 0);
-
+
void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum);
void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum);
@@ -68,8 +68,12 @@ public:
void printT2AddrModeImm8Operand(const MCInst *MI, unsigned OpNum) {}
void printT2AddrModeImm8s4Operand(const MCInst *MI, unsigned OpNum) {}
void printT2AddrModeImm8OffsetOperand(const MCInst *MI, unsigned OpNum) {}
+ void printT2AddrModeImm8s4OffsetOperand(const MCInst *MI, unsigned OpNum) {}
void printT2AddrModeSoRegOperand(const MCInst *MI, unsigned OpNum) {}
+ void printCPSOptionOperand(const MCInst *MI, unsigned OpNum) {}
+ void printMSRMaskOperand(const MCInst *MI, unsigned OpNum) {}
+ void printNegZeroOperand(const MCInst *MI, unsigned OpNum) {}
void printPredicateOperand(const MCInst *MI, unsigned OpNum);
void printMandatoryPredicateOperand(const MCInst *MI, unsigned OpNum);
void printSBitModifierOperand(const MCInst *MI, unsigned OpNum);
diff --git a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
index 5f8705e..7cb305f 100644
--- a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
@@ -21,6 +21,7 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
//#include "llvm/MC/MCStreamer.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
using namespace llvm;
@@ -45,7 +46,7 @@ GetGlobalAddressSymbol(const MachineOperand &MO) const {
case 0: break;
}
- return Printer.GetGlobalValueSymbol(MO.getGlobal());
+ return Printer.Mang->getSymbol(MO.getGlobal());
}
MCSymbol *ARMMCInstLower::
@@ -135,7 +136,7 @@ void ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
- MO.getMBB()->getSymbol(Ctx), Ctx));
+ MO.getMBB()->getSymbol(), Ctx));
break;
case MachineOperand::MO_GlobalAddress:
MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
diff --git a/lib/Target/ARM/AsmPrinter/Makefile b/lib/Target/ARM/AsmPrinter/Makefile
index 208becc..65d372e 100644
--- a/lib/Target/ARM/AsmPrinter/Makefile
+++ b/lib/Target/ARM/AsmPrinter/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMARMAsmPrinter
# Hack: we need to include 'main' arm target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/ARM/Thumb1InstrInfo.cpp b/lib/Target/ARM/Thumb1InstrInfo.cpp
index 7f42c82..29ae631 100644
--- a/lib/Target/ARM/Thumb1InstrInfo.cpp
+++ b/lib/Target/ARM/Thumb1InstrInfo.cpp
@@ -159,7 +159,6 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH));
AddDefaultPred(MIB);
- MIB.addReg(0); // No write back.
for (unsigned i = CSI.size(); i != 0; --i) {
unsigned Reg = CSI[i-1].getReg();
// Add the callee-saved register as live-in. It's killed at the spill.
@@ -182,7 +181,6 @@ restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
DebugLoc DL = MI->getDebugLoc();
MachineInstrBuilder MIB = BuildMI(MF, DL, get(ARM::tPOP));
AddDefaultPred(MIB);
- MIB.addReg(0); // No write back.
bool NumRegs = false;
for (unsigned i = CSI.size(); i != 0; --i) {
diff --git a/lib/Target/ARM/Thumb1RegisterInfo.cpp b/lib/Target/ARM/Thumb1RegisterInfo.cpp
index 6215d2f..99c38b1 100644
--- a/lib/Target/ARM/Thumb1RegisterInfo.cpp
+++ b/lib/Target/ARM/Thumb1RegisterInfo.cpp
@@ -791,9 +791,9 @@ static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs))
return true;
else if (MI->getOpcode() == ARM::tPOP) {
- // The first three operands are predicates and such. The last two are
+ // The first two operands are predicates. The last two are
// imp-def and imp-use of SP. Check everything in between.
- for (int i = 3, e = MI->getNumOperands() - 2; i != e; ++i)
+ for (int i = 2, e = MI->getNumOperands() - 2; i != e; ++i)
if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs))
return false;
return true;
@@ -854,12 +854,16 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
}
if (VARegSaveSize) {
+ // Unlike T2 and ARM mode, the T1 pop instruction cannot restore
+ // to LR, and we can't pop the value directly to the PC since
+ // we need to update the SP after popping the value. Therefore, we
+ // pop the old LR into R3 as a temporary.
+
// Move back past the callee-saved register restoration
while (MBBI != MBB.end() && isCSRestore(MBBI, CSRegs))
++MBBI;
// Epilogue for vararg functions: pop LR to R3 and branch off it.
AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)))
- .addReg(0) // No write back.
.addReg(ARM::R3, RegState::Define);
emitSPUpdate(MBB, MBBI, TII, dl, *this, VARegSaveSize);
diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp
index 5086eff..2bc75f2 100644
--- a/lib/Target/ARM/Thumb2SizeReduction.cpp
+++ b/lib/Target/ARM/Thumb2SizeReduction.cpp
@@ -121,9 +121,11 @@ namespace {
{ ARM::t2STRHi12,ARM::tSTRH, 0, 5, 0, 1, 0, 0,0, 1 },
{ ARM::t2STRHs, ARM::tSTRH, 0, 0, 0, 1, 0, 0,0, 1 },
+ { ARM::t2LDM, ARM::tLDM, 0, 0, 0, 1, 1, 1,1, 1 },
{ ARM::t2LDM_RET,0, ARM::tPOP_RET, 0, 0, 1, 1, 1,1, 1 },
- { ARM::t2LDM, ARM::tLDM, ARM::tPOP, 0, 0, 1, 1, 1,1, 1 },
- { ARM::t2STM, ARM::tSTM, ARM::tPUSH, 0, 0, 1, 1, 1,1, 1 },
+ { ARM::t2LDM_UPD,ARM::tLDM_UPD,ARM::tPOP, 0, 0, 1, 1, 1,1, 1 },
+ // ARM::t2STM (with no basereg writeback) has no Thumb1 equivalent
+ { ARM::t2STM_UPD,ARM::tSTM_UPD,ARM::tPUSH, 0, 0, 1, 1, 1,1, 1 },
};
class Thumb2SizeReduce : public MachineFunctionPass {
@@ -231,8 +233,9 @@ Thumb2SizeReduce::VerifyPredAndCC(MachineInstr *MI, const ReduceEntry &Entry,
static bool VerifyLowRegs(MachineInstr *MI) {
unsigned Opc = MI->getOpcode();
- bool isPCOk = (Opc == ARM::t2LDM_RET) || (Opc == ARM::t2LDM);
- bool isLROk = (Opc == ARM::t2STM);
+ bool isPCOk = (Opc == ARM::t2LDM_RET || Opc == ARM::t2LDM ||
+ Opc == ARM::t2LDM_UPD);
+ bool isLROk = (Opc == ARM::t2STM_UPD);
bool isSPOk = isPCOk || isLROk || (Opc == ARM::t2ADDrSPi);
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
@@ -307,19 +310,35 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI,
HasShift = true;
OpNum = 4;
break;
- case ARM::t2LDM_RET:
- case ARM::t2LDM:
- case ARM::t2STM: {
- OpNum = 0;
+ case ARM::t2LDM: {
unsigned BaseReg = MI->getOperand(0).getReg();
- unsigned Mode = MI->getOperand(1).getImm();
- if (BaseReg == ARM::SP && ARM_AM::getAM4WBFlag(Mode)) {
- Opc = Entry.NarrowOpc2;
- OpNum = 2;
- } else if (Entry.WideOpc == ARM::t2LDM_RET ||
- !isARMLowRegister(BaseReg) ||
- !ARM_AM::getAM4WBFlag(Mode) ||
- ARM_AM::getAM4SubMode(Mode) != ARM_AM::ia) {
+ ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(1).getImm());
+ if (!isARMLowRegister(BaseReg) || Mode != ARM_AM::ia)
+ return false;
+ OpNum = 0;
+ isLdStMul = true;
+ break;
+ }
+ case ARM::t2LDM_RET: {
+ unsigned BaseReg = MI->getOperand(1).getReg();
+ if (BaseReg != ARM::SP)
+ return false;
+ Opc = Entry.NarrowOpc2; // tPOP_RET
+ OpNum = 3;
+ isLdStMul = true;
+ break;
+ }
+ case ARM::t2LDM_UPD:
+ case ARM::t2STM_UPD: {
+ OpNum = 0;
+ unsigned BaseReg = MI->getOperand(1).getReg();
+ ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(2).getImm());
+ if (BaseReg == ARM::SP &&
+ ((Entry.WideOpc == ARM::t2LDM_UPD && Mode == ARM_AM::ia) ||
+ (Entry.WideOpc == ARM::t2STM_UPD && Mode == ARM_AM::db))) {
+ Opc = Entry.NarrowOpc2; // tPOP or tPUSH
+ OpNum = 3;
+ } else if (!isARMLowRegister(BaseReg) || Mode != ARM_AM::ia) {
return false;
}
isLdStMul = true;
diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td
index 95de3d8..91e58ce 100644
--- a/lib/Target/Alpha/AlphaInstrInfo.td
+++ b/lib/Target/Alpha/AlphaInstrInfo.td
@@ -1059,8 +1059,8 @@ def : Pat<(i64 immSExt16:$imm),
def : Pat<(i64 immSExt16int:$imm),
(ZAPNOTi (LDA (SExt16 immSExt16int:$imm), R31), 15)>;
def : Pat<(i64 immConst2PartInt:$imm),
- (ZAPNOTi (LDA (LL16 (SExt32 immConst2PartInt:$imm)),
- (LDAH (LH16 (SExt32 immConst2PartInt:$imm)), R31)), 15)>;
+ (ZAPNOTi (LDA (LL16 (i64 (SExt32 immConst2PartInt:$imm))),
+ (LDAH (LH16 (i64 (SExt32 immConst2PartInt:$imm))), R31)), 15)>;
//TODO: I want to just define these like this!
diff --git a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
index 733a46c..093cf05 100644
--- a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
+++ b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
@@ -24,6 +24,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
@@ -37,9 +38,8 @@ namespace {
///
explicit AlphaAsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
- : AsmPrinter(o, tm, Ctx, Streamer, T) {}
+ MCStreamer &Streamer)
+ : AsmPrinter(o, tm, Streamer) {}
virtual const char *getPassName() const {
return "Alpha Assembly Printer";
@@ -96,7 +96,7 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_ConstantPoolIndex:
@@ -109,7 +109,7 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
return;
case MachineOperand::MO_GlobalAddress:
- O << *GetGlobalValueSymbol(MO.getGlobal());
+ O << *Mang->getSymbol(MO.getGlobal());
return;
case MachineOperand::MO_JumpTableIndex:
diff --git a/lib/Target/Alpha/AsmPrinter/Makefile b/lib/Target/Alpha/AsmPrinter/Makefile
index 3c64a3c..ea13c38 100644
--- a/lib/Target/Alpha/AsmPrinter/Makefile
+++ b/lib/Target/Alpha/AsmPrinter/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMAlphaAsmPrinter
# Hack: we need to include 'main' alpha target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
index fe13e14..1c6d841 100644
--- a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
+++ b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
@@ -27,6 +27,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
@@ -39,9 +40,8 @@ namespace {
class BlackfinAsmPrinter : public AsmPrinter {
public:
BlackfinAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *MAI)
- : AsmPrinter(O, TM, Ctx, Streamer, MAI) {}
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer) {}
virtual const char *getPassName() const {
return "Blackfin Assembly Printer";
@@ -82,10 +82,10 @@ void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress:
- O << *GetGlobalValueSymbol(MO.getGlobal());
+ O << *Mang->getSymbol(MO.getGlobal());
printOffset(MO.getOffset());
break;
case MachineOperand::MO_ExternalSymbol:
diff --git a/lib/Target/Blackfin/AsmPrinter/Makefile b/lib/Target/Blackfin/AsmPrinter/Makefile
index 091d4df..a106a23 100644
--- a/lib/Target/Blackfin/AsmPrinter/Makefile
+++ b/lib/Target/Blackfin/AsmPrinter/Makefile
@@ -11,6 +11,6 @@ LIBRARYNAME = LLVMBlackfinAsmPrinter
# Hack: we need to include 'main' Blackfin target directory to grab private
# headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 10f873f..b1ba0d2 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -36,6 +36,7 @@
#include "llvm/Target/Mangler.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetRegistry.h"
@@ -95,6 +96,7 @@ namespace {
LoopInfo *LI;
const Module *TheModule;
const MCAsmInfo* TAsm;
+ MCContext *TCtx;
const TargetData* TD;
std::map<const Type *, std::string> TypeNames;
std::map<const ConstantFP *, unsigned> FPConstantMap;
@@ -1731,7 +1733,8 @@ bool CWriter::doInitialization(Module &M) {
TAsm = Match->createAsmInfo(Triple);
#endif
TAsm = new CBEMCAsmInfo();
- Mang = new Mangler(*TAsm);
+ TCtx = new MCContext(*TAsm);
+ Mang = new Mangler(*TCtx, *TD);
// Keep track of which functions are static ctors/dtors so they can have
// an attribute added to their prototypes.
diff --git a/lib/Target/CellSPU/AsmPrinter/Makefile b/lib/Target/CellSPU/AsmPrinter/Makefile
index 69639ef..4ec9d04 100644
--- a/lib/Target/CellSPU/AsmPrinter/Makefile
+++ b/lib/Target/CellSPU/AsmPrinter/Makefile
@@ -12,6 +12,6 @@ LIBRARYNAME = LLVMCellSPUAsmPrinter
# Hack: we need to include 'main' CellSPU target directory to grab
# private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
index 2ca05c2..857ddcf 100644
--- a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
+++ b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
@@ -24,6 +24,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetOptions.h"
@@ -38,9 +39,8 @@ namespace {
class SPUAsmPrinter : public AsmPrinter {
public:
explicit SPUAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T) :
- AsmPrinter(O, TM, Ctx, Streamer, T) {}
+ MCStreamer &Streamer) :
+ AsmPrinter(O, TM, Streamer) {}
virtual const char *getPassName() const {
return "STI CBEA SPU Assembly Printer";
@@ -281,7 +281,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
@@ -311,7 +311,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
return;
}
}
- O << *GetGlobalValueSymbol(MO.getGlobal());
+ O << *Mang->getSymbol(MO.getGlobal());
return;
default:
O << "<unknown operand type: " << MO.getType() << ">";
diff --git a/lib/Target/CellSPU/CellSDKIntrinsics.td b/lib/Target/CellSPU/CellSDKIntrinsics.td
index 1fe7aff..9468aee 100644
--- a/lib/Target/CellSPU/CellSDKIntrinsics.td
+++ b/lib/Target/CellSPU/CellSDKIntrinsics.td
@@ -205,10 +205,9 @@ def CellSDKnand:
// Shift/rotate intrinsics:
//===----------------------------------------------------------------------===//
-/* FIXME: These have (currently unenforced) type conflicts. */
def CellSDKshli:
Pat<(int_spu_si_shli (v4i32 VECREG:$rA), uimm7:$val),
- (SHLIv4i32 VECREG:$rA, uimm7:$val)>;
+ (SHLIv4i32 VECREG:$rA, (TO_IMM32 imm:$val))>;
def CellSDKshlqbi:
Pat<(int_spu_si_shlqbi VECREG:$rA, R32C:$rB),
@@ -216,7 +215,7 @@ def CellSDKshlqbi:
def CellSDKshlqii:
Pat<(int_spu_si_shlqbii VECREG:$rA, uimm7:$val),
- (SHLQBIIv16i8 VECREG:$rA, uimm7:$val)>;
+ (SHLQBIIv16i8 VECREG:$rA, (TO_IMM32 imm:$val))>;
def CellSDKshlqby:
Pat<(int_spu_si_shlqby VECREG:$rA, R32C:$rB),
@@ -224,7 +223,8 @@ def CellSDKshlqby:
def CellSDKshlqbyi:
Pat<(int_spu_si_shlqbyi VECREG:$rA, uimm7:$val),
- (SHLQBYIv16i8 VECREG:$rA, uimm7:$val)>;
+ (SHLQBYIv16i8 VECREG:$rA, (TO_IMM32 imm:$val))>;
+
//===----------------------------------------------------------------------===//
// Branch/compare intrinsics:
diff --git a/lib/Target/CellSPU/SPU64InstrInfo.td b/lib/Target/CellSPU/SPU64InstrInfo.td
index 47cb579..069a182 100644
--- a/lib/Target/CellSPU/SPU64InstrInfo.td
+++ b/lib/Target/CellSPU/SPU64InstrInfo.td
@@ -155,8 +155,9 @@ multiclass CompareLogicalGreaterEqual64 {
defm I64LGE: CompareLogicalGreaterEqual64;
def : Pat<(setuge R64C:$rA, R64C:$rB), I64LGEr64.Fragment>;
-def : Pat<(setuge (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)),
- I64LGEv2i64.Fragment>;
+def : Pat<(v2i64 (setuge (v2i64 VECREG:$rA), (v2i64 VECREG:$rB))),
+ I64LGEv2i64.Fragment>;
+
// i64 setult:
def : I64SETCCNegCond<setult, I64LGEr64>;
@@ -233,8 +234,8 @@ multiclass CompareGreaterEqual64 {
defm I64GE: CompareGreaterEqual64;
def : Pat<(setge R64C:$rA, R64C:$rB), I64GEr64.Fragment>;
-def : Pat<(setge (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)),
- I64GEv2i64.Fragment>;
+def : Pat<(v2i64 (setge (v2i64 VECREG:$rA), (v2i64 VECREG:$rB))),
+ I64GEv2i64.Fragment>;
// i64 setult:
def : I64SETCCNegCond<setlt, I64GEr64>;
diff --git a/lib/Target/CellSPU/SPUInstrInfo.td b/lib/Target/CellSPU/SPUInstrInfo.td
index b96b64e..ad12604 100644
--- a/lib/Target/CellSPU/SPUInstrInfo.td
+++ b/lib/Target/CellSPU/SPUInstrInfo.td
@@ -2179,10 +2179,10 @@ multiclass ShiftLeftHalfwordImm
defm SHLHI : ShiftLeftHalfwordImm;
def : Pat<(SPUvec_shl (v8i16 VECREG:$rA), (i32 uimm7:$val)),
- (SHLHIv8i16 VECREG:$rA, uimm7:$val)>;
+ (SHLHIv8i16 VECREG:$rA, (TO_IMM16 uimm7:$val))>;
def : Pat<(shl R16C:$rA, (i32 uimm7:$val)),
- (SHLHIr16 R16C:$rA, uimm7:$val)>;
+ (SHLHIr16 R16C:$rA, (TO_IMM16 uimm7:$val))>;
//===----------------------------------------------------------------------===//
@@ -2410,8 +2410,8 @@ multiclass RotateLeftHalfwordImm
defm ROTHI: RotateLeftHalfwordImm;
-def : Pat<(SPUvec_rotl VECREG:$rA, (i32 uimm7:$val)),
- (ROTHIv8i16 VECREG:$rA, imm:$val)>;
+def : Pat<(SPUvec_rotl (v8i16 VECREG:$rA), (i32 uimm7:$val)),
+ (ROTHIv8i16 VECREG:$rA, (TO_IMM16 imm:$val))>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// Rotate word:
@@ -2682,10 +2682,10 @@ def : Pat<(SPUvec_srl (v8i16 VECREG:$rA), (i32 imm:$val)),
(ROTHMIv8i16 VECREG:$rA, imm:$val)>;
def: Pat<(SPUvec_srl (v8i16 VECREG:$rA), (i16 imm:$val)),
- (ROTHMIv8i16 VECREG:$rA, imm:$val)>;
+ (ROTHMIv8i16 VECREG:$rA, (TO_IMM32 imm:$val))>;
def: Pat<(SPUvec_srl (v8i16 VECREG:$rA), (i8 imm:$val)),
- (ROTHMIv8i16 VECREG:$rA, imm:$val)>;
+ (ROTHMIv8i16 VECREG:$rA, (TO_IMM32 imm:$val))>;
def ROTHMIr16:
ROTHMIInst<(outs R16C:$rT), (ins R16C:$rA, rothNeg7imm:$val),
@@ -2695,10 +2695,10 @@ def: Pat<(srl R16C:$rA, (i32 uimm7:$val)),
(ROTHMIr16 R16C:$rA, uimm7:$val)>;
def: Pat<(srl R16C:$rA, (i16 uimm7:$val)),
- (ROTHMIr16 R16C:$rA, uimm7:$val)>;
+ (ROTHMIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>;
def: Pat<(srl R16C:$rA, (i8 uimm7:$val)),
- (ROTHMIr16 R16C:$rA, uimm7:$val)>;
+ (ROTHMIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>;
// ROTM v4i32 form: See the ROTHM v8i16 comments.
class ROTMInst<dag OOL, dag IOL, list<dag> pattern>:
@@ -2709,14 +2709,14 @@ def ROTMv4i32:
ROTMInst<(outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
[/* see patterns below - $rB must be negated */]>;
-def : Pat<(SPUvec_srl VECREG:$rA, R32C:$rB),
+def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), R32C:$rB),
(ROTMv4i32 VECREG:$rA, (SFIr32 R32C:$rB, 0))>;
-def : Pat<(SPUvec_srl VECREG:$rA, R16C:$rB),
+def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), R16C:$rB),
(ROTMv4i32 VECREG:$rA,
(SFIr32 (XSHWr16 R16C:$rB), 0))>;
-def : Pat<(SPUvec_srl VECREG:$rA, R8C:$rB),
+def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), R8C:$rB),
(ROTMv4i32 VECREG:$rA,
(SFIr32 (XSHWr16 (XSBHr8 R8C:$rB)), 0))>;
@@ -2742,11 +2742,11 @@ def ROTMIv4i32:
[(set (v4i32 VECREG:$rT),
(SPUvec_srl VECREG:$rA, (i32 uimm7:$val)))]>;
-def : Pat<(SPUvec_srl VECREG:$rA, (i16 uimm7:$val)),
- (ROTMIv4i32 VECREG:$rA, uimm7:$val)>;
+def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), (i16 uimm7:$val)),
+ (ROTMIv4i32 VECREG:$rA, (TO_IMM32 uimm7:$val))>;
-def : Pat<(SPUvec_srl VECREG:$rA, (i8 uimm7:$val)),
- (ROTMIv4i32 VECREG:$rA, uimm7:$val)>;
+def : Pat<(SPUvec_srl (v4i32 VECREG:$rA), (i8 uimm7:$val)),
+ (ROTMIv4i32 VECREG:$rA, (TO_IMM32 uimm7:$val))>;
// ROTMI r32 form: know how to complement the immediate value.
def ROTMIr32:
@@ -2755,10 +2755,10 @@ def ROTMIr32:
[(set R32C:$rT, (srl R32C:$rA, (i32 uimm7:$val)))]>;
def : Pat<(srl R32C:$rA, (i16 imm:$val)),
- (ROTMIr32 R32C:$rA, uimm7:$val)>;
+ (ROTMIr32 R32C:$rA, (TO_IMM32 uimm7:$val))>;
def : Pat<(srl R32C:$rA, (i8 imm:$val)),
- (ROTMIr32 R32C:$rA, uimm7:$val)>;
+ (ROTMIr32 R32C:$rA, (TO_IMM32 uimm7:$val))>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// ROTQMBY: This is a vector form merely so that when used in an
@@ -2916,14 +2916,14 @@ def ROTMAHv8i16:
"rotmah\t$rT, $rA, $rB", RotateShift,
[/* see patterns below - $rB must be negated */]>;
-def : Pat<(SPUvec_sra VECREG:$rA, R32C:$rB),
+def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), R32C:$rB),
(ROTMAHv8i16 VECREG:$rA, (SFIr32 R32C:$rB, 0))>;
-def : Pat<(SPUvec_sra VECREG:$rA, R16C:$rB),
+def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), R16C:$rB),
(ROTMAHv8i16 VECREG:$rA,
(SFIr32 (XSHWr16 R16C:$rB), 0))>;
-def : Pat<(SPUvec_sra VECREG:$rA, R8C:$rB),
+def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), R8C:$rB),
(ROTMAHv8i16 VECREG:$rA,
(SFIr32 (XSHWr16 (XSBHr8 R8C:$rB)), 0))>;
@@ -2950,10 +2950,10 @@ def ROTMAHIv8i16:
(SPUvec_sra (v8i16 VECREG:$rA), (i32 uimm7:$val)))]>;
def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), (i16 uimm7:$val)),
- (ROTMAHIv8i16 (v8i16 VECREG:$rA), (i32 uimm7:$val))>;
+ (ROTMAHIv8i16 (v8i16 VECREG:$rA), (TO_IMM32 uimm7:$val))>;
def : Pat<(SPUvec_sra (v8i16 VECREG:$rA), (i8 uimm7:$val)),
- (ROTMAHIv8i16 (v8i16 VECREG:$rA), (i32 uimm7:$val))>;
+ (ROTMAHIv8i16 (v8i16 VECREG:$rA), (TO_IMM32 uimm7:$val))>;
def ROTMAHIr16:
RRForm<0b01111110000, (outs R16C:$rT), (ins R16C:$rA, rothNeg7imm_i16:$val),
@@ -2961,25 +2961,25 @@ def ROTMAHIr16:
[(set R16C:$rT, (sra R16C:$rA, (i16 uimm7:$val)))]>;
def : Pat<(sra R16C:$rA, (i32 imm:$val)),
- (ROTMAHIr16 R16C:$rA, uimm7:$val)>;
+ (ROTMAHIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>;
def : Pat<(sra R16C:$rA, (i8 imm:$val)),
- (ROTMAHIr16 R16C:$rA, uimm7:$val)>;
+ (ROTMAHIr16 R16C:$rA, (TO_IMM32 uimm7:$val))>;
def ROTMAv4i32:
RRForm<0b01011010000, (outs VECREG:$rT), (ins VECREG:$rA, R32C:$rB),
"rotma\t$rT, $rA, $rB", RotateShift,
[/* see patterns below - $rB must be negated */]>;
-def : Pat<(SPUvec_sra VECREG:$rA, R32C:$rB),
- (ROTMAv4i32 (v4i32 VECREG:$rA), (SFIr32 R32C:$rB, 0))>;
+def : Pat<(SPUvec_sra (v4i32 VECREG:$rA), R32C:$rB),
+ (ROTMAv4i32 VECREG:$rA, (SFIr32 R32C:$rB, 0))>;
-def : Pat<(SPUvec_sra VECREG:$rA, R16C:$rB),
- (ROTMAv4i32 (v4i32 VECREG:$rA),
+def : Pat<(SPUvec_sra (v4i32 VECREG:$rA), R16C:$rB),
+ (ROTMAv4i32 VECREG:$rA,
(SFIr32 (XSHWr16 R16C:$rB), 0))>;
-def : Pat<(SPUvec_sra VECREG:$rA, R8C:$rB),
- (ROTMAv4i32 (v4i32 VECREG:$rA),
+def : Pat<(SPUvec_sra (v4i32 VECREG:$rA), R8C:$rB),
+ (ROTMAv4i32 VECREG:$rA,
(SFIr32 (XSHWr16 (XSBHr8 R8C:$rB)), 0))>;
def ROTMAr32:
diff --git a/lib/Target/CellSPU/SPUOperands.td b/lib/Target/CellSPU/SPUOperands.td
index 802628f..6216651 100644
--- a/lib/Target/CellSPU/SPUOperands.td
+++ b/lib/Target/CellSPU/SPUOperands.td
@@ -9,6 +9,17 @@
// Cell SPU Instruction Operands:
//===----------------------------------------------------------------------===//
+// TO_IMM32 - Convert an i8/i16 to i32.
+def TO_IMM32 : SDNodeXForm<imm, [{
+ return getI32Imm(N->getZExtValue());
+}]>;
+
+// TO_IMM16 - Convert an i8/i32 to i16.
+def TO_IMM16 : SDNodeXForm<imm, [{
+ return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i16);
+}]>;
+
+
def LO16 : SDNodeXForm<imm, [{
unsigned val = N->getZExtValue();
// Transformation function: get the low 16 bits.
diff --git a/lib/Target/CellSPU/SPURegisterInfo.cpp b/lib/Target/CellSPU/SPURegisterInfo.cpp
index 4ba0cb1..8c78bab 100644
--- a/lib/Target/CellSPU/SPURegisterInfo.cpp
+++ b/lib/Target/CellSPU/SPURegisterInfo.cpp
@@ -436,7 +436,7 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
// Prepare for debug frame info.
bool hasDebugInfo = MMI && MMI->hasDebugInfo();
- unsigned FrameLabelId = 0;
+ MCSymbol *FrameLabel = 0;
// Move MBBI back to the beginning of the function.
MBBI = MBB.begin();
@@ -452,8 +452,8 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
FrameSize = -(FrameSize + SPUFrameInfo::minStackSize());
if (hasDebugInfo) {
// Mark effective beginning of when frame pointer becomes valid.
- FrameLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, dl, TII.get(SPU::DBG_LABEL)).addImm(FrameLabelId);
+ FrameLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(SPU::DBG_LABEL)).addSym(FrameLabel);
}
// Adjust stack pointer, spilling $lr -> 16($sp) and $sp -> -FrameSize($sp)
@@ -500,7 +500,7 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
// Show update of SP.
MachineLocation SPDst(MachineLocation::VirtualFP);
MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize);
- Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
+ Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
// Add callee saved registers to move list.
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
@@ -510,16 +510,16 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
if (Reg == SPU::R0) continue;
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
MachineLocation CSSrc(Reg);
- Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc));
+ Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc));
}
// Mark effective beginning of when frame pointer is ready.
- unsigned ReadyLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, dl, TII.get(SPU::DBG_LABEL)).addImm(ReadyLabelId);
+ MCSymbol *ReadyLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(SPU::DBG_LABEL)).addSym(ReadyLabel);
MachineLocation FPDst(SPU::R1);
MachineLocation FPSrc(MachineLocation::VirtualFP);
- Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc));
+ Moves.push_back(MachineMove(ReadyLabel, FPDst, FPSrc));
}
} else {
// This is a leaf function -- insert a branch hint iff there are
@@ -530,8 +530,8 @@ void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
dl = MBBI->getDebugLoc();
// Insert terminator label
- unsigned BranchLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, dl, TII.get(SPU::DBG_LABEL)).addImm(BranchLabelId);
+ BuildMI(MBB, MBBI, dl, TII.get(SPU::DBG_LABEL))
+ .addSym(MMI->getContext().CreateTempSymbol());
}
}
}
diff --git a/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp
index 6fe1026..ee2c7c8 100644
--- a/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp
+++ b/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp
@@ -31,6 +31,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
@@ -52,9 +53,8 @@ namespace {
const MBlazeSubtarget *Subtarget;
public:
explicit MBlazeAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T )
- : AsmPrinter(O, TM, Ctx, Streamer, T) {
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer) {
Subtarget = &TM.getSubtarget<MBlazeSubtarget>();
}
@@ -236,11 +236,11 @@ void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
}
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress:
- O << *GetGlobalValueSymbol(MO.getGlobal());
+ O << *Mang->getSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
diff --git a/lib/Target/MBlaze/AsmPrinter/Makefile b/lib/Target/MBlaze/AsmPrinter/Makefile
index c8e4d8f..c44651c 100644
--- a/lib/Target/MBlaze/AsmPrinter/Makefile
+++ b/lib/Target/MBlaze/AsmPrinter/Makefile
@@ -12,6 +12,6 @@ LIBRARYNAME = LLVMMBlazeAsmPrinter
# Hack: we need to include 'main' MBlaze target directory to grab
# private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
index 7a35eb0..04ac6f1 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
@@ -32,6 +32,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
@@ -42,9 +43,8 @@ namespace {
class MSP430AsmPrinter : public AsmPrinter {
public:
MSP430AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *MAI)
- : AsmPrinter(O, TM, Ctx, Streamer, MAI) {}
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer) {}
virtual const char *getPassName() const {
return "MSP430 Assembly Printer";
@@ -92,7 +92,7 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
@@ -109,7 +109,7 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
if (Offset)
O << '(' << Offset << '+';
- O << *GetGlobalValueSymbol(MO.getGlobal());
+ O << *Mang->getSymbol(MO.getGlobal());
if (Offset)
O << ')';
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp b/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
index 2e5ef8e..32c6b04 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
@@ -20,6 +20,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/SmallString.h"
@@ -32,7 +33,7 @@ GetGlobalAddressSymbol(const MachineOperand &MO) const {
case 0: break;
}
- return Printer.GetGlobalValueSymbol(MO.getGlobal());
+ return Printer.Mang->getSymbol(MO.getGlobal());
}
MCSymbol *MSP430MCInstLower::
@@ -116,7 +117,7 @@ void MSP430MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
- MO.getMBB()->getSymbol(Printer.OutContext), Ctx));
+ MO.getMBB()->getSymbol(), Ctx));
break;
case MachineOperand::MO_GlobalAddress:
MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
diff --git a/lib/Target/MSP430/AsmPrinter/Makefile b/lib/Target/MSP430/AsmPrinter/Makefile
index 4f340c6..a5293ab 100644
--- a/lib/Target/MSP430/AsmPrinter/Makefile
+++ b/lib/Target/MSP430/AsmPrinter/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMMSP430AsmPrinter
# Hack: we need to include 'main' MSP430 target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/Mangler.cpp b/lib/Target/Mangler.cpp
index ef6defc..fb93706 100644
--- a/lib/Target/Mangler.cpp
+++ b/lib/Target/Mangler.cpp
@@ -12,8 +12,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/Target/Mangler.h"
-#include "llvm/GlobalValue.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
using namespace llvm;
@@ -59,11 +63,10 @@ static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
/// appendMangledName - Add the specified string in mangled form if it uses
/// any unusual characters.
static void appendMangledName(SmallVectorImpl<char> &OutName, StringRef Str,
- const MCAsmInfo *MAI) {
+ const MCAsmInfo &MAI) {
// The first character is not allowed to be a number unless the target
// explicitly allows it.
- if ((MAI == 0 || !MAI->doesAllowNameToStartWithDigit()) &&
- Str[0] >= '0' && Str[0] <= '9') {
+ if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9') {
MangleLetter(OutName, Str[0]);
Str = Str.substr(1);
}
@@ -100,6 +103,8 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
StringRef Name = GVName.toStringRef(TmpData);
assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
+ const MCAsmInfo &MAI = Context.getAsmInfo();
+
// If the global name is not led with \1, add the appropriate prefixes.
if (Name[0] == '\1') {
Name = Name.substr(1);
@@ -134,7 +139,7 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
// On systems that do not allow quoted names, we need to mangle most
// strange characters.
if (!MAI.doesAllowQuotesInName())
- return appendMangledName(OutName, Name, &MAI);
+ return appendMangledName(OutName, Name, MAI);
// Okay, the system allows quoted strings. We can quote most anything, the
// only characters that need escaping are " and \n.
@@ -142,6 +147,26 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
return appendMangledQuotedName(OutName, Name);
}
+/// AddFastCallStdCallSuffix - Microsoft fastcall and stdcall functions require
+/// a suffix on their name indicating the number of words of arguments they
+/// take.
+static void AddFastCallStdCallSuffix(SmallVectorImpl<char> &OutName,
+ const Function *F, const TargetData &TD) {
+ // Calculate arguments size total.
+ unsigned ArgWords = 0;
+ for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ AI != AE; ++AI) {
+ const Type *Ty = AI->getType();
+ // 'Dereference' type in case of byval parameter attribute
+ if (AI->hasByValAttr())
+ Ty = cast<PointerType>(Ty)->getElementType();
+ // Size should be aligned to DWORD boundary
+ ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
+ }
+
+ raw_svector_ostream(OutName) << '@' << ArgWords;
+}
+
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
/// and the specified global variable's name. If the global variable doesn't
@@ -156,16 +181,43 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
PrefixTy = Mangler::LinkerPrivate;
// If this global has a name, handle it simply.
- if (GV->hasName())
- return getNameWithPrefix(OutName, GV->getName(), PrefixTy);
+ if (GV->hasName()) {
+ getNameWithPrefix(OutName, GV->getName(), PrefixTy);
+ } else {
+ // Get the ID for the global, assigning a new one if we haven't got one
+ // already.
+ unsigned &ID = AnonGlobalIDs[GV];
+ if (ID == 0) ID = NextAnonGlobalID++;
- // Get the ID for the global, assigning a new one if we haven't got one
- // already.
- unsigned &ID = AnonGlobalIDs[GV];
- if (ID == 0) ID = NextAnonGlobalID++;
+ // Must mangle the global into a unique ID.
+ getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy);
+ }
- // Must mangle the global into a unique ID.
- getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy);
+ // If we are supposed to add a microsoft-style suffix for stdcall/fastcall,
+ // add it.
+ if (Context.getAsmInfo().hasMicrosoftFastStdCallMangling()) {
+ if (const Function *F = dyn_cast<Function>(GV)) {
+ CallingConv::ID CC = F->getCallingConv();
+
+ // fastcall functions need to start with @.
+ // FIXME: This logic seems unlikely to be right.
+ if (CC == CallingConv::X86_FastCall) {
+ if (OutName[0] == '_')
+ OutName[0] = '@';
+ else
+ OutName.insert(OutName.begin(), '@');
+ }
+
+ // fastcall and stdcall functions usually need @42 at the end to specify
+ // the argument info.
+ const FunctionType *FT = F->getFunctionType();
+ if ((CC == CallingConv::X86_FastCall || CC == CallingConv::X86_StdCall) &&
+ // "Pure" variadic functions do not receive @0 suffix.
+ (!FT->isVarArg() || FT->getNumParams() == 0 ||
+ (FT->getNumParams() == 1 && F->hasStructRetAttr())))
+ AddFastCallStdCallSuffix(OutName, F, TD);
+ }
+ }
}
/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
@@ -177,3 +229,16 @@ std::string Mangler::getNameWithPrefix(const GlobalValue *GV,
getNameWithPrefix(Buf, GV, isImplicitlyPrivate);
return std::string(Buf.begin(), Buf.end());
}
+
+/// getSymbol - Return the MCSymbol for the specified global value. This
+/// symbol is the main label that is the address of the global.
+MCSymbol *Mangler::getSymbol(const GlobalValue *GV) {
+ SmallString<60> NameStr;
+ getNameWithPrefix(NameStr, GV, false);
+ if (!GV->hasPrivateLinkage())
+ return Context.GetOrCreateSymbol(NameStr.str());
+
+ return Context.GetOrCreateTemporarySymbol(NameStr.str());
+}
+
+
diff --git a/lib/Target/Mips/AsmPrinter/Makefile b/lib/Target/Mips/AsmPrinter/Makefile
index a2fecf4..b1efe9b 100644
--- a/lib/Target/Mips/AsmPrinter/Makefile
+++ b/lib/Target/Mips/AsmPrinter/Makefile
@@ -12,6 +12,6 @@ LIBRARYNAME = LLVMMipsAsmPrinter
# Hack: we need to include 'main' Mips target directory to grab
# private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
index b8641c3..2a2d9dc 100644
--- a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
@@ -31,6 +31,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
@@ -50,9 +51,8 @@ namespace {
const MipsSubtarget *Subtarget;
public:
explicit MipsAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
- : AsmPrinter(O, TM, Ctx, Streamer, T) {
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer) {
Subtarget = &TM.getSubtarget<MipsSubtarget>();
}
@@ -277,11 +277,11 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
break;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress:
- O << *GetGlobalValueSymbol(MO.getGlobal());
+ O << *Mang->getSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
diff --git a/lib/Target/PIC16/AsmPrinter/Makefile b/lib/Target/PIC16/AsmPrinter/Makefile
index f4db57e..e3c0684 100644
--- a/lib/Target/PIC16/AsmPrinter/Makefile
+++ b/lib/Target/PIC16/AsmPrinter/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMPIC16AsmPrinter
# Hack: we need to include 'main' pic16 target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
index 44a6cc0..b6eceb3 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
@@ -25,6 +25,7 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/ErrorHandling.h"
@@ -35,11 +36,10 @@ using namespace llvm;
#include "PIC16GenAsmWriter.inc"
PIC16AsmPrinter::PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
-: AsmPrinter(O, TM, Ctx, Streamer, T), DbgInfo(O, T) {
+ MCStreamer &Streamer)
+: AsmPrinter(O, TM, Streamer), DbgInfo(O, TM.getMCAsmInfo()) {
PTLI = static_cast<PIC16TargetLowering*>(TM.getTargetLowering());
- PMAI = static_cast<const PIC16MCAsmInfo*>(T);
+ PMAI = static_cast<const PIC16MCAsmInfo*>(TM.getMCAsmInfo());
PTOF = (PIC16TargetObjectFile *)&PTLI->getObjFileLowering();
}
@@ -179,7 +179,7 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
return;
case MachineOperand::MO_GlobalAddress: {
- MCSymbol *Sym = GetGlobalValueSymbol(MO.getGlobal());
+ MCSymbol *Sym = Mang->getSymbol(MO.getGlobal());
// FIXME: currently we do not have a memcpy def coming in the module
// by any chance, as we do not link in those as .bc lib. So these calls
// are always external and it is safe to emit an extern.
@@ -206,7 +206,7 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
break;
}
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
default:
@@ -312,7 +312,7 @@ void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
if (!I->isDeclaration() && !I->hasExternalLinkage())
continue;
- MCSymbol *Sym = GetGlobalValueSymbol(I);
+ MCSymbol *Sym = Mang->getSymbol(I);
// Do not emit memcpy, memset, and memmove here.
// Calls to these routines can be generated in two ways,
@@ -342,7 +342,7 @@ void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
for (unsigned j = 0; j < Items.size(); j++)
- O << MAI->getExternDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
+ O << MAI->getExternDirective() << *Mang->getSymbol(Items[j]) << "\n";
O << MAI->getCommentString() << "Imported Variables - END" << "\n";
}
@@ -353,7 +353,7 @@ void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
for (unsigned j = 0; j < Items.size(); j++)
- O << MAI->getGlobalDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
+ O << MAI->getGlobalDirective() << *Mang->getSymbol(Items[j]) << "\n";
O << MAI->getCommentString() << "Exported Variables - END" << "\n";
}
@@ -432,7 +432,7 @@ void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
for (unsigned j = 0; j < Items.size(); j++) {
Constant *C = Items[j]->getInitializer();
int AddrSpace = Items[j]->getType()->getAddressSpace();
- O << *GetGlobalValueSymbol(Items[j]);
+ O << *Mang->getSymbol(Items[j]);
EmitGlobalConstant(C, AddrSpace);
}
}
@@ -451,7 +451,7 @@ EmitUninitializedDataSection(const PIC16Section *S) {
Constant *C = Items[j]->getInitializer();
const Type *Ty = C->getType();
unsigned Size = TD->getTypeAllocSize(Ty);
- O << *GetGlobalValueSymbol(Items[j]) << " RES " << Size << "\n";
+ O << *Mang->getSymbol(Items[j]) << " RES " << Size << "\n";
}
}
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
index 77b6e63..519be4c 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
@@ -31,8 +31,7 @@ namespace llvm {
class VISIBILITY_HIDDEN PIC16AsmPrinter : public AsmPrinter {
public:
explicit PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T);
+ MCStreamer &Streamer);
private:
virtual const char *getPassName() const {
return "PIC16 Assembly Printer";
diff --git a/lib/Target/PowerPC/AsmPrinter/Makefile b/lib/Target/PowerPC/AsmPrinter/Makefile
index 269ef92..bd5dce1 100644
--- a/lib/Target/PowerPC/AsmPrinter/Makefile
+++ b/lib/Target/PowerPC/AsmPrinter/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMPowerPCAsmPrinter
# Hack: we need to include 'main' PowerPC target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index 3c7dfaf..ed6fc9d 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -34,6 +34,7 @@
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
@@ -60,9 +61,8 @@ namespace {
uint64_t LabelID;
public:
explicit PPCAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
- : AsmPrinter(O, TM, Ctx, Streamer, T),
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer),
Subtarget(TM.getSubtarget<PPCSubtarget>()), LabelID(0) {}
virtual const char *getPassName() const {
@@ -198,10 +198,11 @@ namespace {
if (GV->isDeclaration() || GV->isWeakForLinker()) {
// Dynamically-resolved functions need a stub for the function.
MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
- MCSymbol *&StubSym =
+ MachineModuleInfoImpl::StubValueTy &StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
- if (StubSym == 0)
- StubSym = GetGlobalValueSymbol(GV);
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
O << *Sym;
return;
}
@@ -212,10 +213,11 @@ namespace {
TempNameStr += StringRef("$stub");
MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
- MCSymbol *&StubSym =
+ MachineModuleInfoImpl::StubValueTy &StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
- if (StubSym == 0)
- StubSym = GetExternalSymbolSymbol(MO.getSymbolName());
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
O << *Sym;
return;
}
@@ -300,10 +302,8 @@ namespace {
void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo) {
const MachineOperand &MO = MI->getOperand(OpNo);
-
assert(MO.getType() == MachineOperand::MO_GlobalAddress);
-
- const MCSymbol *Sym = GetGlobalValueSymbol(MO.getGlobal());
+ const MCSymbol *Sym = Mang->getSymbol(MO.getGlobal());
// Map symbol -> label of TOC entry.
const MCSymbol *&TOCEntry = TOC[Sym];
@@ -323,9 +323,8 @@ namespace {
class PPCLinuxAsmPrinter : public PPCAsmPrinter {
public:
explicit PPCLinuxAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
- : PPCAsmPrinter(O, TM, Ctx, Streamer, T) {}
+ MCStreamer &Streamer)
+ : PPCAsmPrinter(O, TM, Streamer) {}
virtual const char *getPassName() const {
return "Linux PPC Assembly Printer";
@@ -349,9 +348,8 @@ namespace {
formatted_raw_ostream &OS;
public:
explicit PPCDarwinAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
- : PPCAsmPrinter(O, TM, Ctx, Streamer, T), OS(O) {}
+ MCStreamer &Streamer)
+ : PPCAsmPrinter(O, TM, Streamer), OS(O) {}
virtual const char *getPassName() const {
return "Darwin PPC Assembly Printer";
@@ -380,7 +378,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
llvm_unreachable("printOp() does not handle immediate values");
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
@@ -404,10 +402,11 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
MCSymbol *NLPSym =
OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
MO.getSymbolName()+"$non_lazy_ptr");
- MCSymbol *&StubSym =
+ MachineModuleInfoImpl::StubValueTy &StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
- if (StubSym == 0)
- StubSym = GetExternalSymbolSymbol(MO.getSymbolName());
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
O << *NLPSym;
return;
@@ -422,24 +421,27 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
(GV->isDeclaration() || GV->isWeakForLinker())) {
if (!GV->hasHiddenVisibility()) {
SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
- MCSymbol *&StubSym =
- MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(SymToPrint);
- if (StubSym == 0)
- StubSym = GetGlobalValueSymbol(GV);
+ MachineModuleInfoImpl::StubValueTy &StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>()
+ .getGVStubEntry(SymToPrint);
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
} else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
GV->hasAvailableExternallyLinkage()) {
SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
- MCSymbol *&StubSym =
+ MachineModuleInfoImpl::StubValueTy &StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().
getHiddenGVStubEntry(SymToPrint);
- if (StubSym == 0)
- StubSym = GetGlobalValueSymbol(GV);
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
} else {
- SymToPrint = GetGlobalValueSymbol(GV);
+ SymToPrint = Mang->getSymbol(GV);
}
} else {
- SymToPrint = GetGlobalValueSymbol(GV);
+ SymToPrint = Mang->getSymbol(GV);
}
O << *SymToPrint;
@@ -704,7 +706,7 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
EmitAlignment(4);
const MCSymbol *Stub = Stubs[i].first;
- const MCSymbol *RawSym = Stubs[i].second;
+ const MCSymbol *RawSym = Stubs[i].second.getPointer();
const MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
const MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
@@ -738,7 +740,7 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
16, SectionKind::getText());
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
const MCSymbol *Stub = Stubs[i].first;
- const MCSymbol *RawSym = Stubs[i].second;
+ const MCSymbol *RawSym = Stubs[i].second.getPointer();
const MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
OutStreamer.SwitchSection(StubSection);
@@ -781,8 +783,9 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
E = Personalities.end(); I != E; ++I) {
if (*I) {
MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
- MCSymbol *&StubSym = MMIMacho.getGVStubEntry(NLPSym);
- StubSym = GetGlobalValueSymbol(*I);
+ MachineModuleInfoImpl::StubValueTy &StubSym =
+ MMIMacho.getGVStubEntry(NLPSym);
+ StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
}
}
}
@@ -797,10 +800,24 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
EmitAlignment(isPPC64 ? 3 : 2);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- O << *Stubs[i].first << ":\n";
- O << "\t.indirect_symbol " << *Stubs[i].second << '\n';
- O << (isPPC64 ? "\t.quad\t0\n" : "\t.long\t0\n");
+ // L_foo$stub:
+ OutStreamer.EmitLabel(Stubs[i].first);
+ // .indirect_symbol _foo
+ MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
+ OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
+
+ if (MCSym.getInt())
+ // External to current translation unit.
+ OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
+ else
+ // Internal to current translation unit.
+ OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
+ OutContext),
+ isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
}
+
+ Stubs.clear();
+ OutStreamer.AddBlankLine();
}
Stubs = MMIMacho.GetHiddenGVStubList();
@@ -809,9 +826,17 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
EmitAlignment(isPPC64 ? 3 : 2);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- O << *Stubs[i].first << ":\n";
- O << (isPPC64 ? "\t.quad\t" : "\t.long\t") << *Stubs[i].second << '\n';
+ // L_foo$stub:
+ OutStreamer.EmitLabel(Stubs[i].first);
+ // .long _foo
+ OutStreamer.EmitValue(MCSymbolRefExpr::
+ Create(Stubs[i].second.getPointer(),
+ OutContext),
+ isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
}
+
+ Stubs.clear();
+ OutStreamer.AddBlankLine();
}
// Funny Darwin hack: This flag tells the linker that no global symbols
@@ -824,21 +849,18 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
return AsmPrinter::doFinalization(M);
}
-
-
/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
/// for a MachineFunction to the given output stream, in a format that the
/// Darwin assembler can deal with.
///
static AsmPrinter *createPPCAsmPrinterPass(formatted_raw_ostream &o,
TargetMachine &tm,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *tai) {
+ MCStreamer &Streamer) {
const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
if (Subtarget->isDarwin())
- return new PPCDarwinAsmPrinter(o, tm, Ctx, Streamer, tai);
- return new PPCLinuxAsmPrinter(o, tm, Ctx, Streamer, tai);
+ return new PPCDarwinAsmPrinter(o, tm, Streamer);
+ return new PPCLinuxAsmPrinter(o, tm, Streamer);
}
// Force static initialization.
diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp
index 327470d..f7c27d4 100644
--- a/lib/Target/PowerPC/PPCCodeEmitter.cpp
+++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp
@@ -30,6 +30,7 @@ namespace {
class PPCCodeEmitter : public MachineFunctionPass {
TargetMachine &TM;
JITCodeEmitter &MCE;
+ MachineModuleInfo *MMI;
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineModuleInfo>();
@@ -87,7 +88,8 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
MF.getTarget().getRelocationModel() != Reloc::Static) &&
"JIT relocation model must be set to static or default!");
- MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
+ MMI = &getAnalysis<MachineModuleInfo>();
+ MCE.setModuleInfo(MMI);
do {
MovePCtoLROffset = 0;
MCE.startFunction(MF);
@@ -110,7 +112,7 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
break;
case TargetOpcode::DBG_LABEL:
case TargetOpcode::EH_LABEL:
- MCE.emitLabel(MI.getOperand(0).getImm());
+ MCE.emitLabel(MI.getOperand(0).getMCSymbol());
break;
case TargetOpcode::IMPLICIT_DEF:
case TargetOpcode::KILL:
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index aeaa7c6..2c072c1 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -13,9 +13,9 @@
#include "PPCISelLowering.h"
#include "PPCMachineFunctionInfo.h"
+#include "PPCPerfectShuffle.h"
#include "PPCPredicates.h"
#include "PPCTargetMachine.h"
-#include "PPCPerfectShuffle.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/CodeGen/CallingConvLower.h"
@@ -60,10 +60,10 @@ cl::desc("enable preincrement load/store generation on PPC (experimental)"),
static TargetLoweringObjectFile *CreateTLOF(const PPCTargetMachine &TM) {
if (TM.getSubtargetImpl()->isDarwin())
return new TargetLoweringObjectFileMachO();
+
return new TargetLoweringObjectFileELF();
}
-
PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
: TargetLowering(TM, CreateTLOF(TM)), PPCSubTarget(*TM.getSubtargetImpl()) {
@@ -4216,7 +4216,7 @@ static bool getAltivecCompareInfo(SDValue Intrin, int &CompareOpc,
/// LowerINTRINSIC_WO_CHAIN - If this is an intrinsic that we want to custom
/// lower, do it, otherwise return null.
SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
- SelectionDAG &DAG) {
+ SelectionDAG &DAG) {
// If this is a lowered altivec predicate compare, CompareOpc is set to the
// opcode number of the comparison.
DebugLoc dl = Op.getDebugLoc();
@@ -4228,8 +4228,8 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
// If this is a non-dot comparison, make the VCMP node and we are done.
if (!isDot) {
SDValue Tmp = DAG.getNode(PPCISD::VCMP, dl, Op.getOperand(2).getValueType(),
- Op.getOperand(1), Op.getOperand(2),
- DAG.getConstant(CompareOpc, MVT::i32));
+ Op.getOperand(1), Op.getOperand(2),
+ DAG.getConstant(CompareOpc, MVT::i32));
return DAG.getNode(ISD::BIT_CONVERT, dl, Op.getValueType(), Tmp);
}
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 31bca16..6e7880e 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -1287,7 +1287,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
UnwindTablesMandatory;
// Prepare for frame info.
- unsigned FrameLabelId = 0;
+ MCSymbol *FrameLabel = 0;
// Scan the prolog, looking for an UPDATE_VRSAVE instruction. If we find it,
// process it.
@@ -1446,33 +1446,33 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
// reverse order.
if (needsFrameMoves) {
// Mark effective beginning of when frame pointer becomes valid.
- FrameLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addImm(FrameLabelId);
+ FrameLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addSym(FrameLabel);
// Show update of SP.
if (NegFrameSize) {
MachineLocation SPDst(MachineLocation::VirtualFP);
MachineLocation SPSrc(MachineLocation::VirtualFP, NegFrameSize);
- Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
+ Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
} else {
MachineLocation SP(isPPC64 ? PPC::X31 : PPC::R31);
- Moves.push_back(MachineMove(FrameLabelId, SP, SP));
+ Moves.push_back(MachineMove(FrameLabel, SP, SP));
}
if (HasFP) {
MachineLocation FPDst(MachineLocation::VirtualFP, FPOffset);
MachineLocation FPSrc(isPPC64 ? PPC::X31 : PPC::R31);
- Moves.push_back(MachineMove(FrameLabelId, FPDst, FPSrc));
+ Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
}
if (MustSaveLR) {
MachineLocation LRDst(MachineLocation::VirtualFP, LROffset);
MachineLocation LRSrc(isPPC64 ? PPC::LR8 : PPC::LR);
- Moves.push_back(MachineMove(FrameLabelId, LRDst, LRSrc));
+ Moves.push_back(MachineMove(FrameLabel, LRDst, LRSrc));
}
}
- unsigned ReadyLabelId = 0;
+ MCSymbol *ReadyLabel = 0;
// If there is a frame pointer, copy R1 into R31
if (HasFP) {
@@ -1487,20 +1487,20 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
}
if (needsFrameMoves) {
- ReadyLabelId = MMI->NextLabelID();
+ ReadyLabel = MMI->getContext().CreateTempSymbol();
// Mark effective beginning of when frame pointer is ready.
- BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addImm(ReadyLabelId);
+ BuildMI(MBB, MBBI, dl, TII.get(PPC::DBG_LABEL)).addSym(ReadyLabel);
MachineLocation FPDst(HasFP ? (isPPC64 ? PPC::X31 : PPC::R31) :
(isPPC64 ? PPC::X1 : PPC::R1));
MachineLocation FPSrc(MachineLocation::VirtualFP);
- Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc));
+ Moves.push_back(MachineMove(ReadyLabel, FPDst, FPSrc));
}
}
if (needsFrameMoves) {
- unsigned LabelId = HasFP ? ReadyLabelId : FrameLabelId;
+ MCSymbol *Label = HasFP ? ReadyLabel : FrameLabel;
// Add callee saved registers to move list.
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
@@ -1510,7 +1510,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
MachineLocation CSSrc(Reg);
- Moves.push_back(MachineMove(LabelId, CSDst, CSSrc));
+ Moves.push_back(MachineMove(Label, CSDst, CSSrc));
}
}
}
diff --git a/lib/Target/README.txt b/lib/Target/README.txt
index 4fd46a8..052a575 100644
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -1819,3 +1819,27 @@ int test2(int mainType, int subType) {
}
//===---------------------------------------------------------------------===//
+
+The following test case (from PR6576):
+
+define i32 @mul(i32 %a, i32 %b) nounwind readnone {
+entry:
+ %cond1 = icmp eq i32 %b, 0 ; <i1> [#uses=1]
+ br i1 %cond1, label %exit, label %bb.nph
+bb.nph: ; preds = %entry
+ %tmp = mul i32 %b, %a ; <i32> [#uses=1]
+ ret i32 %tmp
+exit: ; preds = %entry
+ ret i32 0
+}
+
+could be reduced to:
+
+define i32 @mul(i32 %a, i32 %b) nounwind readnone {
+entry:
+ %tmp = mul i32 %b, %a
+ ret i32 %tmp
+}
+
+//===---------------------------------------------------------------------===//
+
diff --git a/lib/Target/Sparc/AsmPrinter/Makefile b/lib/Target/Sparc/AsmPrinter/Makefile
index a856828..fe47538 100644
--- a/lib/Target/Sparc/AsmPrinter/Makefile
+++ b/lib/Target/Sparc/AsmPrinter/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMSparcAsmPrinter
# Hack: we need to include 'main' Sparc target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
index f6753a6..3e40dbb 100644
--- a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
@@ -21,6 +21,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormattedStream.h"
@@ -30,9 +31,8 @@ namespace {
class SparcAsmPrinter : public AsmPrinter {
public:
explicit SparcAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
- : AsmPrinter(O, TM, Ctx, Streamer, T) {}
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer) {}
virtual const char *getPassName() const {
return "Sparc Assembly Printer";
@@ -84,10 +84,10 @@ void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << (int)MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress:
- O << *GetGlobalValueSymbol(MO.getGlobal());
+ O << *Mang->getSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
O << MO.getSymbolName();
diff --git a/lib/Target/SystemZ/AsmPrinter/Makefile b/lib/Target/SystemZ/AsmPrinter/Makefile
index 9a350df..0f90ed3 100644
--- a/lib/Target/SystemZ/AsmPrinter/Makefile
+++ b/lib/Target/SystemZ/AsmPrinter/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMSystemZAsmPrinter
# Hack: we need to include 'main' SystemZ target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
index 7a9e8dd..b29dfcd 100644
--- a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
@@ -29,6 +29,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
@@ -40,9 +41,8 @@ namespace {
class SystemZAsmPrinter : public AsmPrinter {
public:
SystemZAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *MAI)
- : AsmPrinter(O, TM, Ctx, Streamer, MAI) {}
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer) {}
virtual const char *getPassName() const {
return "SystemZ Assembly Printer";
@@ -89,11 +89,11 @@ void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum){
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress: {
const GlobalValue *GV = MO.getGlobal();
- O << *GetGlobalValueSymbol(GV);
+ O << *Mang->getSymbol(GV);
// Assemble calls via PLT for externally visible symbols if PIC.
if (TM.getRelocationModel() == Reloc::PIC_ &&
@@ -144,7 +144,7 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
@@ -158,7 +158,7 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
printOffset(MO.getOffset());
break;
case MachineOperand::MO_GlobalAddress:
- O << *GetGlobalValueSymbol(MO.getGlobal());
+ O << *Mang->getSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol: {
O << *GetExternalSymbolSymbol(MO.getSymbolName());
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index 8c12039..a093e2d 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -19,6 +19,7 @@
#include "llvm/GlobalVariable.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
@@ -290,45 +291,38 @@ TargetLoweringObjectFile::getSectionForConstant(SectionKind Kind) const {
return DataSection;
}
-/// getSymbolForDwarfGlobalReference - Return an MCExpr to use for a
+/// getExprForDwarfGlobalReference - Return an MCExpr to use for a
/// reference to the specified global variable from exception
/// handling information.
const MCExpr *TargetLoweringObjectFile::
-getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding) const {
- // FIXME: Use GetGlobalValueSymbol.
- SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, false);
- const MCSymbol *Sym;
-
- if (GV->hasPrivateLinkage())
- Sym = getContext().GetOrCreateTemporarySymbol(Name.str());
- else
- Sym = getContext().GetOrCreateSymbol(Name.str());
-
- return getSymbolForDwarfReference(Sym, MMI, Encoding);
+getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const {
+ const MCSymbol *Sym = Mang->getSymbol(GV);
+ return getExprForDwarfReference(Sym, Mang, MMI, Encoding, Streamer);
}
const MCExpr *TargetLoweringObjectFile::
-getSymbolForDwarfReference(const MCSymbol *Sym, MachineModuleInfo *MMI,
- unsigned Encoding) const {
+getExprForDwarfReference(const MCSymbol *Sym, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const {
const MCExpr *Res = MCSymbolRefExpr::Create(Sym, getContext());
switch (Encoding & 0xF0) {
default:
llvm_report_error("We do not support this DWARF encoding yet!");
- break;
case dwarf::DW_EH_PE_absptr:
// Do nothing special
- break;
- case dwarf::DW_EH_PE_pcrel:
- // FIXME: PCSymbol
- const MCExpr *PC = MCSymbolRefExpr::Create(".", getContext());
- Res = MCBinaryExpr::CreateSub(Res, PC, getContext());
- break;
+ return Res;
+ case dwarf::DW_EH_PE_pcrel: {
+ // Emit a label to the streamer for the current position. This gives us
+ // .-foo addressing.
+ MCSymbol *PCSym = getContext().GetOrCreateTemporarySymbol();
+ Streamer.EmitLabel(PCSym);
+ const MCExpr *PC = MCSymbolRefExpr::Create(PCSym, getContext());
+ return MCBinaryExpr::CreateSub(Res, PC, getContext());
+ }
}
-
- return Res;
}
unsigned TargetLoweringObjectFile::getPersonalityEncoding() const {
diff --git a/lib/Target/X86/AsmParser/Makefile b/lib/Target/X86/AsmParser/Makefile
index 25fb0a2..fb97607 100644
--- a/lib/Target/X86/AsmParser/Makefile
+++ b/lib/Target/X86/AsmParser/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMX86AsmParser
# Hack: we need to include 'main' x86 target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 84d7bb7..dde86fb 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -542,6 +542,15 @@ ParseInstruction(const StringRef &Name, SMLoc NameLoc,
}
}
+ // FIXME: Hack to handle recognizing s{hr,ar,hl}? $1.
+ if ((Name.startswith("shr") || Name.startswith("sar") ||
+ Name.startswith("shl")) &&
+ Operands.size() == 3 &&
+ static_cast<X86Operand*>(Operands[1])->isImm() &&
+ isa<MCConstantExpr>(static_cast<X86Operand*>(Operands[1])->getImm()) &&
+ cast<MCConstantExpr>(static_cast<X86Operand*>(Operands[1])->getImm())->getValue() == 1)
+ Operands.erase(Operands.begin() + 1);
+
return false;
}
diff --git a/lib/Target/X86/AsmPrinter/Makefile b/lib/Target/X86/AsmPrinter/Makefile
index 2368761..c82aa33 100644
--- a/lib/Target/X86/AsmPrinter/Makefile
+++ b/lib/Target/X86/AsmPrinter/Makefile
@@ -10,6 +10,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMX86AsmPrinter
# Hack: we need to include 'main' x86 target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index caf84b6..c3dcf8e 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -53,30 +53,6 @@ void X86AsmPrinter::PrintPICBaseSymbol() const {
OutContext);
}
-MCSymbol *X86AsmPrinter::GetGlobalValueSymbol(const GlobalValue *GV) const {
- SmallString<60> NameStr;
- Mang->getNameWithPrefix(NameStr, GV, false);
- MCSymbol *Symb;
- if (GV->hasPrivateLinkage())
- Symb = OutContext.GetOrCreateTemporarySymbol(NameStr.str());
- else
- Symb = OutContext.GetOrCreateSymbol(NameStr.str());
-
- if (Subtarget->isTargetCygMing()) {
- X86COFFMachineModuleInfo &COFFMMI =
- MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(Symb, OutContext, GV, *TM.getTargetData());
-
- // Save function name for later type emission.
- if (const Function *F = dyn_cast<Function>(GV))
- if (F->isDeclaration())
- COFFMMI.addExternalFunction(Symb->getName());
-
- }
-
- return Symb;
-}
-
/// runOnMachineFunction - Emit the function body.
///
bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
@@ -124,7 +100,7 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
GVSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
else
- GVSym = GetGlobalValueSymbol(GV);
+ GVSym = Mang->getSymbol(GV);
// Handle dllimport linkage.
if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
@@ -133,24 +109,25 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
-
- MCSymbol *&StubSym =
+ MachineModuleInfoImpl::StubValueTy &StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
- if (StubSym == 0)
- StubSym = GetGlobalValueSymbol(GV);
-
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
- MCSymbol *&StubSym =
+ MachineModuleInfoImpl::StubValueTy &StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(Sym);
- if (StubSym == 0)
- StubSym = GetGlobalValueSymbol(GV);
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
- MCSymbol *&StubSym =
+ MachineModuleInfoImpl::StubValueTy &StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
- if (StubSym == 0)
- StubSym = GetGlobalValueSymbol(GV);
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
}
// If the name begins with a dollar-sign, enclose it in parens. We do this
@@ -170,13 +147,15 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
TempNameStr += StringRef("$stub");
MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
- MCSymbol *&StubSym =
+ MachineModuleInfoImpl::StubValueTy &StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
- if (StubSym == 0) {
+ if (StubSym.getPointer() == 0) {
TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end());
- StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(OutContext.GetOrCreateSymbol(TempNameStr.str()),
+ true);
}
- SymToPrint = StubSym;
+ SymToPrint = StubSym.getPointer();
} else {
SymToPrint = GetExternalSymbolSymbol(MO.getSymbolName());
}
@@ -235,7 +214,7 @@ void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_ExternalSymbol:
@@ -480,6 +459,11 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
return false;
}
+void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
+ if (Subtarget->isTargetDarwin())
+ OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
+}
+
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetDarwin()) {
@@ -507,7 +491,8 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
// L_foo$stub:
OutStreamer.EmitLabel(Stubs[i].first);
// .indirect_symbol _foo
- OutStreamer.EmitSymbolAttribute(Stubs[i].second, MCSA_IndirectSymbol);
+ OutStreamer.EmitSymbolAttribute(Stubs[i].second.getPointer(),
+ MCSA_IndirectSymbol);
// hlt; hlt; hlt; hlt; hlt hlt = 0xf4 = -12.
const char HltInsts[] = { -12, -12, -12, -12, -12 };
OutStreamer.EmitBytes(StringRef(HltInsts, 5), 0/*addrspace*/);
@@ -530,9 +515,18 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
// L_foo$non_lazy_ptr:
OutStreamer.EmitLabel(Stubs[i].first);
// .indirect_symbol _foo
- OutStreamer.EmitSymbolAttribute(Stubs[i].second, MCSA_IndirectSymbol);
+ MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
+ OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),
+ MCSA_IndirectSymbol);
// .long 0
- OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
+ if (MCSym.getInt())
+ // External to current translation unit.
+ OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
+ else
+ // Internal to current translation unit.
+ OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
+ OutContext),
+ 4/*size*/, 0/*addrspace*/);
}
Stubs.clear();
OutStreamer.AddBlankLine();
@@ -547,8 +541,9 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
// L_foo$non_lazy_ptr:
OutStreamer.EmitLabel(Stubs[i].first);
// .long _foo
- OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second,
- OutContext),
+ OutStreamer.EmitValue(MCSymbolRefExpr::
+ Create(Stubs[i].second.getPointer(),
+ OutContext),
4/*size*/, 0/*addrspace*/);
}
Stubs.clear();
@@ -584,15 +579,13 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
static_cast<TargetLoweringObjectFileCOFF&>(getObjFileLowering());
for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (I->hasDLLExportLinkage()) {
- MCSymbol *Sym = GetGlobalValueSymbol(I);
- DLLExportedFns.push_back(Sym);
- }
+ if (I->hasDLLExportLinkage())
+ DLLExportedFns.push_back(Mang->getSymbol(I));
for (Module::const_global_iterator I = M.global_begin(),
E = M.global_end(); I != E; ++I)
if (I->hasDLLExportLinkage())
- DLLExportedGlobals.push_back(GetGlobalValueSymbol(I));
+ DLLExportedGlobals.push_back(Mang->getSymbol(I));
// Output linker support code for dllexported globals on windows.
if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
@@ -624,7 +617,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
O << *Stubs[i].first << ":\n"
<< (TD->getPointerSize() == 8 ?
MAI->getData64bitsDirective() : MAI->getData32bitsDirective())
- << *Stubs[i].second << '\n';
+ << *Stubs[i].second.getPointer() << '\n';
Stubs.clear();
}
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
index 039214a..28c25f9 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
@@ -36,9 +36,8 @@ class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
const X86Subtarget *Subtarget;
public:
explicit X86AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
- : AsmPrinter(O, TM, Ctx, Streamer, T) {
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer) {
Subtarget = &TM.getSubtarget<X86Subtarget>();
}
@@ -55,13 +54,13 @@ class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
AsmPrinter::getAnalysisUsage(AU);
}
-
+ virtual void EmitStartOfAsmFile(Module &M);
+
virtual void EmitEndOfAsmFile(Module &M);
virtual void EmitInstruction(const MachineInstr *MI);
void printSymbolOperand(const MachineOperand &MO);
- virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
// These methods are used by the tablegen'erated instruction printer.
void printOperand(const MachineInstr *MI, unsigned OpNo,
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
index b8a6eeb..cbfc57a 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
@@ -16,13 +16,13 @@
#include "X86AsmPrinter.h"
#include "X86COFFMachineModuleInfo.h"
#include "X86MCAsmInfo.h"
-#include "X86MCTargetExpr.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/ADT/SmallString.h"
@@ -54,7 +54,12 @@ GetSymbolFromOperand(const MachineOperand &MO) const {
SmallString<128> Name;
- if (MO.isGlobal()) {
+ if (!MO.isGlobal()) {
+ assert(MO.isSymbol());
+ Name += AsmPrinter.MAI->getGlobalPrefix();
+ Name += MO.getSymbolName();
+ } else {
+ const GlobalValue *GV = MO.getGlobal();
bool isImplicitlyPrivate = false;
if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
@@ -62,18 +67,7 @@ GetSymbolFromOperand(const MachineOperand &MO) const {
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
isImplicitlyPrivate = true;
- const GlobalValue *GV = MO.getGlobal();
Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
-
- if (getSubtarget().isTargetCygMing()) {
- X86COFFMachineModuleInfo &COFFMMI =
- AsmPrinter.MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(Name, GV, *AsmPrinter.TM.getTargetData());
- }
- } else {
- assert(MO.isSymbol());
- Name += AsmPrinter.MAI->getGlobalPrefix();
- Name += MO.getSymbolName();
}
// If the target flags on the operand changes the name of the symbol, do that
@@ -91,35 +85,49 @@ GetSymbolFromOperand(const MachineOperand &MO) const {
Name += "$non_lazy_ptr";
MCSymbol *Sym = Ctx.GetOrCreateTemporarySymbol(Name.str());
- MCSymbol *&StubSym = getMachOMMI().getGVStubEntry(Sym);
- if (StubSym == 0) {
+ MachineModuleInfoImpl::StubValueTy &StubSym =
+ getMachOMMI().getGVStubEntry(Sym);
+ if (StubSym.getPointer() == 0) {
assert(MO.isGlobal() && "Extern symbol not handled yet");
- StubSym = AsmPrinter.GetGlobalValueSymbol(MO.getGlobal());
+ StubSym =
+ MachineModuleInfoImpl::
+ StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()),
+ !MO.getGlobal()->hasInternalLinkage());
}
return Sym;
}
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
Name += "$non_lazy_ptr";
MCSymbol *Sym = Ctx.GetOrCreateTemporarySymbol(Name.str());
- MCSymbol *&StubSym = getMachOMMI().getHiddenGVStubEntry(Sym);
- if (StubSym == 0) {
+ MachineModuleInfoImpl::StubValueTy &StubSym =
+ getMachOMMI().getHiddenGVStubEntry(Sym);
+ if (StubSym.getPointer() == 0) {
assert(MO.isGlobal() && "Extern symbol not handled yet");
- StubSym = AsmPrinter.GetGlobalValueSymbol(MO.getGlobal());
+ StubSym =
+ MachineModuleInfoImpl::
+ StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()),
+ !MO.getGlobal()->hasInternalLinkage());
}
return Sym;
}
case X86II::MO_DARWIN_STUB: {
Name += "$stub";
MCSymbol *Sym = Ctx.GetOrCreateTemporarySymbol(Name.str());
- MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym);
- if (StubSym)
+ MachineModuleInfoImpl::StubValueTy &StubSym =
+ getMachOMMI().getFnStubEntry(Sym);
+ if (StubSym.getPointer())
return Sym;
if (MO.isGlobal()) {
- StubSym = AsmPrinter.GetGlobalValueSymbol(MO.getGlobal());
+ StubSym =
+ MachineModuleInfoImpl::
+ StubValueTy(AsmPrinter.Mang->getSymbol(MO.getGlobal()),
+ !MO.getGlobal()->hasInternalLinkage());
} else {
Name.erase(Name.end()-5, Name.end());
- StubSym = Ctx.GetOrCreateTemporarySymbol(Name.str());
+ StubSym =
+ MachineModuleInfoImpl::
+ StubValueTy(Ctx.GetOrCreateTemporarySymbol(Name.str()), false);
}
return Sym;
}
@@ -133,7 +141,7 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
// FIXME: We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing.
const MCExpr *Expr = 0;
- X86MCTargetExpr::VariantKind RefKind = X86MCTargetExpr::Invalid;
+ MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
@@ -144,15 +152,15 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
case X86II::MO_DARWIN_STUB:
break;
- case X86II::MO_TLSGD: RefKind = X86MCTargetExpr::TLSGD; break;
- case X86II::MO_GOTTPOFF: RefKind = X86MCTargetExpr::GOTTPOFF; break;
- case X86II::MO_INDNTPOFF: RefKind = X86MCTargetExpr::INDNTPOFF; break;
- case X86II::MO_TPOFF: RefKind = X86MCTargetExpr::TPOFF; break;
- case X86II::MO_NTPOFF: RefKind = X86MCTargetExpr::NTPOFF; break;
- case X86II::MO_GOTPCREL: RefKind = X86MCTargetExpr::GOTPCREL; break;
- case X86II::MO_GOT: RefKind = X86MCTargetExpr::GOT; break;
- case X86II::MO_GOTOFF: RefKind = X86MCTargetExpr::GOTOFF; break;
- case X86II::MO_PLT: RefKind = X86MCTargetExpr::PLT; break;
+ case X86II::MO_TLSGD: RefKind = MCSymbolRefExpr::VK_TLSGD; break;
+ case X86II::MO_GOTTPOFF: RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break;
+ case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break;
+ case X86II::MO_TPOFF: RefKind = MCSymbolRefExpr::VK_TPOFF; break;
+ case X86II::MO_NTPOFF: RefKind = MCSymbolRefExpr::VK_NTPOFF; break;
+ case X86II::MO_GOTPCREL: RefKind = MCSymbolRefExpr::VK_GOTPCREL; break;
+ case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break;
+ case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break;
+ case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break;
case X86II::MO_PIC_BASE_OFFSET:
case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
@@ -164,12 +172,8 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
break;
}
- if (Expr == 0) {
- if (RefKind == X86MCTargetExpr::Invalid)
- Expr = MCSymbolRefExpr::Create(Sym, Ctx);
- else
- Expr = X86MCTargetExpr::Create(Sym, RefKind, Ctx);
- }
+ if (Expr == 0)
+ Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx);
if (!MO.isJTI() && MO.getOffset())
Expr = MCBinaryExpr::CreateAdd(Expr,
@@ -233,7 +237,7 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
- MO.getMBB()->getSymbol(Ctx), Ctx));
+ MO.getMBB()->getSymbol(), Ctx));
break;
case MachineOperand::MO_GlobalAddress:
MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
@@ -294,6 +298,29 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
LowerSubReg32_Op0(OutMI, X86::MOV32r0); // MOV64r0 -> MOV32r0
LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); // MOV32r0 -> XOR32rr
break;
+
+
+ // The assembler backend wants to see branches in their small form and relax
+ // them to their large form. The JIT can only handle the large form because
+ // it does not do relaxation. For now, translate the large form to the
+ // small one here.
+ case X86::JMP_4: OutMI.setOpcode(X86::JMP_1); break;
+ case X86::JO_4: OutMI.setOpcode(X86::JO_1); break;
+ case X86::JNO_4: OutMI.setOpcode(X86::JNO_1); break;
+ case X86::JB_4: OutMI.setOpcode(X86::JB_1); break;
+ case X86::JAE_4: OutMI.setOpcode(X86::JAE_1); break;
+ case X86::JE_4: OutMI.setOpcode(X86::JE_1); break;
+ case X86::JNE_4: OutMI.setOpcode(X86::JNE_1); break;
+ case X86::JBE_4: OutMI.setOpcode(X86::JBE_1); break;
+ case X86::JA_4: OutMI.setOpcode(X86::JA_1); break;
+ case X86::JS_4: OutMI.setOpcode(X86::JS_1); break;
+ case X86::JNS_4: OutMI.setOpcode(X86::JNS_1); break;
+ case X86::JP_4: OutMI.setOpcode(X86::JP_1); break;
+ case X86::JNP_4: OutMI.setOpcode(X86::JNP_1); break;
+ case X86::JL_4: OutMI.setOpcode(X86::JL_1); break;
+ case X86::JGE_4: OutMI.setOpcode(X86::JGE_1); break;
+ case X86::JLE_4: OutMI.setOpcode(X86::JLE_1); break;
+ case X86::JG_4: OutMI.setOpcode(X86::JG_1); break;
}
}
@@ -344,6 +371,13 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
} else
printOperand(MI, 0);
} else {
+ if (MI->getOperand(0).getType()==MachineOperand::MO_Register &&
+ MI->getOperand(0).getReg()==0) {
+ // Suppress offset in this case, it is not meaningful.
+ O << "undef";
+ OutStreamer.AddBlankLine();
+ return;
+ }
// Frame address. Currently handles register +- offset only.
assert(MI->getOperand(0).getType()==MachineOperand::MO_Register);
assert(MI->getOperand(3).getType()==MachineOperand::MO_Immediate);
@@ -392,11 +426,8 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
// For this, we want to print something like:
// MYGLOBAL + (. - PICBASE)
// However, we can't generate a ".", so just emit a new label here and refer
- // to it. We know that this operand flag occurs at most once per function.
- const char *Prefix = MAI->getPrivateGlobalPrefix();
- MCSymbol *DotSym = OutContext.GetOrCreateTemporarySymbol(Twine(Prefix)+
- "picbaseref" +
- Twine(getFunctionNumber()));
+ // to it.
+ MCSymbol *DotSym = OutContext.GetOrCreateTemporarySymbol();
OutStreamer.EmitLabel(DotSym);
// Now that we have emitted the label, lower the complex operand expression.
diff --git a/lib/Target/X86/CMakeLists.txt b/lib/Target/X86/CMakeLists.txt
index eed3b45..4d3dedf 100644
--- a/lib/Target/X86/CMakeLists.txt
+++ b/lib/Target/X86/CMakeLists.txt
@@ -27,7 +27,6 @@ set(sources
X86JITInfo.cpp
X86MCAsmInfo.cpp
X86MCCodeEmitter.cpp
- X86MCTargetExpr.cpp
X86RegisterInfo.cpp
X86Subtarget.cpp
X86TargetMachine.cpp
diff --git a/lib/Target/X86/Disassembler/Makefile b/lib/Target/X86/Disassembler/Makefile
index b289647..8669fd8 100644
--- a/lib/Target/X86/Disassembler/Makefile
+++ b/lib/Target/X86/Disassembler/Makefile
@@ -11,6 +11,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMX86Disassembler
# Hack: we need to include 'main' x86 target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/X86/TargetInfo/Makefile b/lib/Target/X86/TargetInfo/Makefile
index 9858e6a..ee91982 100644
--- a/lib/Target/X86/TargetInfo/Makefile
+++ b/lib/Target/X86/TargetInfo/Makefile
@@ -11,6 +11,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMX86Info
# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
index ba0ee6c..c753cf2 100644
--- a/lib/Target/X86/X86.h
+++ b/lib/Target/X86/X86.h
@@ -21,7 +21,6 @@ namespace llvm {
class FunctionPass;
class JITCodeEmitter;
-class MCAssembler;
class MCCodeEmitter;
class MCContext;
class MachineCodeEmitter;
@@ -57,8 +56,8 @@ MCCodeEmitter *createX86_32MCCodeEmitter(const Target &, TargetMachine &TM,
MCCodeEmitter *createX86_64MCCodeEmitter(const Target &, TargetMachine &TM,
MCContext &Ctx);
-TargetAsmBackend *createX86_32AsmBackend(const Target &, MCAssembler &);
-TargetAsmBackend *createX86_64AsmBackend(const Target &, MCAssembler &);
+TargetAsmBackend *createX86_32AsmBackend(const Target &, const std::string &);
+TargetAsmBackend *createX86_64AsmBackend(const Target &, const std::string &);
/// createX86EmitCodeToMemory - Returns a pass that converts a register
/// allocated function into raw machine code in a dynamically
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
index 7919559..6a4bdb5 100644
--- a/lib/Target/X86/X86.td
+++ b/lib/Target/X86/X86.td
@@ -55,7 +55,8 @@ def Feature3DNowA : SubtargetFeature<"3dnowa", "X863DNowLevel", "ThreeDNowA",
// feature, because SSE2 can be disabled (e.g. for compiling OS kernels)
// without disabling 64-bit mode.
def Feature64Bit : SubtargetFeature<"64bit", "HasX86_64", "true",
- "Support 64-bit instructions">;
+ "Support 64-bit instructions",
+ [FeatureCMOV]>;
def FeatureSlowBTMem : SubtargetFeature<"slow-bt-mem", "IsBTMemSlow", "true",
"Bit testing of memory is slow">;
def FeatureSSE4A : SubtargetFeature<"sse4a", "HasSSE4A", "true",
diff --git a/lib/Target/X86/X86AsmBackend.cpp b/lib/Target/X86/X86AsmBackend.cpp
index e6654ef..a44afc6 100644
--- a/lib/Target/X86/X86AsmBackend.cpp
+++ b/lib/Target/X86/X86AsmBackend.cpp
@@ -9,6 +9,7 @@
#include "llvm/Target/TargetAsmBackend.h"
#include "X86.h"
+#include "llvm/MC/MCSectionMachO.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmBackend.h"
using namespace llvm;
@@ -17,18 +18,63 @@ namespace {
class X86AsmBackend : public TargetAsmBackend {
public:
- X86AsmBackend(const Target &T, MCAssembler &A)
+ X86AsmBackend(const Target &T)
: TargetAsmBackend(T) {}
};
+class DarwinX86AsmBackend : public X86AsmBackend {
+public:
+ DarwinX86AsmBackend(const Target &T)
+ : X86AsmBackend(T) {}
+
+ virtual bool hasAbsolutizedSet() const { return true; }
+
+ virtual bool hasScatteredSymbols() const { return true; }
+};
+
+class DarwinX86_32AsmBackend : public DarwinX86AsmBackend {
+public:
+ DarwinX86_32AsmBackend(const Target &T)
+ : DarwinX86AsmBackend(T) {}
+};
+
+class DarwinX86_64AsmBackend : public DarwinX86AsmBackend {
+public:
+ DarwinX86_64AsmBackend(const Target &T)
+ : DarwinX86AsmBackend(T) {}
+
+ virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
+ // Temporary labels in the string literals sections require symbols. The
+ // issue is that the x86_64 relocation format does not allow symbol +
+ // offset, and so the linker does not have enough information to resolve the
+ // access to the appropriate atom unless an external relocation is used. For
+ // non-cstring sections, we expect the compiler to use a non-temporary label
+ // for anything that could have an addend pointing outside the symbol.
+ //
+ // See <rdar://problem/4765733>.
+ const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
+ return SMO.getType() == MCSectionMachO::S_CSTRING_LITERALS;
+ }
+};
+
}
TargetAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
- MCAssembler &A) {
- return new X86AsmBackend(T, A);
+ const std::string &TT) {
+ switch (Triple(TT).getOS()) {
+ case Triple::Darwin:
+ return new DarwinX86_32AsmBackend(T);
+ default:
+ return new X86AsmBackend(T);
+ }
}
TargetAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
- MCAssembler &A) {
- return new X86AsmBackend(T, A);
+ const std::string &TT) {
+ switch (Triple(TT).getOS()) {
+ case Triple::Darwin:
+ return new DarwinX86_64AsmBackend(T);
+ default:
+ return new X86AsmBackend(T);
+ }
}
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.cpp b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
index ab67acb..4326814 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.cpp
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
@@ -12,80 +12,9 @@
//===----------------------------------------------------------------------===//
#include "X86COFFMachineModuleInfo.h"
-#include "X86MachineFunctionInfo.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-X86COFFMachineModuleInfo::X86COFFMachineModuleInfo(const MachineModuleInfo &) {
-}
-X86COFFMachineModuleInfo::~X86COFFMachineModuleInfo() {
-}
-
-void X86COFFMachineModuleInfo::addExternalFunction(const StringRef& Name) {
- CygMingStubs.insert(Name);
-}
-
-/// DecorateCygMingName - Apply various name decorations if the function uses
-/// stdcall or fastcall calling convention.
-void X86COFFMachineModuleInfo::DecorateCygMingName(SmallVectorImpl<char> &Name,
- const GlobalValue *GV,
- const TargetData &TD) {
- const Function *F = dyn_cast<Function>(GV);
- if (!F) return;
-
- // We don't want to decorate non-stdcall or non-fastcall functions right now
- CallingConv::ID CC = F->getCallingConv();
- if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
- return;
-
- unsigned ArgWords = 0;
- DenseMap<const Function*, unsigned>::const_iterator item = FnArgWords.find(F);
- if (item == FnArgWords.end()) {
- // Calculate arguments sizes
- for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
- AI != AE; ++AI) {
- const Type* Ty = AI->getType();
- // 'Dereference' type in case of byval parameter attribute
- if (AI->hasByValAttr())
- Ty = cast<PointerType>(Ty)->getElementType();
-
- // Size should be aligned to DWORD boundary
- ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
- }
-
- FnArgWords[F] = ArgWords;
- } else
- ArgWords = item->second;
-
- const FunctionType *FT = F->getFunctionType();
- // "Pure" variadic functions do not receive @0 suffix.
- if (!FT->isVarArg() || FT->getNumParams() == 0 ||
- (FT->getNumParams() == 1 && F->hasStructRetAttr()))
- raw_svector_ostream(Name) << '@' << ArgWords;
-
- if (CC == CallingConv::X86_FastCall) {
- if (Name[0] == '_')
- Name[0] = '@';
- else
- Name.insert(Name.begin(), '@');
- }
+X86COFFMachineModuleInfo::~X86COFFMachineModuleInfo() {
}
-/// DecorateCygMingName - Query FunctionInfoMap and use this information for
-/// various name decorations for Cygwin and MingW.
-void X86COFFMachineModuleInfo::DecorateCygMingName(MCSymbol *&Name,
- MCContext &Ctx,
- const GlobalValue *GV,
- const TargetData &TD) {
- SmallString<128> NameStr(Name->getName().begin(), Name->getName().end());
- DecorateCygMingName(NameStr, GV, TD);
-
- Name = Ctx.GetOrCreateSymbol(NameStr.str());
-}
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.h b/lib/Target/X86/X86COFFMachineModuleInfo.h
index 9de3dcd..eece462 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.h
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.h
@@ -26,17 +26,14 @@ namespace llvm {
/// for X86 COFF targets.
class X86COFFMachineModuleInfo : public MachineModuleInfoImpl {
StringSet<> CygMingStubs;
- DenseMap<const Function*, unsigned> FnArgWords;
public:
- X86COFFMachineModuleInfo(const MachineModuleInfo &);
- ~X86COFFMachineModuleInfo();
+ X86COFFMachineModuleInfo(const MachineModuleInfo &) {}
+ virtual ~X86COFFMachineModuleInfo();
- void DecorateCygMingName(MCSymbol* &Name, MCContext &Ctx,
- const GlobalValue *GV, const TargetData &TD);
- void DecorateCygMingName(SmallVectorImpl<char> &Name, const GlobalValue *GV,
- const TargetData &TD);
-
- void addExternalFunction(const StringRef& Name);
+ void addExternalFunction(StringRef Name) {
+ CygMingStubs.insert(Name);
+ }
+
typedef StringSet<>::const_iterator stub_iterator;
stub_iterator stub_begin() const { return CygMingStubs.begin(); }
stub_iterator stub_end() const { return CygMingStubs.end(); }
diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td
index 12d3d04..fd15efd 100644
--- a/lib/Target/X86/X86CallingConv.td
+++ b/lib/Target/X86/X86CallingConv.td
@@ -221,6 +221,20 @@ def CC_X86_Win64_C : CallingConv<[
CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToStack<8, 8>>
]>;
+def CC_X86_64_GHC : CallingConv<[
+ // Promote i8/i16/i32 arguments to i64.
+ CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,
+
+ // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, R6, SpLim
+ CCIfType<[i64],
+ CCAssignToReg<[R13, RBP, R12, RBX, R14, RSI, RDI, R8, R9, R15]>>,
+
+ // Pass in STG registers: F1, F2, F3, F4, D1, D2
+ CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
+ CCIfSubtarget<"hasSSE1()",
+ CCAssignToReg<[XMM1, XMM2, XMM3, XMM4, XMM5, XMM6]>>>
+]>;
+
//===----------------------------------------------------------------------===//
// X86 C Calling Convention
//===----------------------------------------------------------------------===//
@@ -320,3 +334,11 @@ def CC_X86_32_FastCC : CallingConv<[
// Otherwise, same as everything else.
CCDelegateTo<CC_X86_32_Common>
]>;
+
+def CC_X86_32_GHC : CallingConv<[
+ // Promote i8/i16 arguments to i32.
+ CCIfType<[i8, i16], CCPromoteToType<i32>>,
+
+ // Pass in STG registers: Base, Sp, Hp, R1
+ CCIfType<[i32], CCAssignToReg<[EBX, EBP, EDI, ESI]>>
+]>;
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index 8deadf6..6638e11 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -46,6 +46,7 @@ namespace {
const TargetData *TD;
X86TargetMachine &TM;
CodeEmitter &MCE;
+ MachineModuleInfo *MMI;
intptr_t PICBaseOffset;
bool Is64BitMode;
bool IsPIC;
@@ -115,8 +116,8 @@ FunctionPass *llvm::createX86JITCodeEmitterPass(X86TargetMachine &TM,
template<class CodeEmitter>
bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
-
- MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
+ MMI = &getAnalysis<MachineModuleInfo>();
+ MCE.setModuleInfo(MMI);
II = TM.getInstrInfo();
TD = TM.getTargetData();
@@ -602,10 +603,11 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI,
llvm_report_error("JIT does not support inline asm!");
break;
case TargetOpcode::DBG_LABEL:
- case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
- MCE.emitLabel(MI.getOperand(0).getImm());
+ case TargetOpcode::EH_LABEL:
+ MCE.emitLabel(MI.getOperand(0).getMCSymbol());
break;
+
case TargetOpcode::IMPLICIT_DEF:
case TargetOpcode::KILL:
case X86::FP_REG_KILL:
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 98e3f4e..96b652d 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -172,7 +172,9 @@ bool X86FastISel::isTypeLegal(const Type *Ty, EVT &VT, bool AllowI1) {
CCAssignFn *X86FastISel::CCAssignFnForCall(CallingConv::ID CC,
bool isTaillCall) {
if (Subtarget->is64Bit()) {
- if (Subtarget->isTargetWin64())
+ if (CC == CallingConv::GHC)
+ return CC_X86_64_GHC;
+ else if (Subtarget->isTargetWin64())
return CC_X86_Win64_C;
else
return CC_X86_64_C;
@@ -182,6 +184,8 @@ CCAssignFn *X86FastISel::CCAssignFnForCall(CallingConv::ID CC,
return CC_X86_32_FastCall;
else if (CC == CallingConv::Fast)
return CC_X86_32_FastCC;
+ else if (CC == CallingConv::GHC)
+ return CC_X86_32_GHC;
else
return CC_X86_32_C;
}
@@ -1162,6 +1166,30 @@ bool X86FastISel::X86VisitIntrinsicCall(IntrinsicInst &I) {
// FIXME: Handle more intrinsics.
switch (I.getIntrinsicID()) {
default: return false;
+ case Intrinsic::objectsize: {
+ ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(2));
+ const Type *Ty = I.getCalledFunction()->getReturnType();
+
+ assert(CI && "Non-constant type in Intrinsic::objectsize?");
+
+ EVT VT;
+ if (!isTypeLegal(Ty, VT))
+ return false;
+
+ unsigned OpC = 0;
+ if (VT == MVT::i32)
+ OpC = X86::MOV32ri;
+ else if (VT == MVT::i64)
+ OpC = X86::MOV64ri;
+ else
+ return false;
+
+ unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
+ BuildMI(MBB, DL, TII.get(OpC), ResultReg).
+ addImm(CI->getZExtValue() == 0 ? -1ULL : 0);
+ UpdateValueMap(&I, ResultReg);
+ return true;
+ }
case Intrinsic::dbg_declare: {
DbgDeclareInst *DI = cast<DbgDeclareInst>(&I);
X86AddressMode AM;
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 3fad8ad..4058885 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -349,17 +349,17 @@ X86DAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const {
return true;
}
-/// MoveBelowCallSeqStart - Replace CALLSEQ_START operand with load's chain
-/// operand and move load below the call's chain operand.
-static void MoveBelowCallSeqStart(SelectionDAG *CurDAG, SDValue Load,
- SDValue Call, SDValue CallSeqStart) {
+/// MoveBelowCallOrigChain - Replace the original chain operand of the call with
+/// load's chain operand and move load below the call's chain operand.
+static void MoveBelowOrigChain(SelectionDAG *CurDAG, SDValue Load,
+ SDValue Call, SDValue OrigChain) {
SmallVector<SDValue, 8> Ops;
- SDValue Chain = CallSeqStart.getOperand(0);
+ SDValue Chain = OrigChain.getOperand(0);
if (Chain.getNode() == Load.getNode())
Ops.push_back(Load.getOperand(0));
else {
assert(Chain.getOpcode() == ISD::TokenFactor &&
- "Unexpected CallSeqStart chain operand");
+ "Unexpected chain operand");
for (unsigned i = 0, e = Chain.getNumOperands(); i != e; ++i)
if (Chain.getOperand(i).getNode() == Load.getNode())
Ops.push_back(Load.getOperand(0));
@@ -371,9 +371,9 @@ static void MoveBelowCallSeqStart(SelectionDAG *CurDAG, SDValue Load,
Ops.clear();
Ops.push_back(NewChain);
}
- for (unsigned i = 1, e = CallSeqStart.getNumOperands(); i != e; ++i)
- Ops.push_back(CallSeqStart.getOperand(i));
- CurDAG->UpdateNodeOperands(CallSeqStart, &Ops[0], Ops.size());
+ for (unsigned i = 1, e = OrigChain.getNumOperands(); i != e; ++i)
+ Ops.push_back(OrigChain.getOperand(i));
+ CurDAG->UpdateNodeOperands(OrigChain, &Ops[0], Ops.size());
CurDAG->UpdateNodeOperands(Load, Call.getOperand(0),
Load.getOperand(1), Load.getOperand(2));
Ops.clear();
@@ -386,7 +386,9 @@ static void MoveBelowCallSeqStart(SelectionDAG *CurDAG, SDValue Load,
/// isCalleeLoad - Return true if call address is a load and it can be
/// moved below CALLSEQ_START and the chains leading up to the call.
/// Return the CALLSEQ_START by reference as a second output.
-static bool isCalleeLoad(SDValue Callee, SDValue &Chain) {
+/// In the case of a tail call, there isn't a callseq node between the call
+/// chain and the load.
+static bool isCalleeLoad(SDValue Callee, SDValue &Chain, bool HasCallSeq) {
if (Callee.getNode() == Chain.getNode() || !Callee.hasOneUse())
return false;
LoadSDNode *LD = dyn_cast<LoadSDNode>(Callee.getNode());
@@ -397,12 +399,14 @@ static bool isCalleeLoad(SDValue Callee, SDValue &Chain) {
return false;
// Now let's find the callseq_start.
- while (Chain.getOpcode() != ISD::CALLSEQ_START) {
+ while (HasCallSeq && Chain.getOpcode() != ISD::CALLSEQ_START) {
if (!Chain.hasOneUse())
return false;
Chain = Chain.getOperand(0);
}
-
+
+ if (!Chain.getNumOperands())
+ return false;
if (Chain.getOperand(0).getNode() == Callee.getNode())
return true;
if (Chain.getOperand(0).getOpcode() == ISD::TokenFactor &&
@@ -420,7 +424,9 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
E = CurDAG->allnodes_end(); I != E; ) {
SDNode *N = I++; // Preincrement iterator to avoid invalidation issues.
- if (OptLevel != CodeGenOpt::None && N->getOpcode() == X86ISD::CALL) {
+ if (OptLevel != CodeGenOpt::None &&
+ (N->getOpcode() == X86ISD::CALL ||
+ N->getOpcode() == X86ISD::TC_RETURN)) {
/// Also try moving call address load from outside callseq_start to just
/// before the call to allow it to be folded.
///
@@ -440,11 +446,12 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
/// \ /
/// \ /
/// [CALL]
+ bool HasCallSeq = N->getOpcode() == X86ISD::CALL;
SDValue Chain = N->getOperand(0);
SDValue Load = N->getOperand(1);
- if (!isCalleeLoad(Load, Chain))
+ if (!isCalleeLoad(Load, Chain, HasCallSeq))
continue;
- MoveBelowCallSeqStart(CurDAG, Load, SDValue(N, 0), Chain);
+ MoveBelowOrigChain(CurDAG, Load, SDValue(N, 0), Chain);
++NumLoadMoved;
continue;
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 0cfcbb6..7d2140b 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -16,7 +16,6 @@
#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86ISelLowering.h"
-#include "X86MCTargetExpr.h"
#include "X86TargetMachine.h"
#include "X86TargetObjectFile.h"
#include "llvm/CallingConv.h"
@@ -37,6 +36,7 @@
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallSet.h"
@@ -45,10 +45,12 @@
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+using namespace dwarf;
STATISTIC(NumTailCalls, "Number of tail calls");
@@ -988,6 +990,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
// We have target-specific dag combine patterns for the following nodes:
setTargetDAGCombine(ISD::VECTOR_SHUFFLE);
+ setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT);
setTargetDAGCombine(ISD::BUILD_VECTOR);
setTargetDAGCombine(ISD::SELECT);
setTargetDAGCombine(ISD::SHL);
@@ -1118,8 +1121,8 @@ X86TargetLowering::LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
Subtarget->isPICStyleGOT());
// In 32-bit ELF systems, our jump table entries are formed with @GOTOFF
// entries.
- return X86MCTargetExpr::Create(MBB->getSymbol(Ctx),
- X86MCTargetExpr::GOTOFF, Ctx);
+ return MCSymbolRefExpr::Create(MBB->getSymbol(),
+ MCSymbolRefExpr::VK_GOTOFF, Ctx);
}
/// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
@@ -1378,6 +1381,8 @@ bool X86TargetLowering::IsCalleePop(bool IsVarArg, CallingConv::ID CallingConv){
return !Subtarget->is64Bit();
case CallingConv::Fast:
return GuaranteedTailCallOpt;
+ case CallingConv::GHC:
+ return GuaranteedTailCallOpt;
}
}
@@ -1385,7 +1390,9 @@ bool X86TargetLowering::IsCalleePop(bool IsVarArg, CallingConv::ID CallingConv){
/// given CallingConvention value.
CCAssignFn *X86TargetLowering::CCAssignFnForNode(CallingConv::ID CC) const {
if (Subtarget->is64Bit()) {
- if (Subtarget->isTargetWin64())
+ if (CC == CallingConv::GHC)
+ return CC_X86_64_GHC;
+ else if (Subtarget->isTargetWin64())
return CC_X86_Win64_C;
else
return CC_X86_64_C;
@@ -1395,6 +1402,8 @@ CCAssignFn *X86TargetLowering::CCAssignFnForNode(CallingConv::ID CC) const {
return CC_X86_32_FastCall;
else if (CC == CallingConv::Fast)
return CC_X86_32_FastCC;
+ else if (CC == CallingConv::GHC)
+ return CC_X86_32_GHC;
else
return CC_X86_32_C;
}
@@ -1412,10 +1421,16 @@ CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain,
/*AlwaysInline=*/true, NULL, 0, NULL, 0);
}
+/// IsTailCallConvention - Return true if the calling convention is one that
+/// supports tail call optimization.
+static bool IsTailCallConvention(CallingConv::ID CC) {
+ return (CC == CallingConv::Fast || CC == CallingConv::GHC);
+}
+
/// FuncIsMadeTailCallSafe - Return true if the function is being made into
/// a tailcall target by changing its ABI.
static bool FuncIsMadeTailCallSafe(CallingConv::ID CC) {
- return GuaranteedTailCallOpt && CC == CallingConv::Fast;
+ return GuaranteedTailCallOpt && IsTailCallConvention(CC);
}
SDValue
@@ -1465,7 +1480,6 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
DebugLoc dl,
SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) {
-
MachineFunction &MF = DAG.getMachineFunction();
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
@@ -1479,8 +1493,8 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
bool Is64Bit = Subtarget->is64Bit();
bool IsWin64 = Subtarget->isTargetWin64();
- assert(!(isVarArg && CallConv == CallingConv::Fast) &&
- "Var args not supported with calling convention fastcc");
+ assert(!(isVarArg && IsTailCallConvention(CallConv)) &&
+ "Var args not supported with calling convention fastcc or ghc");
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -1683,7 +1697,7 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
} else {
BytesToPopOnReturn = 0; // Callee pops nothing.
// If this is an sret function, the return should pop the hidden pointer.
- if (!Is64Bit && CallConv != CallingConv::Fast && ArgsAreStructReturn(Ins))
+ if (!Is64Bit && !IsTailCallConvention(CallConv) && ArgsAreStructReturn(Ins))
BytesToPopOnReturn = 4;
}
@@ -1767,7 +1781,8 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (isTailCall) {
// Check if it's really possible to do a tail call.
- isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv, isVarArg,
+ isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
+ isVarArg, IsStructRet, MF.getFunction()->hasStructRetAttr(),
Outs, Ins, DAG);
// Sibcalls are automatically detected tailcalls which do not require
@@ -1779,8 +1794,8 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
++NumTailCalls;
}
- assert(!(isVarArg && CallConv == CallingConv::Fast) &&
- "Var args not supported with calling convention fastcc");
+ assert(!(isVarArg && IsTailCallConvention(CallConv)) &&
+ "Var args not supported with calling convention fastcc or ghc");
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -1794,7 +1809,7 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// This is a sibcall. The memory operands are available in caller's
// own caller's stack.
NumBytes = 0;
- else if (GuaranteedTailCallOpt && CallConv == CallingConv::Fast)
+ else if (GuaranteedTailCallOpt && IsTailCallConvention(CallConv))
NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
int FPDiff = 0;
@@ -2074,18 +2089,6 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
OpFlags);
}
- if (isTailCall && !WasGlobalOrExternal) {
- // Force the address into a (call preserved) caller-saved register since
- // tailcall must happen after callee-saved registers are poped.
- // FIXME: Give it a special register class that contains caller-saved
- // register instead?
- unsigned TCReg = Is64Bit ? X86::R11 : X86::EAX;
- Chain = DAG.getCopyToReg(Chain, dl,
- DAG.getRegister(TCReg, getPointerTy()),
- Callee,InFlag);
- Callee = DAG.getRegister(TCReg, getPointerTy());
- }
-
// Returns a chain & a flag for retval copy to use.
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
SmallVector<SDValue, 8> Ops;
@@ -2131,14 +2134,6 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (RVLocs[i].isRegLoc())
MF.getRegInfo().addLiveOut(RVLocs[i].getLocReg());
}
-
- assert(((Callee.getOpcode() == ISD::Register &&
- (cast<RegisterSDNode>(Callee)->getReg() == X86::EAX ||
- cast<RegisterSDNode>(Callee)->getReg() == X86::R11)) ||
- Callee.getOpcode() == ISD::TargetExternalSymbol ||
- Callee.getOpcode() == ISD::TargetGlobalAddress) &&
- "Expecting a global address, external symbol, or scratch register");
-
return DAG.getNode(X86ISD::TC_RETURN, dl,
NodeTys, &Ops[0], Ops.size());
}
@@ -2150,7 +2145,7 @@ X86TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
unsigned NumBytesForCalleeToPush;
if (IsCalleePop(isVarArg, CallConv))
NumBytesForCalleeToPush = NumBytes; // Callee pops everything
- else if (!Is64Bit && CallConv != CallingConv::Fast && IsStructRet)
+ else if (!Is64Bit && !IsTailCallConvention(CallConv) && IsStructRet)
// If this is a call to a struct-return function, the callee
// pops the hidden struct pointer, so we have to push it back.
// This is common for Darwin/X86, Linux & Mingw32 targets.
@@ -2285,17 +2280,19 @@ bool
X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
CallingConv::ID CalleeCC,
bool isVarArg,
+ bool isCalleeStructRet,
+ bool isCallerStructRet,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
SelectionDAG& DAG) const {
- if (CalleeCC != CallingConv::Fast &&
+ if (!IsTailCallConvention(CalleeCC) &&
CalleeCC != CallingConv::C)
return false;
// If -tailcallopt is specified, make fastcc functions tail-callable.
const Function *CallerF = DAG.getMachineFunction().getFunction();
if (GuaranteedTailCallOpt) {
- if (CalleeCC == CallingConv::Fast &&
+ if (IsTailCallConvention(CalleeCC) &&
CallerF->getCallingConv() == CalleeCC)
return true;
return false;
@@ -2304,10 +2301,15 @@ X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Callee,
// Look for obvious safe cases to perform tail call optimization that does not
// requite ABI changes. This is what gcc calls sibcall.
- // Do not tail call optimize vararg calls for now.
+ // Do not sibcall optimize vararg calls for now.
if (isVarArg)
return false;
+ // Also avoid sibcall optimization if either caller or callee uses struct
+ // return semantics.
+ if (isCalleeStructRet || isCallerStructRet)
+ return false;
+
// If the callee takes no arguments then go on to check the results of the
// call.
if (!Outs.empty()) {
@@ -6158,7 +6160,7 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
N2C && N2C->isNullValue() &&
RHSC && RHSC->isNullValue()) {
SDValue CmpOp0 = Cmp.getOperand(0);
- Cmp = DAG.getNode(X86ISD::CMP, dl, CmpOp0.getValueType(),
+ Cmp = DAG.getNode(X86ISD::CMP, dl, MVT::i32,
CmpOp0, DAG.getConstant(1, CmpOp0.getValueType()));
return DAG.getNode(X86ISD::SETCC_CARRY, dl, Op.getValueType(),
DAG.getConstant(X86::COND_B, MVT::i8), Cmp);
@@ -8439,6 +8441,11 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
case X86::CMOV_V4F32:
case X86::CMOV_V2F64:
case X86::CMOV_V2I64:
+ case X86::CMOV_GR16:
+ case X86::CMOV_GR32:
+ case X86::CMOV_RFP32:
+ case X86::CMOV_RFP64:
+ case X86::CMOV_RFP80:
return EmitLoweredSelect(MI, BB, EM);
case X86::FP32_TO_INT16_IN_MEM:
@@ -8521,6 +8528,21 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
return BB;
}
+ // DBG_VALUE. Only the frame index case is done here.
+ case X86::DBG_VALUE: {
+ const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+ DebugLoc DL = MI->getDebugLoc();
+ X86AddressMode AM;
+ MachineFunction *F = BB->getParent();
+ AM.BaseType = X86AddressMode::FrameIndexBase;
+ AM.Base.FrameIndex = MI->getOperand(0).getImm();
+ addFullAddress(BuildMI(BB, DL, TII->get(X86::DBG_VALUE)), AM).
+ addImm(MI->getOperand(1).getImm()).
+ addMetadata(MI->getOperand(2).getMetadata());
+ F->DeleteMachineInstr(MI); // Remove pseudo.
+ return BB;
+ }
+
// String/text processing lowering.
case X86::PCMPISTRM128REG:
return EmitPCMP(MI, BB, 3, false /* in-mem */);
@@ -8832,6 +8854,87 @@ static SDValue PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
+/// PerformShuffleCombine - Detect vector gather/scatter index generation
+/// and convert it from being a bunch of shuffles and extracts to a simple
+/// store and scalar loads to extract the elements.
+static SDValue PerformEXTRACT_VECTOR_ELTCombine(SDNode *N, SelectionDAG &DAG,
+ const TargetLowering &TLI) {
+ SDValue InputVector = N->getOperand(0);
+
+ // Only operate on vectors of 4 elements, where the alternative shuffling
+ // gets to be more expensive.
+ if (InputVector.getValueType() != MVT::v4i32)
+ return SDValue();
+
+ // Check whether every use of InputVector is an EXTRACT_VECTOR_ELT with a
+ // single use which is a sign-extend or zero-extend, and all elements are
+ // used.
+ SmallVector<SDNode *, 4> Uses;
+ unsigned ExtractedElements = 0;
+ for (SDNode::use_iterator UI = InputVector.getNode()->use_begin(),
+ UE = InputVector.getNode()->use_end(); UI != UE; ++UI) {
+ if (UI.getUse().getResNo() != InputVector.getResNo())
+ return SDValue();
+
+ SDNode *Extract = *UI;
+ if (Extract->getOpcode() != ISD::EXTRACT_VECTOR_ELT)
+ return SDValue();
+
+ if (Extract->getValueType(0) != MVT::i32)
+ return SDValue();
+ if (!Extract->hasOneUse())
+ return SDValue();
+ if (Extract->use_begin()->getOpcode() != ISD::SIGN_EXTEND &&
+ Extract->use_begin()->getOpcode() != ISD::ZERO_EXTEND)
+ return SDValue();
+ if (!isa<ConstantSDNode>(Extract->getOperand(1)))
+ return SDValue();
+
+ // Record which element was extracted.
+ ExtractedElements |=
+ 1 << cast<ConstantSDNode>(Extract->getOperand(1))->getZExtValue();
+
+ Uses.push_back(Extract);
+ }
+
+ // If not all the elements were used, this may not be worthwhile.
+ if (ExtractedElements != 15)
+ return SDValue();
+
+ // Ok, we've now decided to do the transformation.
+ DebugLoc dl = InputVector.getDebugLoc();
+
+ // Store the value to a temporary stack slot.
+ SDValue StackPtr = DAG.CreateStackTemporary(InputVector.getValueType());
+ SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, InputVector, StackPtr, NULL, 0,
+ false, false, 0);
+
+ // Replace each use (extract) with a load of the appropriate element.
+ for (SmallVectorImpl<SDNode *>::iterator UI = Uses.begin(),
+ UE = Uses.end(); UI != UE; ++UI) {
+ SDNode *Extract = *UI;
+
+ // Compute the element's address.
+ SDValue Idx = Extract->getOperand(1);
+ unsigned EltSize =
+ InputVector.getValueType().getVectorElementType().getSizeInBits()/8;
+ uint64_t Offset = EltSize * cast<ConstantSDNode>(Idx)->getZExtValue();
+ SDValue OffsetVal = DAG.getConstant(Offset, TLI.getPointerTy());
+
+ SDValue ScalarAddr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), OffsetVal, StackPtr);
+
+ // Load the scalar.
+ SDValue LoadScalar = DAG.getLoad(Extract->getValueType(0), dl, Ch, ScalarAddr,
+ NULL, 0, false, false, 0);
+
+ // Replace the exact with the load.
+ DAG.ReplaceAllUsesOfValueWith(SDValue(Extract, 0), LoadScalar);
+ }
+
+ // The replacement was made in place; don't return anything.
+ return SDValue();
+}
+
/// PerformSELECTCombine - Do target-specific dag combines on SELECT nodes.
static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
const X86Subtarget *Subtarget) {
@@ -9721,6 +9824,8 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
switch (N->getOpcode()) {
default: break;
case ISD::VECTOR_SHUFFLE: return PerformShuffleCombine(N, DAG, *this);
+ case ISD::EXTRACT_VECTOR_ELT:
+ return PerformEXTRACT_VECTOR_ELTCombine(N, DAG, *this);
case ISD::SELECT: return PerformSELECTCombine(N, DAG, Subtarget);
case X86ISD::CMOV: return PerformCMOVCombine(N, DAG, DCI);
case ISD::MUL: return PerformMulCombine(N, DAG, DCI);
@@ -9810,7 +9915,8 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
AsmPieces[2] == "${0:w}" &&
IA->getConstraintString().compare(0, 5, "=r,0,") == 0) {
AsmPieces.clear();
- SplitString(IA->getConstraintString().substr(5), AsmPieces, ",");
+ const std::string &Constraints = IA->getConstraintString();
+ SplitString(StringRef(Constraints).substr(5), AsmPieces, ",");
std::sort(AsmPieces.begin(), AsmPieces.end());
if (AsmPieces.size() == 4 &&
AsmPieces[0] == "~{cc}" &&
@@ -10265,41 +10371,3 @@ X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
return Res;
}
-
-//===----------------------------------------------------------------------===//
-// X86 Widen vector type
-//===----------------------------------------------------------------------===//
-
-/// getWidenVectorType: given a vector type, returns the type to widen
-/// to (e.g., v7i8 to v8i8). If the vector type is legal, it returns itself.
-/// If there is no vector type that we want to widen to, returns MVT::Other
-/// When and where to widen is target dependent based on the cost of
-/// scalarizing vs using the wider vector type.
-
-EVT X86TargetLowering::getWidenVectorType(EVT VT) const {
- assert(VT.isVector());
- if (isTypeLegal(VT))
- return VT;
-
- // TODO: In computeRegisterProperty, we can compute the list of legal vector
- // type based on element type. This would speed up our search (though
- // it may not be worth it since the size of the list is relatively
- // small).
- EVT EltVT = VT.getVectorElementType();
- unsigned NElts = VT.getVectorNumElements();
-
- // On X86, it make sense to widen any vector wider than 1
- if (NElts <= 1)
- return MVT::Other;
-
- for (unsigned nVT = MVT::FIRST_VECTOR_VALUETYPE;
- nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
- EVT SVT = (MVT::SimpleValueType)nVT;
-
- if (isTypeLegal(SVT) &&
- SVT.getVectorElementType() == EltVT &&
- SVT.getVectorNumElements() > NElts)
- return SVT;
- }
- return MVT::Other;
-}
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 4c12fcc..0f15eba 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -564,13 +564,6 @@ namespace llvm {
(VT == MVT::f32 && X86ScalarSSEf32); // f32 is when SSE1
}
- /// getWidenVectorType: given a vector type, returns the type to widen
- /// to (e.g., v7i8 to v8i8). If the vector type is legal, it returns itself.
- /// If there is no vector type that we want to widen to, returns EVT::Other
- /// When and were to widen is target dependent based on the cost of
- /// scalarizing vs using the wider vector type.
- virtual EVT getWidenVectorType(EVT VT) const;
-
/// createFastISel - This method returns a target specific FastISel object,
/// or null if the target does not support "fast" ISel.
virtual FastISel *
@@ -637,6 +630,8 @@ namespace llvm {
bool IsEligibleForTailCallOptimization(SDValue Callee,
CallingConv::ID CalleeCC,
bool isVarArg,
+ bool isCalleeStructRet,
+ bool isCallerStructRet,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<ISD::InputArg> &Ins,
SelectionDAG& DAG) const;
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 8e684c9..4262c0ac 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -24,6 +24,7 @@ def i64i32imm : Operand<i64>;
// pc relative.
def i64i32imm_pcrel : Operand<i64> {
let PrintMethod = "print_pcrel_imm";
+ let ParserMatchClass = X86AbsMemAsmOperand;
}
@@ -32,17 +33,26 @@ def i64i8imm : Operand<i64> {
let ParserMatchClass = ImmSExt8AsmOperand;
}
+// Special i64mem for addresses of load folding tail calls. These are not
+// allowed to use callee-saved registers since they must be scheduled
+// after callee-saved register are popped.
+def i64mem_TC : Operand<i64> {
+ let PrintMethod = "printi64mem";
+ let MIOperandInfo = (ops GR64_TC, i8imm, GR64_TC, i32imm, i8imm);
+ let ParserMatchClass = X86MemAsmOperand;
+}
+
def lea64mem : Operand<i64> {
let PrintMethod = "printlea64mem";
let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm);
- let ParserMatchClass = X86MemAsmOperand;
+ let ParserMatchClass = X86NoSegMemAsmOperand;
}
def lea64_32mem : Operand<i32> {
let PrintMethod = "printlea64_32mem";
let AsmOperandLowerMethod = "lower_lea64_32mem";
let MIOperandInfo = (ops GR32, i8imm, GR32_NOSP, i32imm);
- let ParserMatchClass = X86MemAsmOperand;
+ let ParserMatchClass = X86NoSegMemAsmOperand;
}
//===----------------------------------------------------------------------===//
@@ -176,22 +186,31 @@ let isCall = 1 in
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
-def TCRETURNdi64 : I<0, Pseudo, (outs), (ins i64imm:$dst, i32imm:$offset,
- variable_ops),
- "#TC_RETURN $dst $offset",
- []>;
-
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
-def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64:$dst, i32imm:$offset,
- variable_ops),
- "#TC_RETURN $dst $offset",
- []>;
-
-
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
- def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64:$dst, variable_ops),
- "jmp{q}\t{*}$dst # TAILCALL",
- []>;
+ let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
+ FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
+ MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
+ XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
+ Uses = [RSP] in {
+ def TCRETURNdi64 : I<0, Pseudo, (outs),
+ (ins i64i32imm_pcrel:$dst, i32imm:$offset, variable_ops),
+ "#TC_RETURN $dst $offset", []>;
+ def TCRETURNri64 : I<0, Pseudo, (outs), (ins GR64_TC:$dst, i32imm:$offset,
+ variable_ops),
+ "#TC_RETURN $dst $offset", []>;
+ def TCRETURNmi64 : I<0, Pseudo, (outs),
+ (ins i64mem_TC:$dst, i32imm:$offset, variable_ops),
+ "#TC_RETURN $dst $offset", []>;
+
+ def TAILJMPd64 : Ii32PCRel<0xE9, RawFrm, (outs),
+ (ins i64i32imm_pcrel:$dst, variable_ops),
+ "jmp\t$dst # TAILCALL", []>;
+ def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins GR64_TC:$dst, variable_ops),
+ "jmp{q}\t{*}$dst # TAILCALL", []>;
+
+ def TAILJMPm64 : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst, variable_ops),
+ "jmp{q}\t{*}$dst # TAILCALL", []>;
+}
// Branches
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
@@ -339,6 +358,22 @@ def MOV64mi32 : RIi32<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
"mov{q}\t{$src, $dst|$dst, $src}",
[(store i64immSExt32:$src, addr:$dst)]>;
+/// Versions of MOV64rr, MOV64rm, and MOV64mr for i64mem_TC and GR64_TC.
+let neverHasSideEffects = 1 in
+def MOV64rr_TC : RI<0x89, MRMDestReg, (outs GR64_TC:$dst), (ins GR64_TC:$src),
+ "mov{q}\t{$src, $dst|$dst, $src}", []>;
+
+let mayLoad = 1,
+ canFoldAsLoad = 1, isReMaterializable = 1 in
+def MOV64rm_TC : RI<0x8B, MRMSrcMem, (outs GR64_TC:$dst), (ins i64mem_TC:$src),
+ "mov{q}\t{$src, $dst|$dst, $src}",
+ []>;
+
+let mayStore = 1 in
+def MOV64mr_TC : RI<0x89, MRMDestMem, (outs), (ins i64mem_TC:$dst, GR64_TC:$src),
+ "mov{q}\t{$src, $dst|$dst, $src}",
+ []>;
+
def MOV64o8a : RIi8<0xA0, RawFrm, (outs), (ins offset8:$src),
"mov{q}\t{$src, %rax|%rax, $src}", []>;
def MOV64o64a : RIi32<0xA1, RawFrm, (outs), (ins offset64:$src),
@@ -463,8 +498,8 @@ let neverHasSideEffects = 1 in {
let Defs = [EFLAGS] in {
-def ADD64i32 : RI<0x05, RawFrm, (outs), (ins i32imm:$src),
- "add{q}\t{$src, %rax|%rax, $src}", []>;
+def ADD64i32 : RIi32<0x05, RawFrm, (outs), (ins i32imm:$src),
+ "add{q}\t{$src, %rax|%rax, $src}", []>;
let isTwoAddress = 1 in {
let isConvertibleToThreeAddress = 1 in {
@@ -520,8 +555,8 @@ def ADD64mi32 : RIi32<0x81, MRM0m, (outs), (ins i64mem:$dst, i64i32imm :$src2),
let Uses = [EFLAGS] in {
-def ADC64i32 : RI<0x15, RawFrm, (outs), (ins i32imm:$src),
- "adc{q}\t{$src, %rax|%rax, $src}", []>;
+def ADC64i32 : RIi32<0x15, RawFrm, (outs), (ins i32imm:$src),
+ "adc{q}\t{$src, %rax|%rax, $src}", []>;
let isTwoAddress = 1 in {
let isCommutable = 1 in
@@ -594,8 +629,8 @@ def SUB64ri32 : RIi32<0x81, MRM5r, (outs GR64:$dst),
(implicit EFLAGS)]>;
} // isTwoAddress
-def SUB64i32 : RI<0x2D, RawFrm, (outs), (ins i32imm:$src),
- "sub{q}\t{$src, %rax|%rax, $src}", []>;
+def SUB64i32 : RIi32<0x2D, RawFrm, (outs), (ins i32imm:$src),
+ "sub{q}\t{$src, %rax|%rax, $src}", []>;
// Memory-Register Subtraction
def SUB64mr : RI<0x29, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
@@ -641,8 +676,8 @@ def SBB64ri32 : RIi32<0x81, MRM3r, (outs GR64:$dst),
[(set GR64:$dst, (sube GR64:$src1, i64immSExt32:$src2))]>;
} // isTwoAddress
-def SBB64i32 : RI<0x1D, RawFrm, (outs), (ins i32imm:$src),
- "sbb{q}\t{$src, %rax|%rax, $src}", []>;
+def SBB64i32 : RIi32<0x1D, RawFrm, (outs), (ins i32imm:$src),
+ "sbb{q}\t{$src, %rax|%rax, $src}", []>;
def SBB64mr : RI<0x19, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
"sbb{q}\t{$src2, $dst|$dst, $src2}",
@@ -1047,8 +1082,8 @@ def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
[(store (not (loadi64 addr:$dst)), addr:$dst)]>;
let Defs = [EFLAGS] in {
-def AND64i32 : RI<0x25, RawFrm, (outs), (ins i32imm:$src),
- "and{q}\t{$src, %rax|%rax, $src}", []>;
+def AND64i32 : RIi32<0x25, RawFrm, (outs), (ins i32imm:$src),
+ "and{q}\t{$src, %rax|%rax, $src}", []>;
let isTwoAddress = 1 in {
let isCommutable = 1 in
@@ -1187,8 +1222,8 @@ def XOR64i32 : RIi32<0x35, RawFrm, (outs), (ins i32imm:$src),
// Integer comparison
let Defs = [EFLAGS] in {
-def TEST64i32 : RI<0xa9, RawFrm, (outs), (ins i32imm:$src),
- "test{q}\t{$src, %rax|%rax, $src}", []>;
+def TEST64i32 : RIi32<0xa9, RawFrm, (outs), (ins i32imm:$src),
+ "test{q}\t{$src, %rax|%rax, $src}", []>;
let isCommutable = 1 in
def TEST64rr : RI<0x85, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
"test{q}\t{$src2, $src1|$src1, $src2}",
@@ -1210,8 +1245,8 @@ def TEST64mi32 : RIi32<0xF7, MRM0m, (outs),
(implicit EFLAGS)]>;
-def CMP64i32 : RI<0x3D, RawFrm, (outs), (ins i32imm:$src),
- "cmp{q}\t{$src, %rax|%rax, $src}", []>;
+def CMP64i32 : RIi32<0x3D, RawFrm, (outs), (ins i32imm:$src),
+ "cmp{q}\t{$src, %rax|%rax, $src}", []>;
def CMP64rr : RI<0x39, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
"cmp{q}\t{$src2, $src1|$src1, $src2}",
[(X86cmp GR64:$src1, GR64:$src2),
@@ -1884,14 +1919,21 @@ def : Pat<(X86call (i64 texternalsym:$dst)),
(WINCALL64pcrel32 texternalsym:$dst)>, Requires<[IsWin64]>;
// tailcall stuff
-def : Pat<(X86tcret GR64:$dst, imm:$off),
- (TCRETURNri64 GR64:$dst, imm:$off)>;
+def : Pat<(X86tcret GR64_TC:$dst, imm:$off),
+ (TCRETURNri64 GR64_TC:$dst, imm:$off)>,
+ Requires<[In64BitMode]>;
+
+def : Pat<(X86tcret (load addr:$dst), imm:$off),
+ (TCRETURNmi64 addr:$dst, imm:$off)>,
+ Requires<[In64BitMode]>;
def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off),
- (TCRETURNdi64 tglobaladdr:$dst, imm:$off)>;
+ (TCRETURNdi64 tglobaladdr:$dst, imm:$off)>,
+ Requires<[In64BitMode]>;
def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off),
- (TCRETURNdi64 texternalsym:$dst, imm:$off)>;
+ (TCRETURNdi64 texternalsym:$dst, imm:$off)>,
+ Requires<[In64BitMode]>;
// Comparisons.
diff --git a/lib/Target/X86/X86InstrFPStack.td b/lib/Target/X86/X86InstrFPStack.td
index ae24bfb..b730918 100644
--- a/lib/Target/X86/X86InstrFPStack.td
+++ b/lib/Target/X86/X86InstrFPStack.td
@@ -350,20 +350,27 @@ def FBLDm : FPI<0xDF, MRM4m, (outs), (ins f32mem:$src), "fbld\t$src">;
def FBSTPm : FPI<0xDF, MRM6m, (outs f32mem:$dst), (ins), "fbstp\t$dst">;
// Floating point cmovs.
+class FpIf32CMov<dag outs, dag ins, FPFormat fp, list<dag> pattern> :
+ FpI_<outs, ins, fp, pattern>, Requires<[FPStackf32, HasCMov]>;
+class FpIf64CMov<dag outs, dag ins, FPFormat fp, list<dag> pattern> :
+ FpI_<outs, ins, fp, pattern>, Requires<[FPStackf64, HasCMov]>;
+
multiclass FPCMov<PatLeaf cc> {
- def _Fp32 : FpIf32<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2),
+ def _Fp32 : FpIf32CMov<(outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2),
CondMovFP,
[(set RFP32:$dst, (X86cmov RFP32:$src1, RFP32:$src2,
cc, EFLAGS))]>;
- def _Fp64 : FpIf64<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2),
+ def _Fp64 : FpIf64CMov<(outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2),
CondMovFP,
[(set RFP64:$dst, (X86cmov RFP64:$src1, RFP64:$src2,
cc, EFLAGS))]>;
def _Fp80 : FpI_<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2),
CondMovFP,
[(set RFP80:$dst, (X86cmov RFP80:$src1, RFP80:$src2,
- cc, EFLAGS))]>;
+ cc, EFLAGS))]>,
+ Requires<[HasCMov]>;
}
+
let Uses = [EFLAGS], isTwoAddress = 1 in {
defm CMOVB : FPCMov<X86_COND_B>;
defm CMOVBE : FPCMov<X86_COND_BE>;
@@ -375,6 +382,7 @@ defm CMOVNE : FPCMov<X86_COND_NE>;
defm CMOVNP : FPCMov<X86_COND_NP>;
}
+let Predicates = [HasCMov] in {
// These are not factored because there's no clean way to pass DA/DB.
def CMOVB_F : FPI<0xC0, AddRegFrm, (outs RST:$op), (ins),
"fcmovb\t{$op, %st(0)|%ST(0), $op}">, DA;
@@ -392,6 +400,7 @@ def CMOVNE_F : FPI<0xC8, AddRegFrm, (outs RST:$op), (ins),
"fcmovne\t{$op, %st(0)|%ST(0), $op}">, DB;
def CMOVNP_F : FPI<0xD8, AddRegFrm, (outs RST:$op), (ins),
"fcmovnu\t{$op, %st(0)|%ST(0), $op}">, DB;
+} // Predicates = [HasCMov]
// Floating point loads & stores.
let canFoldAsLoad = 1 in {
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 4fd91bb..139a905 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -266,6 +266,7 @@ X86InstrInfo::X86InstrInfo(X86TargetMachine &tm)
{ X86::MOV16rr, X86::MOV16mr, 0, 0 },
{ X86::MOV32ri, X86::MOV32mi, 0, 0 },
{ X86::MOV32rr, X86::MOV32mr, 0, 0 },
+ { X86::MOV32rr_TC, X86::MOV32mr_TC, 0, 0 },
{ X86::MOV64ri32, X86::MOV64mi32, 0, 0 },
{ X86::MOV64rr, X86::MOV64mr, 0, 0 },
{ X86::MOV8ri, X86::MOV8mi, 0, 0 },
@@ -301,6 +302,7 @@ X86InstrInfo::X86InstrInfo(X86TargetMachine &tm)
{ X86::SETPr, X86::SETPm, 0, 0 },
{ X86::SETSr, X86::SETSm, 0, 0 },
{ X86::TAILJMPr, X86::TAILJMPm, 1, 0 },
+ { X86::TAILJMPr64, X86::TAILJMPm64, 1, 0 },
{ X86::TEST16ri, X86::TEST16mi, 1, 0 },
{ X86::TEST32ri, X86::TEST32mi, 1, 0 },
{ X86::TEST64ri32, X86::TEST64mi32, 1, 0 },
@@ -376,6 +378,7 @@ X86InstrInfo::X86InstrInfo(X86TargetMachine &tm)
{ X86::Int_UCOMISSrr, X86::Int_UCOMISSrm, 0 },
{ X86::MOV16rr, X86::MOV16rm, 0 },
{ X86::MOV32rr, X86::MOV32rm, 0 },
+ { X86::MOV32rr_TC, X86::MOV32rm_TC, 0 },
{ X86::MOV64rr, X86::MOV64rm, 0 },
{ X86::MOV64toPQIrr, X86::MOVQI2PQIrm, 0 },
{ X86::MOV64toSDrr, X86::MOV64toSDrm, 0 },
@@ -675,6 +678,8 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI,
case X86::MOV16rr:
case X86::MOV32rr:
case X86::MOV64rr:
+ case X86::MOV32rr_TC:
+ case X86::MOV64rr_TC:
// FP Stack register class copies
case X86::MOV_Fp3232: case X86::MOV_Fp6464: case X86::MOV_Fp8080:
@@ -1901,6 +1906,10 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
Opc = X86::MOV16rr;
} else if (CommonRC == &X86::GR8_NOREXRegClass) {
Opc = X86::MOV8rr;
+ } else if (CommonRC == &X86::GR64_TCRegClass) {
+ Opc = X86::MOV64rr_TC;
+ } else if (CommonRC == &X86::GR32_TCRegClass) {
+ Opc = X86::MOV32rr_TC;
} else if (CommonRC == &X86::RFP32RegClass) {
Opc = X86::MOV_Fp3232;
} else if (CommonRC == &X86::RFP64RegClass || CommonRC == &X86::RSTRegClass) {
@@ -2038,6 +2047,10 @@ static unsigned getStoreRegOpcode(unsigned SrcReg,
Opc = X86::MOV16mr;
} else if (RC == &X86::GR8_NOREXRegClass) {
Opc = X86::MOV8mr;
+ } else if (RC == &X86::GR64_TCRegClass) {
+ Opc = X86::MOV64mr_TC;
+ } else if (RC == &X86::GR32_TCRegClass) {
+ Opc = X86::MOV32mr_TC;
} else if (RC == &X86::RFP80RegClass) {
Opc = X86::ST_FpP80m; // pops
} else if (RC == &X86::RFP64RegClass) {
@@ -2131,6 +2144,10 @@ static unsigned getLoadRegOpcode(unsigned DestReg,
Opc = X86::MOV16rm;
} else if (RC == &X86::GR8_NOREXRegClass) {
Opc = X86::MOV8rm;
+ } else if (RC == &X86::GR64_TCRegClass) {
+ Opc = X86::MOV64rm_TC;
+ } else if (RC == &X86::GR32_TCRegClass) {
+ Opc = X86::MOV32rm_TC;
} else if (RC == &X86::RFP80RegClass) {
Opc = X86::LD_Fp80m;
} else if (RC == &X86::RFP64RegClass) {
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 071c5aa..1225b68 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -21,6 +21,7 @@ def SDTIntShiftDOp: SDTypeProfile<1, 3,
[SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
SDTCisInt<0>, SDTCisInt<3>]>;
+// FIXME: Should be modelled as returning i32
def SDTX86CmpTest : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
def SDTX86Cmov : SDTypeProfile<1, 4,
@@ -83,7 +84,6 @@ def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>;
-
def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>;
def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>;
@@ -234,6 +234,15 @@ def i8mem_NOREX : Operand<i64> {
let ParserMatchClass = X86MemAsmOperand;
}
+// Special i32mem for addresses of load folding tail calls. These are not
+// allowed to use callee-saved registers since they must be scheduled
+// after callee-saved register are popped.
+def i32mem_TC : Operand<i32> {
+ let PrintMethod = "printi32mem";
+ let MIOperandInfo = (ops GR32_TC, i8imm, GR32_TC, i32imm, i8imm);
+ let ParserMatchClass = X86MemAsmOperand;
+}
+
def lea32mem : Operand<i32> {
let PrintMethod = "printlea32mem";
let MIOperandInfo = (ops GR32, i8imm, GR32_NOSP, i32imm);
@@ -288,6 +297,8 @@ def tls32addr : ComplexPattern<i32, 4, "SelectTLSADDRAddr",
//===----------------------------------------------------------------------===//
// X86 Instruction Predicate Definitions.
+def HasCMov : Predicate<"Subtarget->hasCMov()">;
+def NoCMov : Predicate<"!Subtarget->hasCMov()">;
def HasMMX : Predicate<"Subtarget->hasMMX()">;
def HasSSE1 : Predicate<"Subtarget->hasSSE1()">;
def HasSSE2 : Predicate<"Subtarget->hasSSE2()">;
@@ -696,30 +707,33 @@ def ENTER : I<0xC8, RawFrm, (outs), (ins i16imm:$len, i8imm:$lvl),
// Tail call stuff.
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
-def TCRETURNdi : I<0, Pseudo, (outs),
- (ins i32imm:$dst, i32imm:$offset, variable_ops),
- "#TC_RETURN $dst $offset",
- []>;
-
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
-def TCRETURNri : I<0, Pseudo, (outs),
- (ins GR32:$dst, i32imm:$offset, variable_ops),
- "#TC_RETURN $dst $offset",
- []>;
-
-// FIXME: The should be pseudo instructions that are lowered when going to
-// mcinst.
-let isCall = 1, isBranch = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
- def TAILJMPd : Ii32<0xE9, RawFrm, (outs),(ins i32imm_pcrel:$dst,variable_ops),
+ let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
+ MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
+ XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
+ Uses = [ESP] in {
+ def TCRETURNdi : I<0, Pseudo, (outs),
+ (ins i32imm_pcrel:$dst, i32imm:$offset, variable_ops),
+ "#TC_RETURN $dst $offset", []>;
+ def TCRETURNri : I<0, Pseudo, (outs),
+ (ins GR32_TC:$dst, i32imm:$offset, variable_ops),
+ "#TC_RETURN $dst $offset", []>;
+ def TCRETURNmi : I<0, Pseudo, (outs),
+ (ins i32mem_TC:$dst, i32imm:$offset, variable_ops),
+ "#TC_RETURN $dst $offset", []>;
+
+ // FIXME: The should be pseudo instructions that are lowered when going to
+ // mcinst.
+ def TAILJMPd : Ii32PCRel<0xE9, RawFrm, (outs),
+ (ins i32imm_pcrel:$dst, variable_ops),
"jmp\t$dst # TAILCALL",
[]>;
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
- def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32:$dst, variable_ops),
+ def TAILJMPr : I<0xFF, MRM4r, (outs), (ins GR32_TC:$dst, variable_ops),
"jmp{l}\t{*}$dst # TAILCALL",
[]>;
-let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
- def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem:$dst, variable_ops),
- "jmp\t{*}$dst # TAILCALL", []>;
+ def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem_TC:$dst, variable_ops),
+ "jmp{l}\t{*}$dst # TAILCALL", []>;
+}
//===----------------------------------------------------------------------===//
// Miscellaneous Instructions...
@@ -1032,6 +1046,22 @@ def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
"mov{l}\t{$src, $dst|$dst, $src}",
[(store GR32:$src, addr:$dst)]>;
+/// Versions of MOV32rr, MOV32rm, and MOV32mr for i32mem_TC and GR32_TC.
+let neverHasSideEffects = 1 in
+def MOV32rr_TC : I<0x89, MRMDestReg, (outs GR32_TC:$dst), (ins GR32_TC:$src),
+ "mov{l}\t{$src, $dst|$dst, $src}", []>;
+
+let mayLoad = 1,
+ canFoldAsLoad = 1, isReMaterializable = 1 in
+def MOV32rm_TC : I<0x8B, MRMSrcMem, (outs GR32_TC:$dst), (ins i32mem_TC:$src),
+ "mov{l}\t{$src, $dst|$dst, $src}",
+ []>;
+
+let mayStore = 1 in
+def MOV32mr_TC : I<0x89, MRMDestMem, (outs), (ins i32mem_TC:$dst, GR32_TC:$src),
+ "mov{l}\t{$src, $dst|$dst, $src}",
+ []>;
+
// Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
// that they can be used for copying and storing h registers, which can't be
// encoded when a REX prefix is present.
@@ -1185,19 +1215,7 @@ let isTwoAddress = 1 in {
// Conditional moves
let Uses = [EFLAGS] in {
-// X86 doesn't have 8-bit conditional moves. Use a customInserter to
-// emit control flow. An alternative to this is to mark i8 SELECT as Promote,
-// however that requires promoting the operands, and can induce additional
-// i8 register pressure. Note that CMOV_GR8 is conservatively considered to
-// clobber EFLAGS, because if one of the operands is zero, the expansion
-// could involve an xor.
-let usesCustomInserter = 1, isTwoAddress = 0, Defs = [EFLAGS] in
-def CMOV_GR8 : I<0, Pseudo,
- (outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cond),
- "#CMOV_GR8 PSEUDO!",
- [(set GR8:$dst, (X86cmov GR8:$src1, GR8:$src2,
- imm:$cond, EFLAGS))]>;
-
+let Predicates = [HasCMov] in {
let isCommutable = 1 in {
def CMOVB16rr : I<0x42, MRMSrcReg, // if <u, GR16 = GR16
(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
@@ -1585,6 +1603,49 @@ def CMOVNO32rm : I<0x41, MRMSrcMem, // if !overflow, GR32 = [mem32]
[(set GR32:$dst, (X86cmov GR32:$src1, (loadi32 addr:$src2),
X86_COND_NO, EFLAGS))]>,
TB;
+} // Predicates = [HasCMov]
+
+// X86 doesn't have 8-bit conditional moves. Use a customInserter to
+// emit control flow. An alternative to this is to mark i8 SELECT as Promote,
+// however that requires promoting the operands, and can induce additional
+// i8 register pressure. Note that CMOV_GR8 is conservatively considered to
+// clobber EFLAGS, because if one of the operands is zero, the expansion
+// could involve an xor.
+let usesCustomInserter = 1, isTwoAddress = 0, Defs = [EFLAGS] in {
+def CMOV_GR8 : I<0, Pseudo,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2, i8imm:$cond),
+ "#CMOV_GR8 PSEUDO!",
+ [(set GR8:$dst, (X86cmov GR8:$src1, GR8:$src2,
+ imm:$cond, EFLAGS))]>;
+
+let Predicates = [NoCMov] in {
+def CMOV_GR32 : I<0, Pseudo,
+ (outs GR32:$dst), (ins GR32:$src1, GR32:$src2, i8imm:$cond),
+ "#CMOV_GR32* PSEUDO!",
+ [(set GR32:$dst,
+ (X86cmov GR32:$src1, GR32:$src2, imm:$cond, EFLAGS))]>;
+def CMOV_GR16 : I<0, Pseudo,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2, i8imm:$cond),
+ "#CMOV_GR16* PSEUDO!",
+ [(set GR16:$dst,
+ (X86cmov GR16:$src1, GR16:$src2, imm:$cond, EFLAGS))]>;
+def CMOV_RFP32 : I<0, Pseudo,
+ (outs RFP32:$dst), (ins RFP32:$src1, RFP32:$src2, i8imm:$cond),
+ "#CMOV_RFP32 PSEUDO!",
+ [(set RFP32:$dst, (X86cmov RFP32:$src1, RFP32:$src2, imm:$cond,
+ EFLAGS))]>;
+def CMOV_RFP64 : I<0, Pseudo,
+ (outs RFP64:$dst), (ins RFP64:$src1, RFP64:$src2, i8imm:$cond),
+ "#CMOV_RFP64 PSEUDO!",
+ [(set RFP64:$dst, (X86cmov RFP64:$src1, RFP64:$src2, imm:$cond,
+ EFLAGS))]>;
+def CMOV_RFP80 : I<0, Pseudo,
+ (outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2, i8imm:$cond),
+ "#CMOV_RFP80 PSEUDO!",
+ [(set RFP80:$dst, (X86cmov RFP80:$src1, RFP80:$src2, imm:$cond,
+ EFLAGS))]>;
+} // Predicates = [NoCMov]
+} // UsesCustomInserter = 1, isTwoAddress = 0, Defs = [EFLAGS]
} // Uses = [EFLAGS]
@@ -4294,14 +4355,21 @@ def : Pat<(store (i32 (X86Wrapper tblockaddress:$src)), addr:$dst),
// Calls
// tailcall stuff
-def : Pat<(X86tcret GR32:$dst, imm:$off),
- (TCRETURNri GR32:$dst, imm:$off)>;
+def : Pat<(X86tcret GR32_TC:$dst, imm:$off),
+ (TCRETURNri GR32_TC:$dst, imm:$off)>,
+ Requires<[In32BitMode]>;
+
+def : Pat<(X86tcret (load addr:$dst), imm:$off),
+ (TCRETURNmi addr:$dst, imm:$off)>,
+ Requires<[In32BitMode]>;
def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off),
- (TCRETURNdi texternalsym:$dst, imm:$off)>;
+ (TCRETURNdi texternalsym:$dst, imm:$off)>,
+ Requires<[In32BitMode]>;
def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off),
- (TCRETURNdi texternalsym:$dst, imm:$off)>;
+ (TCRETURNdi texternalsym:$dst, imm:$off)>,
+ Requires<[In32BitMode]>;
// Normal calls, with various flavors of addresses.
def : Pat<(X86call (i32 tglobaladdr:$dst)),
diff --git a/lib/Target/X86/X86InstrMMX.td b/lib/Target/X86/X86InstrMMX.td
index eea0eb8..e1203e2 100644
--- a/lib/Target/X86/X86InstrMMX.td
+++ b/lib/Target/X86/X86InstrMMX.td
@@ -272,9 +272,9 @@ defm MMX_PSRAD : MMXI_binop_rmi_int<0xE2, 0x72, MRM4r, "psrad",
// Shift up / down and insert zero's.
def : Pat<(v1i64 (X86vshl VR64:$src, (i8 imm:$amt))),
- (MMX_PSLLQri VR64:$src, imm:$amt)>;
+ (MMX_PSLLQri VR64:$src, (GetLo32XForm imm:$amt))>;
def : Pat<(v1i64 (X86vshr VR64:$src, (i8 imm:$amt))),
- (MMX_PSRLQri VR64:$src, imm:$amt)>;
+ (MMX_PSRLQri VR64:$src, (GetLo32XForm imm:$amt))>;
// Comparison Instructions
defm MMX_PCMPEQB : MMXI_binop_rm_int<0x74, "pcmpeqb", int_x86_mmx_pcmpeq_b>;
diff --git a/lib/Target/X86/X86InstrSSE.td b/lib/Target/X86/X86InstrSSE.td
index bd6e1b8..18f9e52 100644
--- a/lib/Target/X86/X86InstrSSE.td
+++ b/lib/Target/X86/X86InstrSSE.td
@@ -379,7 +379,7 @@ let Constraints = "$src1 = $dst" in
def MOVSSrr : SSI<0x10, MRMSrcReg,
(outs VR128:$dst), (ins VR128:$src1, FR32:$src2),
"movss\t{$src2, $dst|$dst, $src2}",
- [(set VR128:$dst,
+ [(set (v4f32 VR128:$dst),
(movl VR128:$src1, (scalar_to_vector FR32:$src2)))]>;
// Extract the low 32-bit value from one vector and insert it into another.
@@ -1141,7 +1141,7 @@ let Constraints = "$src1 = $dst" in
def MOVSDrr : SDI<0x10, MRMSrcReg,
(outs VR128:$dst), (ins VR128:$src1, FR64:$src2),
"movsd\t{$src2, $dst|$dst, $src2}",
- [(set VR128:$dst,
+ [(set (v2f64 VR128:$dst),
(movl VR128:$src1, (scalar_to_vector FR64:$src2)))]>;
// Extract the low 64-bit value from one vector and insert it into another.
diff --git a/lib/Target/X86/X86JITInfo.cpp b/lib/Target/X86/X86JITInfo.cpp
index d297d24..6f0a8d9 100644
--- a/lib/Target/X86/X86JITInfo.cpp
+++ b/lib/Target/X86/X86JITInfo.cpp
@@ -19,6 +19,7 @@
#include "llvm/Function.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/System/Valgrind.h"
#include <cstdlib>
#include <cstring>
using namespace llvm;
@@ -37,6 +38,10 @@ void X86JITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
unsigned NewAddr = (intptr_t)New;
unsigned OldAddr = (intptr_t)OldWord;
*OldWord = NewAddr - OldAddr - 4; // Emit PC-relative addr of New code.
+
+ // X86 doesn't need to invalidate the processor cache, so just invalidate
+ // Valgrind's cache directly.
+ sys::ValgrindDiscardTranslations(Old, 5);
}
@@ -393,8 +398,10 @@ X86CompilationCallback2(intptr_t *StackPtr, intptr_t RetAddr) {
*(intptr_t *)(RetAddr - 0xa) = NewVal;
((unsigned char*)RetAddr)[0] = (2 | (4 << 3) | (3 << 6));
}
+ sys::ValgrindDiscardTranslations((void*)(RetAddr-0xc), 0xd);
#else
((unsigned char*)RetAddr)[-1] = 0xE9;
+ sys::ValgrindDiscardTranslations((void*)(RetAddr-1), 5);
#endif
}
diff --git a/lib/Target/X86/X86MCAsmInfo.cpp b/lib/Target/X86/X86MCAsmInfo.cpp
index 9498810..1afabc9 100644
--- a/lib/Target/X86/X86MCAsmInfo.cpp
+++ b/lib/Target/X86/X86MCAsmInfo.cpp
@@ -70,7 +70,7 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &Triple) {
ExceptionsType = ExceptionHandling::Dwarf;
}
-X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &Triple) {
+X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) {
AsmTransCBE = x86_asm_table;
AssemblerDialect = AsmWriterFlavor;
@@ -89,6 +89,11 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &Triple) {
// Exceptions handling
ExceptionsType = ExceptionHandling::Dwarf;
+
+ // OpenBSD has buggy support for .quad in 32-bit mode, just split into two
+ // .words.
+ if (T.getOS() == Triple::OpenBSD && T.getArch() == Triple::x86)
+ Data64bitsDirective = 0;
}
MCSection *X86ELFMCAsmInfo::getNonexecutableStackSection(MCContext &Ctx) const {
diff --git a/lib/Target/X86/X86MCTargetExpr.cpp b/lib/Target/X86/X86MCTargetExpr.cpp
deleted file mode 100644
index 17b4fe8..0000000
--- a/lib/Target/X86/X86MCTargetExpr.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//===- X86MCTargetExpr.cpp - X86 Target Specific MCExpr Implementation ----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "X86MCTargetExpr.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/MCValue.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-
-X86MCTargetExpr *X86MCTargetExpr::Create(const MCSymbol *Sym, VariantKind K,
- MCContext &Ctx) {
- return new (Ctx) X86MCTargetExpr(Sym, K);
-}
-
-void X86MCTargetExpr::PrintImpl(raw_ostream &OS) const {
- OS << *Sym;
-
- switch (Kind) {
- case Invalid: OS << "@<invalid>"; break;
- case GOT: OS << "@GOT"; break;
- case GOTOFF: OS << "@GOTOFF"; break;
- case GOTPCREL: OS << "@GOTPCREL"; break;
- case GOTTPOFF: OS << "@GOTTPOFF"; break;
- case INDNTPOFF: OS << "@INDNTPOFF"; break;
- case NTPOFF: OS << "@NTPOFF"; break;
- case PLT: OS << "@PLT"; break;
- case TLSGD: OS << "@TLSGD"; break;
- case TPOFF: OS << "@TPOFF"; break;
- }
-}
-
-bool X86MCTargetExpr::EvaluateAsRelocatableImpl(MCValue &Res) const {
- // FIXME: I don't know if this is right, it followed MCSymbolRefExpr.
-
- // Evaluate recursively if this is a variable.
- if (Sym->isVariable())
- return Sym->getValue()->EvaluateAsRelocatable(Res);
-
- Res = MCValue::get(Sym, 0, 0);
- return true;
-}
diff --git a/lib/Target/X86/X86MCTargetExpr.h b/lib/Target/X86/X86MCTargetExpr.h
deleted file mode 100644
index 7de8a5c..0000000
--- a/lib/Target/X86/X86MCTargetExpr.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//===- X86MCTargetExpr.h - X86 Target Specific MCExpr -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef X86_MCTARGETEXPR_H
-#define X86_MCTARGETEXPR_H
-
-#include "llvm/MC/MCExpr.h"
-
-namespace llvm {
-
-/// X86MCTargetExpr - This class represents symbol variants, like foo@GOT.
-class X86MCTargetExpr : public MCTargetExpr {
-public:
- enum VariantKind {
- Invalid,
- GOT,
- GOTOFF,
- GOTPCREL,
- GOTTPOFF,
- INDNTPOFF,
- NTPOFF,
- PLT,
- TLSGD,
- TPOFF
- };
-private:
- /// Sym - The symbol being referenced.
- const MCSymbol * const Sym;
- /// Kind - The modifier.
- const VariantKind Kind;
-
- X86MCTargetExpr(const MCSymbol *S, VariantKind K) : Sym(S), Kind(K) {}
-public:
- static X86MCTargetExpr *Create(const MCSymbol *Sym, VariantKind K,
- MCContext &Ctx);
-
- void PrintImpl(raw_ostream &OS) const;
- bool EvaluateAsRelocatableImpl(MCValue &Res) const;
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index cdb579c..3238cce 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -294,13 +294,20 @@ X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
const unsigned *
X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
bool callsEHReturn = false;
+ bool ghcCall = false;
if (MF) {
const MachineFrameInfo *MFI = MF->getFrameInfo();
const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
callsEHReturn = (MMI ? MMI->callsEHReturn() : false);
+ const Function *F = MF->getFunction();
+ ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
}
+ static const unsigned GhcCalleeSavedRegs[] = {
+ 0
+ };
+
static const unsigned CalleeSavedRegs32Bit[] = {
X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
};
@@ -326,7 +333,9 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
X86::XMM14, X86::XMM15, 0
};
- if (Is64Bit) {
+ if (ghcCall) {
+ return GhcCalleeSavedRegs;
+ } else if (Is64Bit) {
if (IsWin64)
return CalleeSavedRegsWin64;
else
@@ -788,7 +797,7 @@ static int mergeSPUpdates(MachineBasicBlock &MBB,
}
void X86RegisterInfo::emitCalleeSavedFrameMoves(MachineFunction &MF,
- unsigned LabelId,
+ MCSymbol *Label,
unsigned FramePtr) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
@@ -851,7 +860,7 @@ void X86RegisterInfo::emitCalleeSavedFrameMoves(MachineFunction &MF,
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
MachineLocation CSSrc(Reg);
- Moves.push_back(MachineMove(LabelId, CSDst, CSSrc));
+ Moves.push_back(MachineMove(Label, CSDst, CSSrc));
}
}
@@ -929,10 +938,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
std::vector<MachineMove> &Moves = MMI->getFrameMoves();
const TargetData *TD = MF.getTarget().getTargetData();
uint64_t NumBytes = 0;
- int stackGrowth =
- (MF.getTarget().getFrameInfo()->getStackGrowthDirection() ==
- TargetFrameInfo::StackGrowsUp ?
- TD->getPointerSize() : -TD->getPointerSize());
+ int stackGrowth = -TD->getPointerSize();
if (HasFP) {
// Calculate required stack adjustment.
@@ -953,26 +959,25 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
if (needsFrameMoves) {
// Mark the place where EBP/RBP was saved.
- unsigned FrameLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(FrameLabelId);
+ MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
// Define the current CFA rule to use the provided offset.
if (StackSize) {
MachineLocation SPDst(MachineLocation::VirtualFP);
MachineLocation SPSrc(MachineLocation::VirtualFP, 2 * stackGrowth);
- Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
+ Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
} else {
// FIXME: Verify & implement for FP
MachineLocation SPDst(StackPtr);
MachineLocation SPSrc(StackPtr, stackGrowth);
- Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
+ Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
}
// Change the rule for the FramePtr to be an "offset" rule.
- MachineLocation FPDst(MachineLocation::VirtualFP,
- 2 * stackGrowth);
+ MachineLocation FPDst(MachineLocation::VirtualFP, 2 * stackGrowth);
MachineLocation FPSrc(FramePtr);
- Moves.push_back(MachineMove(FrameLabelId, FPDst, FPSrc));
+ Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
}
// Update EBP with the new base value...
@@ -982,13 +987,13 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
if (needsFrameMoves) {
// Mark effective beginning of when frame pointer becomes valid.
- unsigned FrameLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(FrameLabelId);
+ MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(FrameLabel);
// Define the current CFA to use the EBP/RBP register.
MachineLocation FPDst(FramePtr);
MachineLocation FPSrc(MachineLocation::VirtualFP);
- Moves.push_back(MachineMove(FrameLabelId, FPDst, FPSrc));
+ Moves.push_back(MachineMove(FrameLabel, FPDst, FPSrc));
}
// Mark the FramePtr as live-in in every block except the entry.
@@ -1022,15 +1027,15 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
if (!HasFP && needsFrameMoves) {
// Mark callee-saved push instruction.
- unsigned LabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(LabelId);
+ MCSymbol *Label = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
// Define the current CFA rule to use the provided offset.
unsigned Ptr = StackSize ?
MachineLocation::VirtualFP : StackPtr;
MachineLocation SPDst(Ptr);
MachineLocation SPSrc(Ptr, StackOffset);
- Moves.push_back(MachineMove(LabelId, SPDst, SPSrc));
+ Moves.push_back(MachineMove(Label, SPDst, SPSrc));
StackOffset += stackGrowth;
}
}
@@ -1094,8 +1099,8 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
if ((NumBytes || PushedRegs) && needsFrameMoves) {
// Mark end of stack pointer adjustment.
- unsigned LabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(LabelId);
+ MCSymbol *Label = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addSym(Label);
if (!HasFP && NumBytes) {
// Define the current CFA rule to use the provided offset.
@@ -1103,18 +1108,18 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineLocation SPDst(MachineLocation::VirtualFP);
MachineLocation SPSrc(MachineLocation::VirtualFP,
-StackSize + stackGrowth);
- Moves.push_back(MachineMove(LabelId, SPDst, SPSrc));
+ Moves.push_back(MachineMove(Label, SPDst, SPSrc));
} else {
// FIXME: Verify & implement for FP
MachineLocation SPDst(StackPtr);
MachineLocation SPSrc(StackPtr, stackGrowth);
- Moves.push_back(MachineMove(LabelId, SPDst, SPSrc));
+ Moves.push_back(MachineMove(Label, SPDst, SPSrc));
}
}
// Emit DWARF info specifying the offsets of the callee-saved registers.
if (PushedRegs)
- emitCalleeSavedFrameMoves(MF, LabelId, HasFP ? FramePtr : StackPtr);
+ emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr);
}
}
@@ -1133,13 +1138,12 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
case X86::RETI:
case X86::TCRETURNdi:
case X86::TCRETURNri:
- case X86::TCRETURNri64:
+ case X86::TCRETURNmi:
case X86::TCRETURNdi64:
+ case X86::TCRETURNri64:
+ case X86::TCRETURNmi64:
case X86::EH_RETURN:
case X86::EH_RETURN64:
- case X86::TAILJMPd:
- case X86::TAILJMPr:
- case X86::TAILJMPm:
break; // These are ok
}
@@ -1224,11 +1228,14 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
StackPtr).addReg(DestAddr.getReg());
} else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi ||
- RetOpcode== X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64) {
+ RetOpcode == X86::TCRETURNmi ||
+ RetOpcode == X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64 ||
+ RetOpcode == X86::TCRETURNmi64) {
+ bool isMem = RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64;
// Tail call return: adjust the stack pointer and jump to callee.
MBBI = prior(MBB.end());
MachineOperand &JumpTarget = MBBI->getOperand(0);
- MachineOperand &StackAdjust = MBBI->getOperand(1);
+ MachineOperand &StackAdjust = MBBI->getOperand(isMem ? 5 : 1);
assert(StackAdjust.isImm() && "Expecting immediate value.");
// Adjust stack pointer.
@@ -1248,10 +1255,17 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
}
// Jump to label or value in register.
- if (RetOpcode == X86::TCRETURNdi|| RetOpcode == X86::TCRETURNdi64) {
- BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPd)).
+ if (RetOpcode == X86::TCRETURNdi || RetOpcode == X86::TCRETURNdi64) {
+ BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNdi)
+ ? X86::TAILJMPd : X86::TAILJMPd64)).
addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
JumpTarget.getTargetFlags());
+ } else if (RetOpcode == X86::TCRETURNmi || RetOpcode == X86::TCRETURNmi64) {
+ MachineInstrBuilder MIB =
+ BuildMI(MBB, MBBI, DL, TII.get((RetOpcode == X86::TCRETURNmi)
+ ? X86::TAILJMPm : X86::TAILJMPm64));
+ for (unsigned i = 0; i != 5; ++i)
+ MIB.addOperand(MBBI->getOperand(i));
} else if (RetOpcode == X86::TCRETURNri64) {
BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64), JumpTarget.getReg());
} else {
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index 12b2f3e..ac96c4c 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -149,7 +149,7 @@ public:
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
- void emitCalleeSavedFrameMoves(MachineFunction &MF, unsigned LabelId,
+ void emitCalleeSavedFrameMoves(MachineFunction &MF, MCSymbol *Label,
unsigned FramePtr) const;
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td
index ed2ce6c..76b8f7a 100644
--- a/lib/Target/X86/X86RegisterInfo.td
+++ b/lib/Target/X86/X86RegisterInfo.td
@@ -535,6 +535,13 @@ def GR32_ABCD : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, EBX]> {
def GR64_ABCD : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RBX]> {
let SubRegClassList = [GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD, GR32_ABCD];
}
+def GR32_TC : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX]> {
+ let SubRegClassList = [GR8, GR8, GR16];
+}
+def GR64_TC : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI,
+ R8, R9, R11]> {
+ let SubRegClassList = [GR8, GR8, GR16, GR32_TC];
+}
// GR8_NOREX - GR8 registers which do not require a REX prefix.
def GR8_NOREX : RegisterClass<"X86", [i8], 8,
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index adef5bc..f907614 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -315,9 +315,14 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &FS,
// If requesting codegen for X86-64, make sure that 64-bit features
// are enabled.
- if (Is64Bit)
+ if (Is64Bit) {
HasX86_64 = true;
+ // All 64-bit cpus have cmov support.
+ HasCMov = true;
+ }
+
+
DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel
<< ", 3DNowLevel " << X863DNowLevel
<< ", 64bit " << HasX86_64 << "\n");
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index 594a470..50338d3 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -133,6 +133,7 @@ public:
PICStyles::Style getPICStyle() const { return PICStyle; }
void setPICStyle(PICStyles::Style Style) { PICStyle = Style; }
+ bool hasCMov() const { return HasCMov; }
bool hasMMX() const { return X86SSELevel >= MMX; }
bool hasSSE1() const { return X86SSELevel >= SSE1; }
bool hasSSE2() const { return X86SSELevel >= SSE2; }
diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp
index c80ae19..c15dfbb 100644
--- a/lib/Target/X86/X86TargetObjectFile.cpp
+++ b/lib/Target/X86/X86TargetObjectFile.cpp
@@ -7,11 +7,12 @@
//
//===----------------------------------------------------------------------===//
-#include "X86MCTargetExpr.h"
#include "X86TargetObjectFile.h"
#include "X86TargetMachine.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSectionMachO.h"
#include "llvm/Target/Mangler.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Dwarf.h"
@@ -19,28 +20,22 @@ using namespace llvm;
using namespace dwarf;
const MCExpr *X8664_MachoTargetObjectFile::
-getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- unsigned Encoding) const {
+getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const {
// On Darwin/X86-64, we can reference dwarf symbols with foo@GOTPCREL+4, which
// is an indirect pc-relative reference.
if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) {
- SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, false);
- const MCSymbol *Sym;
- if (GV->hasPrivateLinkage())
- Sym = getContext().GetOrCreateTemporarySymbol(Name);
- else
- Sym = getContext().GetOrCreateSymbol(Name);
+ const MCSymbol *Sym = Mang->getSymbol(GV);
const MCExpr *Res =
- X86MCTargetExpr::Create(Sym, X86MCTargetExpr::GOTPCREL, getContext());
+ MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext());
const MCExpr *Four = MCConstantExpr::Create(4, getContext());
return MCBinaryExpr::CreateAdd(Res, Four, getContext());
}
return TargetLoweringObjectFileMachO::
- getSymbolForDwarfGlobalReference(GV, Mang, MMI, Encoding);
+ getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, Streamer);
}
unsigned X8632_ELFTargetObjectFile::getPersonalityEncoding() const {
diff --git a/lib/Target/X86/X86TargetObjectFile.h b/lib/Target/X86/X86TargetObjectFile.h
index 0444417..f2fd49c 100644
--- a/lib/Target/X86/X86TargetObjectFile.h
+++ b/lib/Target/X86/X86TargetObjectFile.h
@@ -17,14 +17,14 @@
namespace llvm {
class X86TargetMachine;
- /// X8664_MachoTargetObjectFile - This TLOF implementation is used for
- /// Darwin/x86-64.
+ /// X8664_MachoTargetObjectFile - This TLOF implementation is used for Darwin
+ /// x86-64.
class X8664_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
public:
-
virtual const MCExpr *
- getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding) const;
+ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
};
class X8632_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
diff --git a/lib/Target/XCore/AsmPrinter/Makefile b/lib/Target/XCore/AsmPrinter/Makefile
index 82dc1df..581f736 100644
--- a/lib/Target/XCore/AsmPrinter/Makefile
+++ b/lib/Target/XCore/AsmPrinter/Makefile
@@ -11,6 +11,6 @@ LEVEL = ../../../..
LIBRARYNAME = LLVMXCoreAsmPrinter
# Hack: we need to include 'main' XCore target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
index 82e23a1..c882338 100644
--- a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
+++ b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
@@ -30,6 +30,7 @@
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
@@ -53,9 +54,8 @@ namespace {
const XCoreSubtarget &Subtarget;
public:
explicit XCoreAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
- MCContext &Ctx, MCStreamer &Streamer,
- const MCAsmInfo *T)
- : AsmPrinter(O, TM, Ctx, Streamer, T),
+ MCStreamer &Streamer)
+ : AsmPrinter(O, TM, Streamer),
Subtarget(TM.getSubtarget<XCoreSubtarget>()) {}
virtual const char *getPassName() const {
@@ -129,7 +129,7 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM));
- MCSymbol *GVSym = GetGlobalValueSymbol(GV);
+ MCSymbol *GVSym = Mang->getSymbol(GV);
Constant *C = GV->getInitializer();
unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());
@@ -276,7 +276,7 @@ printInlineJT(const MachineInstr *MI, int opNum, const std::string &directive)
MachineBasicBlock *MBB = JTBBs[i];
if (i > 0)
O << ",";
- O << *MBB->getSymbol(OutContext);
+ O << *MBB->getSymbol();
}
}
@@ -290,10 +290,10 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- O << *MO.getMBB()->getSymbol(OutContext);
+ O << *MO.getMBB()->getSymbol();
break;
case MachineOperand::MO_GlobalAddress:
- O << *GetGlobalValueSymbol(MO.getGlobal());
+ O << *Mang->getSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
O << MO.getSymbolName();
diff --git a/lib/Target/XCore/README.txt b/lib/Target/XCore/README.txt
index deaeb0f..b69205b 100644
--- a/lib/Target/XCore/README.txt
+++ b/lib/Target/XCore/README.txt
@@ -5,4 +5,3 @@ To-do
* Tailcalls
* Investigate loop alignment
* Add builtins
-* Make better use of lmul / macc
diff --git a/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/lib/Target/XCore/XCoreISelDAGToDAG.cpp
index 29a6ab7..1615547 100644
--- a/lib/Target/XCore/XCoreISelDAGToDAG.cpp
+++ b/lib/Target/XCore/XCoreISelDAGToDAG.cpp
@@ -173,29 +173,6 @@ SDNode *XCoreDAGToDAGISel::Select(SDNode *N) {
}
break;
}
- case ISD::SMUL_LOHI: {
- // 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, 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));
- ReplaceUses(SDValue(N, 1), SDValue(ResNode, 0));
- return NULL;
- }
- case ISD::UMUL_LOHI: {
- // 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[] = { N->getOperand(0), N->getOperand(1),
- Zero, Zero };
- SDNode *ResNode = CurDAG->getMachineNode(XCore::LMUL_l6r, dl, MVT::i32,
- MVT::i32, Ops, 4);
- ReplaceUses(SDValue(N, 0), SDValue(ResNode, 1));
- ReplaceUses(SDValue(N, 1), SDValue(ResNode, 0));
- return NULL;
- }
case XCoreISD::LADD: {
SDValue Ops[] = { N->getOperand(0), N->getOperand(1),
N->getOperand(2) };
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index 8249219..bf1a457 100644
--- a/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/lib/Target/XCore/XCoreISelLowering.cpp
@@ -324,6 +324,10 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG)
return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, Res);
}
+unsigned XCoreTargetLowering::getJumpTableEncoding() const {
+ return MachineJumpTableInfo::EK_Inline;
+}
+
SDValue XCoreTargetLowering::
LowerBR_JT(SDValue Op, SelectionDAG &DAG)
{
@@ -1341,12 +1345,41 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
}
}
break;
+ case XCoreISD::LMUL: {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
+ SDValue N3 = N->getOperand(3);
+ ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
+ ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
+ EVT VT = N0.getValueType();
+ // Canonicalize multiplicative constant to RHS. If both multiplicative
+ // operands are constant canonicalize smallest to RHS.
+ if ((N0C && !N1C) ||
+ (N0C && N1C && N0C->getZExtValue() < N1C->getZExtValue()))
+ return DAG.getNode(XCoreISD::LMUL, dl, DAG.getVTList(VT, VT), N1, N0, N2, N3);
+
+ // lmul(x, 0, a, b)
+ if (N1C && N1C->isNullValue()) {
+ // If the high result is unused fold to add(a, b)
+ if (N->hasNUsesOfValue(0, 0)) {
+ SDValue Lo = DAG.getNode(ISD::ADD, dl, VT, N2, N3);
+ SDValue Ops [] = { Lo, Lo };
+ return DAG.getMergeValues(Ops, 2, dl);
+ }
+ // Otherwise fold to ladd(a, b, 0)
+ return DAG.getNode(XCoreISD::LADD, dl, DAG.getVTList(VT, VT), N2, N3, N1);
+ }
+ }
+ break;
case ISD::ADD: {
- // Fold expressions such as add(add(mul(x,y),a),b) -> lmul(x, y, a, b).
+ // Fold 32 bit expressions such as add(add(mul(x,y),a),b) ->
+ // lmul(x, y, a, b). The high result of lmul will be ignored.
// This is only profitable if the intermediate results are unused
// elsewhere.
SDValue Mul0, Mul1, Addend0, Addend1;
- if (isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, true)) {
+ if (N->getValueType(0) == MVT::i32 &&
+ isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, true)) {
SDValue Zero = DAG.getConstant(0, MVT::i32);
SDValue Ignored = DAG.getNode(XCoreISD::LMUL, dl,
DAG.getVTList(MVT::i32, MVT::i32), Mul0,
@@ -1354,6 +1387,31 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
SDValue Result(Ignored.getNode(), 1);
return Result;
}
+ APInt HighMask = APInt::getHighBitsSet(64, 32);
+ // Fold 64 bit expression such as add(add(mul(x,y),a),b) ->
+ // lmul(x, y, a, b) if all operands are zero-extended. We do this
+ // before type legalization as it is messy to match the operands after
+ // that.
+ if (N->getValueType(0) == MVT::i64 &&
+ isADDADDMUL(SDValue(N, 0), Mul0, Mul1, Addend0, Addend1, false) &&
+ DAG.MaskedValueIsZero(Mul0, HighMask) &&
+ DAG.MaskedValueIsZero(Mul1, HighMask) &&
+ DAG.MaskedValueIsZero(Addend0, HighMask) &&
+ DAG.MaskedValueIsZero(Addend1, HighMask)) {
+ SDValue Mul0L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Mul0, DAG.getConstant(0, MVT::i32));
+ SDValue Mul1L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Mul1, DAG.getConstant(0, MVT::i32));
+ SDValue Addend0L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Addend0, DAG.getConstant(0, MVT::i32));
+ SDValue Addend1L = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32,
+ Addend1, DAG.getConstant(0, MVT::i32));
+ SDValue Hi = DAG.getNode(XCoreISD::LMUL, dl,
+ DAG.getVTList(MVT::i32, MVT::i32), Mul0L, Mul1L,
+ Addend0L, Addend1L);
+ SDValue Lo(Hi.getNode(), 1);
+ return DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, Lo, Hi);
+ }
}
break;
case ISD::STORE: {
diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h
index f597780..3ccdeec 100644
--- a/lib/Target/XCore/XCoreISelLowering.h
+++ b/lib/Target/XCore/XCoreISelLowering.h
@@ -80,6 +80,8 @@ namespace llvm {
explicit XCoreTargetLowering(XCoreTargetMachine &TM);
+ virtual unsigned getJumpTableEncoding() const;
+
/// LowerOperation - Provide custom lowering hooks for some operations.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
diff --git a/lib/Target/XCore/XCoreInstrInfo.cpp b/lib/Target/XCore/XCoreInstrInfo.cpp
index 722e747..e5f5a6d 100644
--- a/lib/Target/XCore/XCoreInstrInfo.cpp
+++ b/lib/Target/XCore/XCoreInstrInfo.cpp
@@ -429,10 +429,9 @@ bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
storeRegToStackSlot(MBB, MI, it->getReg(), true,
it->getFrameIdx(), it->getRegClass());
if (emitFrameMoves) {
- unsigned SaveLabelId = MMI->NextLabelID();
- BuildMI(MBB, MI, DL, get(XCore::DBG_LABEL)).addImm(SaveLabelId);
- XFI->getSpillLabels().push_back(
- std::pair<unsigned, CalleeSavedInfo>(SaveLabelId, *it));
+ MCSymbol *SaveLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MI, DL, get(XCore::DBG_LABEL)).addSym(SaveLabel);
+ XFI->getSpillLabels().push_back(std::make_pair(SaveLabel, *it));
}
}
return true;
diff --git a/lib/Target/XCore/XCoreMachineFunctionInfo.h b/lib/Target/XCore/XCoreMachineFunctionInfo.h
index 124a011..a575a0f 100644
--- a/lib/Target/XCore/XCoreMachineFunctionInfo.h
+++ b/lib/Target/XCore/XCoreMachineFunctionInfo.h
@@ -31,7 +31,7 @@ private:
int LRSpillSlot;
int FPSpillSlot;
int VarArgsFrameIndex;
- std::vector<std::pair<unsigned, CalleeSavedInfo> > SpillLabels;
+ std::vector<std::pair<MCSymbol*, CalleeSavedInfo> > SpillLabels;
public:
XCoreFunctionInfo() :
@@ -60,7 +60,7 @@ public:
void setFPSpillSlot(int off) { FPSpillSlot = off; }
int getFPSpillSlot() const { return FPSpillSlot; }
- std::vector<std::pair<unsigned, CalleeSavedInfo> >&getSpillLabels() {
+ std::vector<std::pair<MCSymbol*, CalleeSavedInfo> > &getSpillLabels() {
return SpillLabels;
}
};
diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp
index 0ab312e..8892504 100644
--- a/lib/Target/XCore/XCoreRegisterInfo.cpp
+++ b/lib/Target/XCore/XCoreRegisterInfo.cpp
@@ -456,17 +456,17 @@ void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const {
std::vector<MachineMove> &Moves = MMI->getFrameMoves();
// Show update of SP.
- unsigned FrameLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId);
+ MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addSym(FrameLabel);
MachineLocation SPDst(MachineLocation::VirtualFP);
MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4);
- Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
+ Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
if (LRSavedOnEntry) {
MachineLocation CSDst(MachineLocation::VirtualFP, 0);
MachineLocation CSSrc(XCore::LR);
- Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc));
+ Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc));
}
}
if (saveLR) {
@@ -475,12 +475,11 @@ void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const {
MBB.addLiveIn(XCore::LR);
if (emitFrameMoves) {
- unsigned SaveLRLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(SaveLRLabelId);
+ MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addSym(SaveLRLabel);
MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset);
MachineLocation CSSrc(XCore::LR);
- MMI->getFrameMoves().push_back(MachineMove(SaveLRLabelId,
- CSDst, CSSrc));
+ MMI->getFrameMoves().push_back(MachineMove(SaveLRLabel, CSDst, CSSrc));
}
}
}
@@ -492,12 +491,11 @@ void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const {
// R10 is live-in. It is killed at the spill.
MBB.addLiveIn(XCore::R10);
if (emitFrameMoves) {
- unsigned SaveR10LabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(SaveR10LabelId);
+ MCSymbol *SaveR10Label = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addSym(SaveR10Label);
MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset);
MachineLocation CSSrc(XCore::R10);
- MMI->getFrameMoves().push_back(MachineMove(SaveR10LabelId,
- CSDst, CSSrc));
+ MMI->getFrameMoves().push_back(MachineMove(SaveR10Label, CSDst, CSSrc));
}
// Set the FP from the SP.
unsigned FramePtr = XCore::R10;
@@ -505,21 +503,21 @@ void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const {
.addImm(0);
if (emitFrameMoves) {
// Show FP is now valid.
- unsigned FrameLabelId = MMI->NextLabelID();
- BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addImm(FrameLabelId);
+ MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(XCore::DBG_LABEL)).addSym(FrameLabel);
MachineLocation SPDst(FramePtr);
MachineLocation SPSrc(MachineLocation::VirtualFP);
- MMI->getFrameMoves().push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
+ MMI->getFrameMoves().push_back(MachineMove(FrameLabel, SPDst, SPSrc));
}
}
if (emitFrameMoves) {
// Frame moves for callee saved.
std::vector<MachineMove> &Moves = MMI->getFrameMoves();
- std::vector<std::pair<unsigned, CalleeSavedInfo> >&SpillLabels =
+ std::vector<std::pair<MCSymbol*, CalleeSavedInfo> >&SpillLabels =
XFI->getSpillLabels();
for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) {
- unsigned SpillLabel = SpillLabels[I].first;
+ MCSymbol *SpillLabel = SpillLabels[I].first;
CalleeSavedInfo &CSI = SpillLabels[I].second;
int Offset = MFI->getObjectOffset(CSI.getFrameIdx());
unsigned Reg = CSI.getReg();
OpenPOWER on IntegriCloud