summaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-01-23 11:09:33 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-01-23 11:09:33 +0000
commit3fd58f91dd318518f7daa4ba64c0aaf31799d89b (patch)
tree74eecbae571601ec6a626a53374b1eddc7b164a5 /lib/Target
parent3fba7d16b41dfbefe3b1be6bc0ab94c017728f79 (diff)
downloadFreeBSD-src-3fd58f91dd318518f7daa4ba64c0aaf31799d89b.zip
FreeBSD-src-3fd58f91dd318518f7daa4ba64c0aaf31799d89b.tar.gz
Update LLVM to r94309.
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp4
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp8
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.h1
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp4
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp23
-rw-r--r--lib/Target/ARM/ARMISelLowering.h2
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td23
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td65
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td20
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td16
-rw-r--r--lib/Target/ARM/ARMMCAsmInfo.cpp2
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp4
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp138
-rw-r--r--lib/Target/ARM/AsmParser/Makefile1
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp239
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp2
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp14
-rw-r--r--lib/Target/ARM/AsmPrinter/Makefile1
-rw-r--r--lib/Target/ARM/Makefile1
-rw-r--r--lib/Target/ARM/README.txt9
-rw-r--r--lib/Target/ARM/TargetInfo/Makefile1
-rw-r--r--lib/Target/ARM/Thumb1InstrInfo.cpp8
-rw-r--r--lib/Target/ARM/Thumb1RegisterInfo.cpp8
-rw-r--r--lib/Target/ARM/Thumb2InstrInfo.cpp10
-rw-r--r--lib/Target/ARM/Thumb2SizeReduction.cpp3
-rw-r--r--lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp82
-rw-r--r--lib/Target/Alpha/AsmPrinter/Makefile1
-rw-r--r--lib/Target/Alpha/Makefile2
-rw-r--r--lib/Target/Alpha/TargetInfo/Makefile1
-rw-r--r--lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp58
-rw-r--r--lib/Target/Blackfin/AsmPrinter/Makefile1
-rw-r--r--lib/Target/Blackfin/Makefile2
-rw-r--r--lib/Target/Blackfin/TargetInfo/Makefile1
-rw-r--r--lib/Target/CBackend/CBackend.cpp75
-rw-r--r--lib/Target/CBackend/Makefile1
-rw-r--r--lib/Target/CBackend/TargetInfo/Makefile1
-rw-r--r--lib/Target/CMakeLists.txt2
-rw-r--r--lib/Target/CellSPU/AsmPrinter/Makefile1
-rw-r--r--lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp129
-rw-r--r--lib/Target/CellSPU/Makefile1
-rw-r--r--lib/Target/CellSPU/SPUMCAsmInfo.cpp2
-rw-r--r--lib/Target/CellSPU/TargetInfo/Makefile1
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp1
-rw-r--r--lib/Target/CppBackend/Makefile1
-rw-r--r--lib/Target/CppBackend/TargetInfo/Makefile1
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp10
-rw-r--r--lib/Target/MSIL/MSILWriter.h2
-rw-r--r--lib/Target/MSIL/Makefile1
-rw-r--r--lib/Target/MSIL/TargetInfo/Makefile1
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp111
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp8
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp14
-rw-r--r--lib/Target/MSP430/AsmPrinter/Makefile1
-rw-r--r--lib/Target/MSP430/CMakeLists.txt3
-rw-r--r--lib/Target/MSP430/MSP430.h2
-rw-r--r--lib/Target/MSP430/MSP430.td10
-rw-r--r--lib/Target/MSP430/MSP430BranchSelector.cpp179
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.cpp67
-rw-r--r--lib/Target/MSP430/MSP430ISelLowering.h17
-rw-r--r--lib/Target/MSP430/MSP430InstrFormats.td166
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.cpp42
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.h18
-rw-r--r--lib/Target/MSP430/MSP430InstrInfo.td1340
-rw-r--r--lib/Target/MSP430/MSP430TargetMachine.cpp6
-rw-r--r--lib/Target/MSP430/MSP430TargetMachine.h1
-rw-r--r--lib/Target/MSP430/Makefile2
-rw-r--r--lib/Target/MSP430/TargetInfo/Makefile1
-rw-r--r--lib/Target/Makefile1
-rw-r--r--lib/Target/Mangler.cpp179
-rw-r--r--lib/Target/Mips/AsmPrinter/Makefile1
-rw-r--r--lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp121
-rw-r--r--lib/Target/Mips/Makefile2
-rw-r--r--lib/Target/Mips/MipsCallingConv.td8
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp54
-rw-r--r--lib/Target/Mips/MipsInstrInfo.cpp9
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td10
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.cpp2
-rw-r--r--lib/Target/Mips/TargetInfo/Makefile1
-rw-r--r--lib/Target/PIC16/AsmPrinter/Makefile1
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp82
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h4
-rw-r--r--lib/Target/PIC16/Makefile2
-rw-r--r--lib/Target/PIC16/PIC16DebugInfo.cpp5
-rw-r--r--lib/Target/PIC16/PIC16Passes/Makefile1
-rw-r--r--lib/Target/PIC16/TargetInfo/Makefile1
-rw-r--r--lib/Target/PowerPC/AsmPrinter/Makefile1
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp563
-rw-r--r--lib/Target/PowerPC/Makefile2
-rw-r--r--lib/Target/PowerPC/PPCMCAsmInfo.cpp3
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp29
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.h12
-rw-r--r--lib/Target/PowerPC/TargetInfo/Makefile1
-rw-r--r--lib/Target/README.txt51
-rw-r--r--lib/Target/Sparc/AsmPrinter/Makefile2
-rw-r--r--lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp97
-rw-r--r--lib/Target/Sparc/Makefile2
-rw-r--r--lib/Target/Sparc/TargetInfo/Makefile1
-rw-r--r--lib/Target/SystemZ/AsmPrinter/Makefile1
-rw-r--r--lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp116
-rw-r--r--lib/Target/SystemZ/Makefile2
-rw-r--r--lib/Target/SystemZ/SystemZMCAsmInfo.cpp6
-rw-r--r--lib/Target/SystemZ/SystemZMCAsmInfo.h3
-rw-r--r--lib/Target/SystemZ/TargetInfo/Makefile1
-rw-r--r--lib/Target/TargetAsmLexer.cpp14
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp98
-rw-r--r--lib/Target/TargetMachine.cpp6
-rw-r--r--lib/Target/X86/AsmParser/CMakeLists.txt1
-rw-r--r--lib/Target/X86/AsmParser/Makefile1
-rw-r--r--lib/Target/X86/AsmParser/X86AsmLexer.cpp43
-rw-r--r--lib/Target/X86/AsmParser/X86AsmParser.cpp239
-rw-r--r--lib/Target/X86/AsmPrinter/Makefile1
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp7
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp314
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.h1
-rw-r--r--lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp6
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.cpp52
-rw-r--r--lib/Target/X86/Disassembler/Makefile1
-rw-r--r--lib/Target/X86/Makefile2
-rw-r--r--lib/Target/X86/TargetInfo/Makefile2
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.cpp11
-rw-r--r--lib/Target/X86/X86COFFMachineModuleInfo.h4
-rw-r--r--lib/Target/X86/X86FastISel.cpp4
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp17
-rw-r--r--lib/Target/X86/X86Instr64bit.td2
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp146
-rw-r--r--lib/Target/X86/X86InstrInfo.h20
-rw-r--r--lib/Target/X86/X86MCAsmInfo.cpp9
-rw-r--r--lib/Target/X86/X86MCAsmInfo.h1
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp21
-rw-r--r--lib/Target/X86/X86RegisterInfo.h2
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp32
-rw-r--r--lib/Target/X86/X86TargetMachine.h12
-rw-r--r--lib/Target/X86/X86TargetObjectFile.cpp7
-rw-r--r--lib/Target/XCore/AsmPrinter/Makefile1
-rw-r--r--lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp105
-rw-r--r--lib/Target/XCore/Makefile2
-rw-r--r--lib/Target/XCore/TargetInfo/Makefile2
138 files changed, 2908 insertions, 2636 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 969c4a4..fd46a4a 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -715,7 +715,7 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
RC == ARM::QPR_VFP2RegisterClass) && "Unknown regclass!");
// FIXME: Neon instructions should support predicates
if (Align >= 16
- && (getRegisterInfo().needsStackRealignment(MF))) {
+ && (getRegisterInfo().canRealignStack(MF))) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64))
.addFrameIndex(FI).addImm(0).addImm(0).addImm(128)
.addMemOperand(MMO)
@@ -760,7 +760,7 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
RC == ARM::QPR_VFP2RegisterClass ||
RC == ARM::QPR_8RegisterClass) && "Unknown regclass!");
if (Align >= 16
- && (getRegisterInfo().needsStackRealignment(MF))) {
+ && (getRegisterInfo().canRealignStack(MF))) {
AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64), DestReg)
.addFrameIndex(FI).addImm(0).addImm(0).addImm(128)
.addMemOperand(MMO));
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index f1b6e1d..ba9e044 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -484,6 +484,14 @@ bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
MFI->isFrameAddressTaken());
}
+bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+ const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+ return (RealignStack &&
+ !AFI->isThumb1OnlyFunction() &&
+ !MFI->hasVarSizedObjects());
+}
+
bool ARMBaseRegisterInfo::
needsStackRealignment(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h
index 2788d07..f5ca25c 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -96,6 +96,7 @@ public:
bool hasFP(const MachineFunction &MF) const;
+ bool canRealignStack(const MachineFunction &MF) const;
bool needsStackRealignment(const MachineFunction &MF) const;
bool cannotEliminateFrame(const MachineFunction &MF) const;
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 14a45b3..a260050 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -1296,12 +1296,12 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
Ops.push_back(Chain);
if (!IsLoad)
- return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+7);
+ return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+8);
std::vector<EVT> ResTys(NumVecs, RegVT);
ResTys.push_back(MVT::Other);
SDNode *VLdLn =
- CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+7);
+ CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+8);
// For a 64-bit vector load to D registers, nothing more needs to be done.
if (is64BitVector)
return VLdLn;
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 7b62c00..76c6a27 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -340,7 +340,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
// ARM does not have ROTL.
setOperationAction(ISD::ROTL, MVT::i32, Expand);
- setOperationAction(ISD::CTTZ, MVT::i32, Expand);
+ setOperationAction(ISD::CTTZ, MVT::i32, Custom);
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
if (!Subtarget->hasV5TOps() || Subtarget->isThumb1Only())
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
@@ -387,7 +387,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only())
- // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR iff target supports vfp2.
+ // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
+ // iff target supports vfp2.
setOperationAction(ISD::BIT_CONVERT, MVT::i64, Custom);
// We want to custom lower some of our intrinsics.
@@ -482,6 +483,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::CMOV: return "ARMISD::CMOV";
case ARMISD::CNEG: return "ARMISD::CNEG";
+ case ARMISD::RBIT: return "ARMISD::RBIT";
+
case ARMISD::FTOSI: return "ARMISD::FTOSI";
case ARMISD::FTOUI: return "ARMISD::FTOUI";
case ARMISD::SITOF: return "ARMISD::SITOF";
@@ -2231,6 +2234,18 @@ SDValue ARMTargetLowering::LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) {
return DAG.getMergeValues(Ops, 2, dl);
}
+static SDValue LowerCTTZ(SDNode *N, SelectionDAG &DAG,
+ const ARMSubtarget *ST) {
+ EVT VT = N->getValueType(0);
+ DebugLoc dl = N->getDebugLoc();
+
+ if (!ST->hasV6T2Ops())
+ return SDValue();
+
+ SDValue rbit = DAG.getNode(ARMISD::RBIT, dl, VT, N->getOperand(0));
+ return DAG.getNode(ISD::CTLZ, dl, VT, rbit);
+}
+
static SDValue LowerShift(SDNode *N, SelectionDAG &DAG,
const ARMSubtarget *ST) {
EVT VT = N->getValueType(0);
@@ -3016,6 +3031,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG);
case ISD::SRL_PARTS:
case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG);
+ case ISD::CTTZ: return LowerCTTZ(Op.getNode(), DAG, Subtarget);
case ISD::VSETCC: return LowerVSETCC(Op, DAG);
case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG);
case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
@@ -3516,7 +3532,8 @@ static SDValue PerformSUBCombine(SDNode *N,
return SDValue();
}
-/// PerformVMOVRRDCombine - Target-specific dag combine xforms for ARMISD::VMOVRRD.
+/// PerformVMOVRRDCombine - Target-specific dag combine xforms for
+/// ARMISD::VMOVRRD.
static SDValue PerformVMOVRRDCombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI) {
// fmrrd(fmdrr x, y) -> x,y
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index e1b3348..cd9c027 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -53,6 +53,8 @@ namespace llvm {
CMOV, // ARM conditional move instructions.
CNEG, // ARM conditional negate instructions.
+ RBIT, // ARM bitreverse instruction
+
FTOSI, // FP to sint within a FP register.
FTOUI, // FP to uint within a FP register.
SITOF, // sint to FP within a FP register.
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index f67e74a..af508ee 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -107,6 +107,8 @@ def ARMMemBarrierV6 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6,
def ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6,
[SDNPHasChain]>;
+def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>;
+
//===----------------------------------------------------------------------===//
// ARM Instruction Predicate Definitions.
//
@@ -1455,6 +1457,15 @@ def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
let Inst{19-16} = 0b1111;
}
+def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
+ "rbit", "\t$dst, $src",
+ [(set GPR:$dst, (ARMrbit GPR:$src))]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{7-4} = 0b0011;
+ let Inst{11-8} = 0b1111;
+ let Inst{19-16} = 0b1111;
+}
+
def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
"rev", "\t$dst, $src",
[(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
@@ -1528,8 +1539,10 @@ def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
defm CMP : AI1_cmp_irs<0b1010, "cmp",
BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
-defm CMN : AI1_cmp_irs<0b1011, "cmn",
- BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
+//FIXME: Disable CMN, as CCodes are backwards from compare expectations
+// Compare-to-zero still works out, just not the relationals
+//defm CMN : AI1_cmp_irs<0b1011, "cmn",
+// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
// Note that TST/TEQ don't set all the same flags that CMP does!
defm TST : AI1_cmp_irs<0b1000, "tst",
@@ -1542,11 +1555,11 @@ defm CMPz : AI1_cmp_irs<0b1010, "cmp",
defm CMNz : AI1_cmp_irs<0b1011, "cmn",
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
-def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
- (CMNri GPR:$src, so_imm_neg:$imm)>;
+//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
+// (CMNri GPR:$src, so_imm_neg:$imm)>;
def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
- (CMNri GPR:$src, so_imm_neg:$imm)>;
+ (CMNzri GPR:$src, so_imm_neg:$imm)>;
// Conditional moves
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td
index 61b7705..cd063bf 100644
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -197,12 +197,12 @@ let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
class VLD2D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b1000,op7_4, (outs DPR:$dst1, DPR:$dst2),
(ins addrmode6:$addr), IIC_VLD2,
- OpcodeStr, Dt, "\\{$dst1,$dst2\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$dst1, $dst2\\}, $addr", "", []>;
class VLD2Q<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0011,op7_4,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
(ins addrmode6:$addr), IIC_VLD2,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3,$dst4\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
"", []>;
def VLD2d8 : VLD2D<0b0000, "vld2", "8">;
@@ -210,7 +210,7 @@ def VLD2d16 : VLD2D<0b0100, "vld2", "16">;
def VLD2d32 : VLD2D<0b1000, "vld2", "32">;
def VLD2d64 : NLdSt<0,0b10,0b1010,0b1100, (outs DPR:$dst1, DPR:$dst2),
(ins addrmode6:$addr), IIC_VLD1,
- "vld1", "64", "\\{$dst1,$dst2\\}, $addr", "", []>;
+ "vld1", "64", "\\{$dst1, $dst2\\}, $addr", "", []>;
def VLD2q8 : VLD2Q<0b0000, "vld2", "8">;
def VLD2q16 : VLD2Q<0b0100, "vld2", "16">;
@@ -220,11 +220,11 @@ def VLD2q32 : VLD2Q<0b1000, "vld2", "32">;
class VLD3D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0100,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
(ins addrmode6:$addr), IIC_VLD3,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3\\}, $addr", "", []>;
class VLD3WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0101,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, GPR:$wb),
(ins addrmode6:$addr), IIC_VLD3,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3\\}, $addr",
"$addr.addr = $wb", []>;
def VLD3d8 : VLD3D<0b0000, "vld3", "8">;
@@ -233,7 +233,7 @@ def VLD3d32 : VLD3D<0b1000, "vld3", "32">;
def VLD3d64 : NLdSt<0,0b10,0b0110,0b1100,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3),
(ins addrmode6:$addr), IIC_VLD1,
- "vld1", "64", "\\{$dst1,$dst2,$dst3\\}, $addr", "", []>;
+ "vld1", "64", "\\{$dst1, $dst2, $dst3\\}, $addr", "", []>;
// vld3 to double-spaced even registers.
def VLD3q8a : VLD3WB<0b0000, "vld3", "8">;
@@ -250,13 +250,13 @@ class VLD4D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0000,op7_4,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
(ins addrmode6:$addr), IIC_VLD4,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3,$dst4\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
"", []>;
class VLD4WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b10,0b0001,op7_4,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb),
(ins addrmode6:$addr), IIC_VLD4,
- OpcodeStr, Dt, "\\{$dst1,$dst2,$dst3,$dst4\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
"$addr.addr = $wb", []>;
def VLD4d8 : VLD4D<0b0000, "vld4", "8">;
@@ -265,7 +265,8 @@ def VLD4d32 : VLD4D<0b1000, "vld4", "32">;
def VLD4d64 : NLdSt<0,0b10,0b0010,0b1100,
(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
(ins addrmode6:$addr), IIC_VLD1,
- "vld1", "64", "\\{$dst1,$dst2,$dst3,$dst4\\}, $addr", "", []>;
+ "vld1", "64", "\\{$dst1, $dst2, $dst3, $dst4\\}, $addr",
+ "", []>;
// vld4 to double-spaced even registers.
def VLD4q8a : VLD4WB<0b0000, "vld4", "8">;
@@ -285,7 +286,7 @@ class VLD2LN<bits<4> op11_8, string OpcodeStr, string Dt>
: NLdSt<1,0b10,op11_8,{?,?,?,?}, (outs DPR:$dst1, DPR:$dst2),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, nohash_imm:$lane),
IIC_VLD2,
- OpcodeStr, Dt, "\\{$dst1[$lane],$dst2[$lane]\\}, $addr",
+ OpcodeStr, Dt, "\\{$dst1[$lane], $dst2[$lane]\\}, $addr",
"$src1 = $dst1, $src2 = $dst2", []>;
// vld2 to single-spaced registers.
@@ -319,7 +320,7 @@ class VLD3LN<bits<4> op11_8, string OpcodeStr, string Dt>
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
nohash_imm:$lane), IIC_VLD3,
OpcodeStr, Dt,
- "\\{$dst1[$lane],$dst2[$lane],$dst3[$lane]\\}, $addr",
+ "\\{$dst1[$lane], $dst2[$lane], $dst3[$lane]\\}, $addr",
"$src1 = $dst1, $src2 = $dst2, $src3 = $dst3", []>;
// vld3 to single-spaced registers.
@@ -356,7 +357,7 @@ class VLD4LN<bits<4> op11_8, string OpcodeStr, string Dt>
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
nohash_imm:$lane), IIC_VLD4,
OpcodeStr, Dt,
- "\\{$dst1[$lane],$dst2[$lane],$dst3[$lane],$dst4[$lane]\\}, $addr",
+ "\\{$dst1[$lane], $dst2[$lane], $dst3[$lane], $dst4[$lane]\\}, $addr",
"$src1 = $dst1, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []>;
// vld4 to single-spaced registers.
@@ -423,12 +424,12 @@ let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
class VST2D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b1000,op7_4, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$src1, $src2\\}, $addr", "", []>;
class VST2Q<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0011,op7_4, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3,$src4\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
"", []>;
def VST2d8 : VST2D<0b0000, "vst2", "8">;
@@ -436,7 +437,7 @@ def VST2d16 : VST2D<0b0100, "vst2", "16">;
def VST2d32 : VST2D<0b1000, "vst2", "32">;
def VST2d64 : NLdSt<0,0b00,0b1010,0b1100, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST,
- "vst1", "64", "\\{$src1,$src2\\}, $addr", "", []>;
+ "vst1", "64", "\\{$src1, $src2\\}, $addr", "", []>;
def VST2q8 : VST2Q<0b0000, "vst2", "8">;
def VST2q16 : VST2Q<0b0100, "vst2", "16">;
@@ -446,11 +447,11 @@ def VST2q32 : VST2Q<0b1000, "vst2", "32">;
class VST3D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0100,op7_4, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3\\}, $addr", "", []>;
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3\\}, $addr", "", []>;
class VST3WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0101,op7_4, (outs GPR:$wb),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3\\}, $addr",
"$addr.addr = $wb", []>;
def VST3d8 : VST3D<0b0000, "vst3", "8">;
@@ -459,7 +460,7 @@ def VST3d32 : VST3D<0b1000, "vst3", "32">;
def VST3d64 : NLdSt<0,0b00,0b0110,0b1100, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3),
IIC_VST,
- "vst1", "64", "\\{$src1,$src2,$src3\\}, $addr", "", []>;
+ "vst1", "64", "\\{$src1, $src2, $src3\\}, $addr", "", []>;
// vst3 to double-spaced even registers.
def VST3q8a : VST3WB<0b0000, "vst3", "8">;
@@ -476,13 +477,13 @@ class VST4D<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0000,op7_4, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3,$src4\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
"", []>;
class VST4WB<bits<4> op7_4, string OpcodeStr, string Dt>
: NLdSt<0,0b00,0b0001,op7_4, (outs GPR:$wb),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4),
IIC_VST,
- OpcodeStr, Dt, "\\{$src1,$src2,$src3,$src4\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1, $src2, $src3, $src4\\}, $addr",
"$addr.addr = $wb", []>;
def VST4d8 : VST4D<0b0000, "vst4", "8">;
@@ -491,7 +492,8 @@ def VST4d32 : VST4D<0b1000, "vst4", "32">;
def VST4d64 : NLdSt<0,0b00,0b0010,0b1100, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
DPR:$src4), IIC_VST,
- "vst1", "64", "\\{$src1,$src2,$src3,$src4\\}, $addr", "", []>;
+ "vst1", "64", "\\{$src1, $src2, $src3, $src4\\}, $addr",
+ "", []>;
// vst4 to double-spaced even registers.
def VST4q8a : VST4WB<0b0000, "vst4", "8">;
@@ -511,7 +513,7 @@ class VST2LN<bits<4> op11_8, string OpcodeStr, string Dt>
: NLdSt<1,0b00,op11_8,{?,?,?,?}, (outs),
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, nohash_imm:$lane),
IIC_VST,
- OpcodeStr, Dt, "\\{$src1[$lane],$src2[$lane]\\}, $addr",
+ OpcodeStr, Dt, "\\{$src1[$lane], $src2[$lane]\\}, $addr",
"", []>;
// vst2 to single-spaced registers.
@@ -545,7 +547,7 @@ class VST3LN<bits<4> op11_8, string OpcodeStr, string Dt>
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3,
nohash_imm:$lane), IIC_VST,
OpcodeStr, Dt,
- "\\{$src1[$lane],$src2[$lane],$src3[$lane]\\}, $addr", "", []>;
+ "\\{$src1[$lane], $src2[$lane], $src3[$lane]\\}, $addr", "", []>;
// vst3 to single-spaced registers.
def VST3LNd8 : VST3LN<0b0010, "vst3", "8"> {
@@ -580,7 +582,7 @@ class VST4LN<bits<4> op11_8, string OpcodeStr, string Dt>
(ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4,
nohash_imm:$lane), IIC_VST,
OpcodeStr, Dt,
- "\\{$src1[$lane],$src2[$lane],$src3[$lane],$src4[$lane]\\}, $addr",
+ "\\{$src1[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $addr",
"", []>;
// vst4 to single-spaced registers.
@@ -2116,7 +2118,7 @@ def VACGTq : N3VQInt<1, 0, 0b10, 0b1110, 1, IIC_VBINQ, "vacgt", "f32",
v4i32, v4f32, int_arm_neon_vacgtq, 0>;
// VTST : Vector Test Bits
defm VTST : N3V_QHS<0, 0, 0b1000, 1, IIC_VBINi4D, IIC_VBINi4D, IIC_VBINi4Q,
- IIC_VBINi4Q, "vtst", "i", NEONvtst, 1>;
+ IIC_VBINi4Q, "vtst", "", NEONvtst, 1>;
// Vector Bitwise Operations.
@@ -3022,19 +3024,19 @@ let hasExtraSrcRegAllocReq = 1 in {
def VTBL2
: N3V<1,1,0b11,0b1001,0,0, (outs DPR:$dst),
(ins DPR:$tbl1, DPR:$tbl2, DPR:$src), IIC_VTB2,
- "vtbl", "8", "$dst, \\{$tbl1,$tbl2\\}, $src", "",
+ "vtbl", "8", "$dst, \\{$tbl1, $tbl2\\}, $src", "",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbl2
DPR:$tbl1, DPR:$tbl2, DPR:$src)))]>;
def VTBL3
: N3V<1,1,0b11,0b1010,0,0, (outs DPR:$dst),
(ins DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src), IIC_VTB3,
- "vtbl", "8", "$dst, \\{$tbl1,$tbl2,$tbl3\\}, $src", "",
+ "vtbl", "8", "$dst, \\{$tbl1, $tbl2, $tbl3\\}, $src", "",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbl3
DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src)))]>;
def VTBL4
: N3V<1,1,0b11,0b1011,0,0, (outs DPR:$dst),
(ins DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src), IIC_VTB4,
- "vtbl", "8", "$dst, \\{$tbl1,$tbl2,$tbl3,$tbl4\\}, $src", "",
+ "vtbl", "8", "$dst, \\{$tbl1, $tbl2, $tbl3, $tbl4\\}, $src", "",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbl4 DPR:$tbl1, DPR:$tbl2,
DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>;
} // hasExtraSrcRegAllocReq = 1
@@ -3050,19 +3052,20 @@ let hasExtraSrcRegAllocReq = 1 in {
def VTBX2
: N3V<1,1,0b11,0b1001,1,0, (outs DPR:$dst),
(ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src), IIC_VTBX2,
- "vtbx", "8", "$dst, \\{$tbl1,$tbl2\\}, $src", "$orig = $dst",
+ "vtbx", "8", "$dst, \\{$tbl1, $tbl2\\}, $src", "$orig = $dst",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbx2
DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src)))]>;
def VTBX3
: N3V<1,1,0b11,0b1010,1,0, (outs DPR:$dst),
(ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src), IIC_VTBX3,
- "vtbx", "8", "$dst, \\{$tbl1,$tbl2,$tbl3\\}, $src", "$orig = $dst",
+ "vtbx", "8", "$dst, \\{$tbl1, $tbl2, $tbl3\\}, $src", "$orig = $dst",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbx3 DPR:$orig, DPR:$tbl1,
DPR:$tbl2, DPR:$tbl3, DPR:$src)))]>;
def VTBX4
: N3V<1,1,0b11,0b1011,1,0, (outs DPR:$dst), (ins DPR:$orig, DPR:$tbl1,
DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src), IIC_VTBX4,
- "vtbx", "8", "$dst, \\{$tbl1,$tbl2,$tbl3,$tbl4\\}, $src", "$orig = $dst",
+ "vtbx", "8", "$dst, \\{$tbl1, $tbl2, $tbl3, $tbl4\\}, $src",
+ "$orig = $dst",
[(set DPR:$dst, (v8i8 (int_arm_neon_vtbx4 DPR:$orig, DPR:$tbl1,
DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>;
} // hasExtraSrcRegAllocReq = 1
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index 603ccf5..746caff 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -208,7 +208,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst",
[(brind GPR:$dst)]>,
- T1Special<{1,0,1,1}> {
+ T1Special<{1,0,1,?}> {
// <Rd> = Inst{7:2-0} = pc
let Inst{2-0} = 0b111;
}
@@ -534,10 +534,12 @@ def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
// CMN register
let Defs = [CPSR] in {
-def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
- "cmn", "\t$lhs, $rhs",
- [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>,
- T1DataProcessing<0b1011>;
+//FIXME: Disable CMN, as CCodes are backwards from compare expectations
+// Compare-to-zero still works out, just not the relationals
+//def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
+// "cmn", "\t$lhs, $rhs",
+// [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>,
+// T1DataProcessing<0b1011>;
def tCMNz : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
"cmn", "\t$lhs, $rhs",
[(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>,
@@ -630,13 +632,13 @@ def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
// FIXME: Make these predicable.
def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr,
"mov\t$dst, $src", []>,
- T1Special<{1,0,0,1}>;
+ T1Special<{1,0,0,?}>;
def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr,
"mov\t$dst, $src", []>,
- T1Special<{1,0,1,0}>;
+ T1Special<{1,0,?,0}>;
def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
"mov\t$dst, $src", []>,
- T1Special<{1,0,1,1}>;
+ T1Special<{1,0,?,?}>;
} // neverHasSideEffects
// multiply register
@@ -771,7 +773,7 @@ let usesCustomInserter = 1 in // Expanded after instruction selection.
// 16-bit movcc in IT blocks for Thumb2.
def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr,
"mov", "\t$dst, $rhs", []>,
- T1Special<{1,0,1,1}>;
+ T1Special<{1,0,?,?}>;
def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi,
"mov", "\t$dst, $rhs", []>,
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 769df7e..c7591d2 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -1540,6 +1540,10 @@ class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops, InstrItinClass itin
def t2CLZ : T2I_misc<0b11, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
"clz", "\t$dst, $src", [(set GPR:$dst, (ctlz GPR:$src))]>;
+def t2RBIT : T2I_misc<0b01, 0b10, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
+ "rbit", "\t$dst, $src",
+ [(set GPR:$dst, (ARMrbit GPR:$src))]>;
+
def t2REV : T2I_misc<0b01, 0b00, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
"rev", ".w\t$dst, $src", [(set GPR:$dst, (bswap GPR:$src))]>;
@@ -1605,16 +1609,18 @@ defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
-defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
- BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
+//FIXME: Disable CMN, as CCodes are backwards from compare expectations
+// Compare-to-zero still works out, just not the relationals
+//defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
+// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
-def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
- (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
+//def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
+// (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
- (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
+ (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
defm t2TST : T2I_cmp_irs<0b0000, "tst",
BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
diff --git a/lib/Target/ARM/ARMMCAsmInfo.cpp b/lib/Target/ARM/ARMMCAsmInfo.cpp
index 0ff65d2..3dd87c0 100644
--- a/lib/Target/ARM/ARMMCAsmInfo.cpp
+++ b/lib/Target/ARM/ARMMCAsmInfo.cpp
@@ -64,7 +64,7 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo() {
PrivateGlobalPrefix = ".L";
WeakRefDirective = "\t.weak\t";
SetDirective = "\t.set\t";
- LCOMMDirective = "\t.lcomm\t";
+ HasLCOMMDirective = true;
DwarfRequiresFrameSection = false;
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
index 1c6fca7..4d20a5c 100644
--- a/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -93,10 +93,6 @@ bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM,
if (Subtarget.hasNEON())
PM.add(createNEONPreAllocPass());
- // Calculate and set max stack object alignment early, so we can decide
- // whether we will need stack realignment (and thus FP).
- PM.add(createMaxStackAlignmentCalculatorPass());
-
// FIXME: temporarily disabling load / store optimization pass for Thumb1.
if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
PM.add(createARMLoadStoreOptimizationPass(true));
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 132738e..89c7769 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -8,18 +8,18 @@
//===----------------------------------------------------------------------===//
#include "ARM.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAsmLexer.h"
-#include "llvm/MC/MCAsmParser.h"
-#include "llvm/MC/MCParsedAsmOperand.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/SourceMgr.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
using namespace llvm;
namespace {
@@ -222,7 +222,7 @@ struct ARMOperand : public MCParsedAsmOperand {
/// TODO this is likely to change to allow different register types and or to
/// parse for a specific register type.
bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
// FIXME: Validate register for the current architecture; we have to do
@@ -232,14 +232,14 @@ bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) {
RegNum = MatchRegisterName(Tok.getString());
if (RegNum == -1)
return true;
- getLexer().Lex(); // Eat identifier token.
+ Parser.Lex(); // Eat identifier token.
bool Writeback = false;
if (ParseWriteBack) {
- const AsmToken &ExclaimTok = getLexer().getTok();
+ const AsmToken &ExclaimTok = Parser.getTok();
if (ExclaimTok.is(AsmToken::Exclaim)) {
Writeback = true;
- getLexer().Lex(); // Eat exclaim token
+ Parser.Lex(); // Eat exclaim token
}
}
@@ -251,26 +251,26 @@ bool ARMAsmParser::MaybeParseRegister(ARMOperand &Op, bool ParseWriteBack) {
/// Parse a register list, return false if successful else return true or an
/// error. The first token must be a '{' when called.
bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
- assert(getLexer().getTok().is(AsmToken::LCurly) &&
+ assert(Parser.getTok().is(AsmToken::LCurly) &&
"Token is not an Left Curly Brace");
- getLexer().Lex(); // Eat left curly brace token.
+ Parser.Lex(); // Eat left curly brace token.
- const AsmToken &RegTok = getLexer().getTok();
+ const AsmToken &RegTok = Parser.getTok();
SMLoc RegLoc = RegTok.getLoc();
if (RegTok.isNot(AsmToken::Identifier))
return Error(RegLoc, "register expected");
int RegNum = MatchRegisterName(RegTok.getString());
if (RegNum == -1)
return Error(RegLoc, "register expected");
- getLexer().Lex(); // Eat identifier token.
+ Parser.Lex(); // Eat identifier token.
unsigned RegList = 1 << RegNum;
int HighRegNum = RegNum;
// TODO ranges like "{Rn-Rm}"
- while (getLexer().getTok().is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat comma token.
+ while (Parser.getTok().is(AsmToken::Comma)) {
+ Parser.Lex(); // Eat comma token.
- const AsmToken &RegTok = getLexer().getTok();
+ const AsmToken &RegTok = Parser.getTok();
SMLoc RegLoc = RegTok.getLoc();
if (RegTok.isNot(AsmToken::Identifier))
return Error(RegLoc, "register expected");
@@ -285,12 +285,12 @@ bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
RegList |= 1 << RegNum;
HighRegNum = RegNum;
- getLexer().Lex(); // Eat identifier token.
+ Parser.Lex(); // Eat identifier token.
}
- const AsmToken &RCurlyTok = getLexer().getTok();
+ const AsmToken &RCurlyTok = Parser.getTok();
if (RCurlyTok.isNot(AsmToken::RCurly))
return Error(RCurlyTok.getLoc(), "'}' expected");
- getLexer().Lex(); // Eat left curly brace token.
+ Parser.Lex(); // Eat left curly brace token.
return false;
}
@@ -300,11 +300,11 @@ bool ARMAsmParser::ParseRegisterList(ARMOperand &Op) {
/// TODO Only preindexing and postindexing addressing are started, unindexed
/// with option, etc are still to do.
bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
- assert(getLexer().getTok().is(AsmToken::LBrac) &&
+ assert(Parser.getTok().is(AsmToken::LBrac) &&
"Token is not an Left Bracket");
- getLexer().Lex(); // Eat left bracket token.
+ Parser.Lex(); // Eat left bracket token.
- const AsmToken &BaseRegTok = getLexer().getTok();
+ const AsmToken &BaseRegTok = Parser.getTok();
if (BaseRegTok.isNot(AsmToken::Identifier))
return Error(BaseRegTok.getLoc(), "register expected");
if (MaybeParseRegister(Op, false))
@@ -319,10 +319,10 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
// First look for preindexed address forms, that is after the "[Rn" we now
// have to see if the next token is a comma.
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.is(AsmToken::Comma)) {
Preindexed = true;
- getLexer().Lex(); // Eat comma token.
+ Parser.Lex(); // Eat comma token.
int OffsetRegNum;
bool OffsetRegShifted;
enum ShiftType ShiftType;
@@ -331,15 +331,15 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
Offset, OffsetIsReg, OffsetRegNum))
return true;
- const AsmToken &RBracTok = getLexer().getTok();
+ const AsmToken &RBracTok = Parser.getTok();
if (RBracTok.isNot(AsmToken::RBrac))
return Error(RBracTok.getLoc(), "']' expected");
- getLexer().Lex(); // Eat right bracket token.
+ Parser.Lex(); // Eat right bracket token.
- const AsmToken &ExclaimTok = getLexer().getTok();
+ const AsmToken &ExclaimTok = Parser.getTok();
if (ExclaimTok.is(AsmToken::Exclaim)) {
Writeback = true;
- getLexer().Lex(); // Eat exclaim token
+ Parser.Lex(); // Eat exclaim token
}
Op = ARMOperand::CreateMem(BaseRegNum, OffsetIsReg, Offset, OffsetRegNum,
OffsetRegShifted, ShiftType, ShiftAmount,
@@ -352,7 +352,7 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
// the "[Rn".
Postindexed = true;
Writeback = true;
- getLexer().Lex(); // Eat right bracket token.
+ Parser.Lex(); // Eat right bracket token.
int OffsetRegNum = 0;
bool OffsetRegShifted = false;
@@ -360,11 +360,11 @@ bool ARMAsmParser::ParseMemory(ARMOperand &Op) {
const MCExpr *ShiftAmount;
const MCExpr *Offset;
- const AsmToken &NextTok = getLexer().getTok();
+ const AsmToken &NextTok = Parser.getTok();
if (NextTok.isNot(AsmToken::EndOfStatement)) {
if (NextTok.isNot(AsmToken::Comma))
return Error(NextTok.getLoc(), "',' expected");
- getLexer().Lex(); // Eat comma token.
+ Parser.Lex(); // Eat comma token.
if(ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType,
ShiftAmount, Offset, OffsetIsReg, OffsetRegNum))
return true;
@@ -398,15 +398,15 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
OffsetRegShifted = false;
OffsetIsReg = false;
OffsetRegNum = -1;
- const AsmToken &NextTok = getLexer().getTok();
+ const AsmToken &NextTok = Parser.getTok();
if (NextTok.is(AsmToken::Plus))
- getLexer().Lex(); // Eat plus token.
+ Parser.Lex(); // Eat plus token.
else if (NextTok.is(AsmToken::Minus)) {
Negative = true;
- getLexer().Lex(); // Eat minus token
+ Parser.Lex(); // Eat minus token
}
// See if there is a register following the "[Rn," or "[Rn]," we have so far.
- const AsmToken &OffsetRegTok = getLexer().getTok();
+ const AsmToken &OffsetRegTok = Parser.getTok();
if (OffsetRegTok.is(AsmToken::Identifier)) {
OffsetIsReg = !MaybeParseRegister(Op, false);
if (OffsetIsReg)
@@ -415,11 +415,11 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
// If we parsed a register as the offset then their can be a shift after that
if (OffsetRegNum != -1) {
// Look for a comma then a shift
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat comma token.
+ Parser.Lex(); // Eat comma token.
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (ParseShift(ShiftType, ShiftAmount))
return Error(Tok.getLoc(), "shift expected");
OffsetRegShifted = true;
@@ -427,10 +427,10 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
}
else { // the "[Rn," or "[Rn,]" we have so far was not followed by "Rm"
// Look for #offset following the "[Rn," or "[Rn],"
- const AsmToken &HashTok = getLexer().getTok();
+ const AsmToken &HashTok = Parser.getTok();
if (HashTok.isNot(AsmToken::Hash))
return Error(HashTok.getLoc(), "'#' expected");
- getLexer().Lex(); // Eat hash token.
+ Parser.Lex(); // Eat hash token.
if (getParser().ParseExpression(Offset))
return true;
@@ -443,7 +443,7 @@ bool ARMAsmParser::ParseMemoryOffsetReg(bool &Negative,
/// rrx
/// and returns true if it parses a shift otherwise it returns false.
bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
return true;
const StringRef &ShiftName = Tok.getString();
@@ -459,17 +459,17 @@ bool ARMAsmParser::ParseShift(ShiftType &St, const MCExpr *&ShiftAmount) {
St = Rrx;
else
return true;
- getLexer().Lex(); // Eat shift type token.
+ Parser.Lex(); // Eat shift type token.
// Rrx stands alone.
if (St == Rrx)
return false;
// Otherwise, there must be a '#' and a shift amount.
- const AsmToken &HashTok = getLexer().getTok();
+ const AsmToken &HashTok = Parser.getTok();
if (HashTok.isNot(AsmToken::Hash))
return Error(HashTok.getLoc(), "'#' expected");
- getLexer().Lex(); // Eat hash token.
+ Parser.Lex(); // Eat hash token.
if (getParser().ParseExpression(ShiftAmount))
return true;
@@ -569,14 +569,14 @@ bool ARMAsmParser::ParseOperand(ARMOperand &Op) {
case AsmToken::Hash:
// #42 -> immediate.
// TODO: ":lower16:" and ":upper16:" modifiers after # before immediate
- getLexer().Lex();
+ Parser.Lex();
const MCExpr *ImmVal;
if (getParser().ParseExpression(ImmVal))
return true;
Op = ARMOperand::CreateImm(ImmVal);
return false;
default:
- return Error(getLexer().getTok().getLoc(), "unexpected token in operand");
+ return Error(Parser.getTok().getLoc(), "unexpected token in operand");
}
}
@@ -585,7 +585,7 @@ bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Operands.push_back(new ARMOperand(ARMOperand::CreateToken(Name)));
- SMLoc Loc = getLexer().getTok().getLoc();
+ SMLoc Loc = Parser.getTok().getLoc();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Read the first operand.
@@ -594,7 +594,7 @@ bool ARMAsmParser::ParseInstruction(const StringRef &Name, SMLoc NameLoc,
Operands.push_back(new ARMOperand(Op));
while (getLexer().is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat the comma.
+ Parser.Lex(); // Eat the comma.
// Parse and remember the operand.
if (ParseOperand(Op)) return true;
@@ -629,7 +629,7 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
if (getParser().ParseExpression(Value))
return true;
- getParser().getStreamer().EmitValue(Value, Size);
+ getParser().getStreamer().EmitValue(Value, Size, 0/*addrspace*/);
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -637,11 +637,11 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
// FIXME: Improve diagnostic.
if (getLexer().isNot(AsmToken::Comma))
return Error(L, "unexpected token in directive");
- getLexer().Lex();
+ Parser.Lex();
}
}
- getLexer().Lex();
+ Parser.Lex();
return false;
}
@@ -650,7 +650,7 @@ bool ARMAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(L, "unexpected token in directive");
- getLexer().Lex();
+ Parser.Lex();
// TODO: set thumb mode
// TODO: tell the MC streamer the mode
@@ -661,15 +661,15 @@ bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
/// ParseDirectiveThumbFunc
/// ::= .thumbfunc symbol_name
bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
return Error(L, "unexpected token in .syntax directive");
- StringRef ATTRIBUTE_UNUSED SymbolName = getLexer().getTok().getIdentifier();
- getLexer().Lex(); // Consume the identifier token.
+ StringRef ATTRIBUTE_UNUSED SymbolName = Parser.getTok().getIdentifier();
+ Parser.Lex(); // Consume the identifier token.
if (getLexer().isNot(AsmToken::EndOfStatement))
return Error(L, "unexpected token in directive");
- getLexer().Lex();
+ Parser.Lex();
// TODO: mark symbol as a thumb symbol
// getParser().getStreamer().Emit???();
@@ -679,25 +679,25 @@ bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
/// ParseDirectiveSyntax
/// ::= .syntax unified | divided
bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
return Error(L, "unexpected token in .syntax directive");
const StringRef &Mode = Tok.getString();
bool unified_syntax;
if (Mode == "unified" || Mode == "UNIFIED") {
- getLexer().Lex();
+ Parser.Lex();
unified_syntax = true;
}
else if (Mode == "divided" || Mode == "DIVIDED") {
- getLexer().Lex();
+ Parser.Lex();
unified_syntax = false;
}
else
return Error(L, "unrecognized syntax mode in .syntax directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(getLexer().getTok().getLoc(), "unexpected token in directive");
- getLexer().Lex();
+ return Error(Parser.getTok().getLoc(), "unexpected token in directive");
+ Parser.Lex();
// TODO tell the MC streamer the mode
// getParser().getStreamer().Emit???();
@@ -707,25 +707,25 @@ bool ARMAsmParser::ParseDirectiveSyntax(SMLoc L) {
/// ParseDirectiveCode
/// ::= .code 16 | 32
bool ARMAsmParser::ParseDirectiveCode(SMLoc L) {
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Integer))
return Error(L, "unexpected token in .code directive");
- int64_t Val = getLexer().getTok().getIntVal();
+ int64_t Val = Parser.getTok().getIntVal();
bool thumb_mode;
if (Val == 16) {
- getLexer().Lex();
+ Parser.Lex();
thumb_mode = true;
}
else if (Val == 32) {
- getLexer().Lex();
+ Parser.Lex();
thumb_mode = false;
}
else
return Error(L, "invalid operand to .code directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(getLexer().getTok().getLoc(), "unexpected token in directive");
- getLexer().Lex();
+ return Error(Parser.getTok().getLoc(), "unexpected token in directive");
+ Parser.Lex();
// TODO tell the MC streamer the mode
// getParser().getStreamer().Emit???();
diff --git a/lib/Target/ARM/AsmParser/Makefile b/lib/Target/ARM/AsmParser/Makefile
index 97e5612..4fb8564 100644
--- a/lib/Target/ARM/AsmParser/Makefile
+++ b/lib/Target/ARM/AsmParser/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMAsmParser
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' ARM target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 2d13533..e1f386e 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -49,7 +49,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include <cctype>
using namespace llvm;
@@ -160,7 +159,6 @@ namespace {
unsigned AsmVariant,
const char *ExtraCode);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void printInstruction(const MachineInstr *MI); // autogenerated.
static const char *getRegisterName(unsigned RegNo);
@@ -172,7 +170,12 @@ namespace {
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
/// the .s file.
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
- printDataDirective(MCPV->getType());
+ switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
+ case 1: O << MAI->getData8bitsDirective(0); break;
+ case 2: O << MAI->getData16bitsDirective(0); break;
+ case 4: O << MAI->getData32bitsDirective(0); break;
+ default: assert(0 && "Unknown CPV size");
+ }
ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
SmallString<128> TmpNameStr;
@@ -184,32 +187,27 @@ namespace {
} else if (ACPV->isBlockAddress()) {
O << GetBlockAddressSymbol(ACPV->getBlockAddress())->getName();
} else if (ACPV->isGlobalValue()) {
- std::string Name;
GlobalValue *GV = ACPV->getGV();
bool isIndirect = Subtarget->isTargetDarwin() &&
Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
if (!isIndirect)
- Name = Mang->getMangledName(GV);
+ O << *GetGlobalValueSymbol(GV);
else {
// FIXME: Remove this when Darwin transition to @GOT like syntax.
- Name = Mang->getMangledName(GV, "$non_lazy_ptr", true);
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(StringRef(Name));
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
+ O << *Sym;
MachineModuleInfoMachO &MMIMachO =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
const MCSymbol *&StubSym =
GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
MMIMachO.getGVStubEntry(Sym);
- if (StubSym == 0) {
- Mang->getNameWithPrefix(TmpNameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(TmpNameStr.str());
- }
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
}
- O << Name;
} else {
assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
- Mang->getNameWithPrefix(TmpNameStr, ACPV->getSymbol());
- OutContext.GetOrCreateSymbol(TmpNameStr.str())->print(O, MAI);
+ O << *GetExternalSymbolSymbol(ACPV->getSymbol());
}
if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
@@ -219,9 +217,9 @@ namespace {
<< "+" << (unsigned)ACPV->getPCAdjustment();
if (ACPV->mustAddCurrentAddress())
O << "-.";
- O << ")";
+ O << ')';
}
- O << "\n";
+ O << '\n';
}
void getAnalysisUsage(AnalysisUsage &AU) const {
@@ -262,7 +260,7 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::InternalLinkage:
break;
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << "\n";
+ O << "\t.globl\t" << *CurrentFnSym << "\n";
break;
case Function::LinkerPrivateLinkage:
case Function::WeakAnyLinkage:
@@ -270,15 +268,15 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
if (Subtarget->isTargetDarwin()) {
- O << "\t.globl\t" << CurrentFnName << "\n";
- O << "\t.weak_definition\t" << CurrentFnName << "\n";
+ O << "\t.globl\t" << *CurrentFnSym << "\n";
+ O << "\t.weak_definition\t" << *CurrentFnSym << "\n";
} else {
- O << MAI->getWeakRefDirective() << CurrentFnName << "\n";
+ O << MAI->getWeakRefDirective() << *CurrentFnSym << "\n";
}
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
unsigned FnAlign = 1 << MF.getAlignment(); // MF alignment is log2.
if (AFI->isThumbFunction()) {
@@ -286,13 +284,13 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
O << "\t.code\t16\n";
O << "\t.thumb_func";
if (Subtarget->isTargetDarwin())
- O << "\t" << CurrentFnName;
+ O << "\t" << *CurrentFnSym;
O << "\n";
} else {
EmitAlignment(FnAlign, F);
}
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
// Emit pre-function debug information.
DW->BeginFunction(&MF);
@@ -320,7 +318,7 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
+ O << "\t.size " << *CurrentFnSym << ", .-" << *CurrentFnSym << "\n";
// Emit post-function debug information.
DW->EndFunction(&MF);
@@ -369,7 +367,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
break;
}
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
@@ -381,7 +379,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
(TF & ARMII::MO_HI16))
O << ":upper16:";
- O << Mang->getMangledName(GV);
+ O << *GetGlobalValueSymbol(GV);
printOffset(MO.getOffset());
@@ -392,9 +390,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
}
case MachineOperand::MO_ExternalSymbol: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
- SmallString<128> NameStr;
- Mang->getNameWithPrefix(NameStr, MO.getSymbolName());
- OutContext.GetOrCreateSymbol(NameStr.str())->print(O, MAI);
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
if (isCallOp && Subtarget->isTargetELF() &&
TM.getRelocationModel() == Reloc::PIC_)
@@ -402,12 +398,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
break;
}
case MachineOperand::MO_ConstantPoolIndex:
- O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
- << '_' << MO.getIndex();
+ O << *GetCPISymbol(MO.getIndex());
break;
case MachineOperand::MO_JumpTableIndex:
- O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << MO.getIndex();
+ O << *GetJTISymbol(MO.getIndex());
break;
}
}
@@ -895,8 +889,7 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
// data itself.
if (!strcmp(Modifier, "label")) {
unsigned ID = MI->getOperand(OpNum).getImm();
- O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
- << '_' << ID << ":\n";
+ O << *GetCPISymbol(ID) << ":\n";
} else {
assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
unsigned CPI = MI->getOperand(OpNum).getIndex();
@@ -916,6 +909,7 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
+
unsigned JTI = MO1.getIndex();
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << JTI << '_' << MO2.getImm() << ":\n";
@@ -941,11 +935,11 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
<< '_' << JTI << '_' << MO2.getImm()
<< "_set_" << MBB->getNumber();
else if (TM.getRelocationModel() == Reloc::PIC_) {
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
- O << '-' << MAI->getPrivateGlobalPrefix() << "JTI"
+ O << *GetMBBSymbol(MBB->getNumber())
+ << '-' << MAI->getPrivateGlobalPrefix() << "JTI"
<< getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
} else {
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MBB->getNumber());
}
if (i != e-1)
O << '\n';
@@ -976,13 +970,11 @@ void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) {
else if (HalfWordOffset)
O << MAI->getData16bitsDirective();
if (ByteOffset || HalfWordOffset) {
- O << '(';
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << '(' << *GetMBBSymbol(MBB->getNumber());
O << "-" << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << JTI << '_' << MO2.getImm() << ")/2";
} else {
- O << "\tb.w ";
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << "\tb.w " << *GetMBBSymbol(MBB->getNumber());
}
if (i != e-1)
O << '\n';
@@ -1174,146 +1166,6 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
}
}
-void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer()) // External global require no code
- return;
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
-
- if (EmitSpecialLLVMGlobal(GVar)) {
- if (Subtarget->isTargetDarwin() &&
- TM.getRelocationModel() == Reloc::Static) {
- if (GVar->getName() == "llvm.global_ctors")
- O << ".reference .constructors_used\n";
- else if (GVar->getName() == "llvm.global_dtors")
- O << ".reference .destructors_used\n";
- }
- return;
- }
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
- bool isDarwin = Subtarget->isTargetDarwin();
-
- printVisibility(name, GVar->getVisibility());
-
- if (Subtarget->isTargetELF())
- O << "\t.type " << name << ",%object\n";
-
- const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
- // FIXME: get this stuff from section kind flags.
- if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
- // Don't put things that should go in the cstring section into "comm".
- !TheSection->getKind().isMergeableCString()) {
- if (GVar->hasExternalLinkage()) {
- if (const char *Directive = MAI->getZeroFillDirective()) {
- O << "\t.globl\t" << name << "\n";
- O << Directive << "__DATA, __common, " << name << ", "
- << Size << ", " << Align << "\n";
- return;
- }
- }
-
- if (GVar->hasLocalLinkage() || GVar->isWeakForLinker()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (isDarwin) {
- if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << "," << Size
- << ',' << Align;
- } else if (GVar->hasCommonLinkage()) {
- O << MAI->getCOMMDirective() << name << "," << Size
- << ',' << Align;
- } else {
- OutStreamer.SwitchSection(TheSection);
- O << "\t.globl " << name << '\n'
- << MAI->getWeakDefDirective() << name << '\n';
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- EmitGlobalConstant(C);
- return;
- }
- } else if (MAI->getLCOMMDirective() != NULL) {
- if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << "," << Size;
- } else {
- O << MAI->getCOMMDirective() << name << "," << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
- }
- } else {
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << "\n";
- O << MAI->getCOMMDirective() << name << "," << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
- }
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << "\n";
- return;
- }
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- if (isDarwin) {
- O << "\t.globl " << name << "\n"
- << "\t.weak_definition " << name << "\n";
- } else {
- O << "\t.weak " << name << "\n";
- }
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- O << "\t.globl " << name << "\n";
- break;
- case GlobalValue::PrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << "\n";
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size " << name << ", " << Size << "\n";
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetDarwin()) {
@@ -1333,10 +1185,8 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
EmitAlignment(2);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n\t.indirect_symbol ";
- Stubs[i].second->print(O, MAI);
- O << "\n\t.long\t0\n";
+ O << *Stubs[i].first << ":\n\t.indirect_symbol ";
+ O << *Stubs[i].second << "\n\t.long\t0\n";
}
}
@@ -1344,12 +1194,8 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
if (!Stubs.empty()) {
OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
EmitAlignment(2);
- for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n\t.long ";
- Stubs[i].second->print(O, MAI);
- O << "\n";
- }
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i)
+ O << *Stubs[i].first << ":\n\t.long " << *Stubs[i].second << "\n";
}
// Funny Darwin hack: This flag tells the linker that no global symbols
@@ -1357,7 +1203,7 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
// implementation of multiple entry points). If this doesn't occur, the
// linker can safely perform dead code stripping. Since LLVM never
// generates code that does this, it is always safe to set.
- OutStreamer.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
+ OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
}
}
@@ -1416,12 +1262,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
EmitAlignment(2);
-
- const char *Prefix = MAI->getPrivateGlobalPrefix();
- MCSymbol *Label = OutContext.GetOrCreateSymbol(Twine(Prefix)+"CPI"+
- Twine(getFunctionNumber())+
- "_"+ Twine(LabelId));
- OutStreamer.EmitLabel(Label);
+ OutStreamer.EmitLabel(GetCPISymbol(LabelId));
const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
if (MCPE.isMachineConstantPoolEntry())
diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
index 9fc57e0..6885ecb 100644
--- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
@@ -62,7 +62,7 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
} else {
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
assert(Op.isExpr() && "unknown operand kind in printOperand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
diff --git a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
index c49fee3..f843ee2 100644
--- a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp
@@ -22,7 +22,6 @@
#include "llvm/MC/MCInst.h"
//#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/SmallString.h"
using namespace llvm;
@@ -40,33 +39,24 @@ MachineModuleInfoMachO &ARMMCInstLower::getMachOMMI() const {
MCSymbol *ARMMCInstLower::
GetGlobalAddressSymbol(const MachineOperand &MO) const {
- const GlobalValue *GV = MO.getGlobal();
-
- SmallString<128> Name;
- Mang.getNameWithPrefix(Name, GV, false);
-
// FIXME: HANDLE PLT references how??
switch (MO.getTargetFlags()) {
default: assert(0 && "Unknown target flag on GV operand");
case 0: break;
}
- return Ctx.GetOrCreateSymbol(Name.str());
+ return Printer.GetGlobalValueSymbol(MO.getGlobal());
}
MCSymbol *ARMMCInstLower::
GetExternalSymbolSymbol(const MachineOperand &MO) const {
- SmallString<128> Name;
- Name += Printer.MAI->getGlobalPrefix();
- Name += MO.getSymbolName();
-
// FIXME: HANDLE PLT references how??
switch (MO.getTargetFlags()) {
default: assert(0 && "Unknown target flag on GV operand");
case 0: break;
}
- return Ctx.GetOrCreateSymbol(Name.str());
+ return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
}
diff --git a/lib/Target/ARM/AsmPrinter/Makefile b/lib/Target/ARM/AsmPrinter/Makefile
index 208becc..93b8fc9 100644
--- a/lib/Target/ARM/AsmPrinter/Makefile
+++ b/lib/Target/ARM/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' arm target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/ARM/Makefile b/lib/Target/ARM/Makefile
index a8dd38c..b766a86 100644
--- a/lib/Target/ARM/Makefile
+++ b/lib/Target/ARM/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMARMCodeGen
TARGET = ARM
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = ARMGenRegisterInfo.h.inc ARMGenRegisterNames.inc \
diff --git a/lib/Target/ARM/README.txt b/lib/Target/ARM/README.txt
index 11c48ad..a6f26a5 100644
--- a/lib/Target/ARM/README.txt
+++ b/lib/Target/ARM/README.txt
@@ -596,3 +596,12 @@ Make use of the "rbit" instruction.
Take a look at test/CodeGen/Thumb2/machine-licm.ll. ARM should be taught how
to licm and cse the unnecessary load from cp#1.
+
+//===---------------------------------------------------------------------===//
+
+The CMN instruction sets the flags like an ADD instruction, while CMP sets
+them like a subtract. Therefore to be able to use CMN for comparisons other
+than the Z bit, we'll need additional logic to reverse the conditionals
+associated with the comparison. Perhaps a pseudo-instruction for the comparison,
+with a post-codegen pass to clean up and handle the condition codes?
+See PR5694 for testcase.
diff --git a/lib/Target/ARM/TargetInfo/Makefile b/lib/Target/ARM/TargetInfo/Makefile
index 6292ab1..589dbe5 100644
--- a/lib/Target/ARM/TargetInfo/Makefile
+++ b/lib/Target/ARM/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMARMInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/ARM/Thumb1InstrInfo.cpp b/lib/Target/ARM/Thumb1InstrInfo.cpp
index e875394..7f42c82 100644
--- a/lib/Target/ARM/Thumb1InstrInfo.cpp
+++ b/lib/Target/ARM/Thumb1InstrInfo.cpp
@@ -105,7 +105,9 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
(TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
isARMLowRegister(SrcReg))) && "Unknown regclass!");
- if (RC == ARM::tGPRRegisterClass) {
+ if (RC == ARM::tGPRRegisterClass ||
+ (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
+ isARMLowRegister(SrcReg))) {
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
MachineMemOperand *MMO =
@@ -130,7 +132,9 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
(TargetRegisterInfo::isPhysicalRegister(DestReg) &&
isARMLowRegister(DestReg))) && "Unknown regclass!");
- if (RC == ARM::tGPRRegisterClass) {
+ if (RC == ARM::tGPRRegisterClass ||
+ (TargetRegisterInfo::isPhysicalRegister(DestReg) &&
+ isARMLowRegister(DestReg))) {
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
MachineMemOperand *MMO =
diff --git a/lib/Target/ARM/Thumb1RegisterInfo.cpp b/lib/Target/ARM/Thumb1RegisterInfo.cpp
index 9f3816a..d6630ce 100644
--- a/lib/Target/ARM/Thumb1RegisterInfo.cpp
+++ b/lib/Target/ARM/Thumb1RegisterInfo.cpp
@@ -479,11 +479,15 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
"Thumb add/sub sp, #imm immediate must be multiple of 4!");
}
- if (Offset == 0) {
+ unsigned PredReg;
+ if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
// Turn it into a move.
MI.setDesc(TII.get(ARM::tMOVgpr2tgpr));
MI.getOperand(i).ChangeToRegister(FrameReg, false);
- MI.RemoveOperand(i+1);
+ // Remove offset and remaining explicit predicate operands.
+ do MI.RemoveOperand(i+1);
+ while (MI.getNumOperands() > i+1 &&
+ (!MI.getOperand(i+1).isReg() || !MI.getOperand(i+1).isImm()));
return 0;
}
diff --git a/lib/Target/ARM/Thumb2InstrInfo.cpp b/lib/Target/ARM/Thumb2InstrInfo.cpp
index f4a8c27..387edaf 100644
--- a/lib/Target/ARM/Thumb2InstrInfo.cpp
+++ b/lib/Target/ARM/Thumb2InstrInfo.cpp
@@ -329,12 +329,16 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
Offset += MI.getOperand(FrameRegIdx+1).getImm();
bool isSP = FrameReg == ARM::SP;
- if (Offset == 0) {
+ unsigned PredReg;
+ if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) {
// Turn it into a move.
MI.setDesc(TII.get(ARM::tMOVgpr2gpr));
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
- MI.RemoveOperand(FrameRegIdx+1);
- Offset = 0;
+ // Remove offset and remaining explicit predicate operands.
+ do MI.RemoveOperand(FrameRegIdx+1);
+ while (MI.getNumOperands() > FrameRegIdx+1 &&
+ (!MI.getOperand(FrameRegIdx+1).isReg() ||
+ !MI.getOperand(FrameRegIdx+1).isImm()));
return true;
}
diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp
index 35359aa..95288bf 100644
--- a/lib/Target/ARM/Thumb2SizeReduction.cpp
+++ b/lib/Target/ARM/Thumb2SizeReduction.cpp
@@ -65,7 +65,8 @@ namespace {
{ ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 0 },
{ ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 0 },
{ ARM::t2BICrr, 0, ARM::tBIC, 0, 0, 0, 1, 0,0, 0 },
- { ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0 },
+ //FIXME: Disable CMN, as CCodes are backwards from compare expectations
+ //{ ARM::t2CMNrr, ARM::tCMN, 0, 0, 0, 1, 0, 2,0, 0 },
{ ARM::t2CMPri, ARM::tCMPi8, 0, 8, 0, 1, 0, 2,0, 0 },
{ ARM::t2CMPrr, ARM::tCMPhir, 0, 0, 0, 0, 0, 2,0, 0 },
{ ARM::t2CMPzri,ARM::tCMPzi8, 0, 8, 0, 1, 0, 2,0, 0 },
diff --git a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
index 338057b..b13f544 100644
--- a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
+++ b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp
@@ -28,7 +28,6 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
@@ -53,7 +52,6 @@ namespace {
void printOp(const MachineOperand &MO, bool IsCallOp = false);
void printOperand(const MachineInstr *MI, int opNum);
void printBaseOffsetPair(const MachineInstr *MI, int i, bool brackets=true);
- void PrintGlobalVariable(const GlobalVariable *GVar);
bool runOnMachineFunction(MachineFunction &F);
void EmitStartOfAsmFile(Module &M);
@@ -95,7 +93,7 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_ConstantPoolIndex:
@@ -108,7 +106,7 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
return;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
return;
case MachineOperand::MO_JumpTableIndex:
@@ -148,29 +146,29 @@ bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::PrivateLinkage:
case Function::LinkerPrivateLinkage:
break;
- case Function::ExternalLinkage:
- O << "\t.globl " << CurrentFnName << "\n";
- break;
+ case Function::ExternalLinkage:
+ O << "\t.globl " << *CurrentFnSym << '\n';
+ break;
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
- O << MAI->getWeakRefDirective() << CurrentFnName << "\n";
+ O << MAI->getWeakRefDirective() << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.ent " << CurrentFnName << "\n";
+ O << "\t.ent " << *CurrentFnSym << "\n";
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
// Print out code for the function.
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
- if (I != MF.begin()) {
+ if (I != MF.begin())
EmitBasicBlockStart(I);
- }
+
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
II != E; ++II) {
// Print the assembly for the instruction.
@@ -185,7 +183,7 @@ bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
}
- O << "\t.end " << CurrentFnName << "\n";
+ O << "\t.end " << *CurrentFnSym << "\n";
// We didn't modify anything.
return false;
@@ -199,62 +197,6 @@ void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) {
O << "\t.set noat\n";
}
-void AlphaAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer()) return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- // 0: Switch to section
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- // 1: Check visibility
- printVisibility(name, GVar->getVisibility());
-
- // 2: Kind
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- O << MAI->getWeakRefDirective() << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- case GlobalValue::ExternalLinkage:
- O << MAI->getGlobalDirective() << name << "\n";
- break;
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- // 3: Type, Size, Align
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type\t" << name << ", @object\n";
- O << "\t.size\t" << name << ", " << Size << "\n";
- }
-
- EmitAlignment(Align, GVar);
-
- O << name << ":\n";
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool AlphaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
diff --git a/lib/Target/Alpha/AsmPrinter/Makefile b/lib/Target/Alpha/AsmPrinter/Makefile
index 3c64a3c..3f64aac 100644
--- a/lib/Target/Alpha/AsmPrinter/Makefile
+++ b/lib/Target/Alpha/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMAlphaAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' alpha target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Alpha/Makefile b/lib/Target/Alpha/Makefile
index d2d7109..14cbc6c 100644
--- a/lib/Target/Alpha/Makefile
+++ b/lib/Target/Alpha/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMAlphaCodeGen
TARGET = Alpha
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = AlphaGenRegisterInfo.h.inc AlphaGenRegisterNames.inc \
diff --git a/lib/Target/Alpha/TargetInfo/Makefile b/lib/Target/Alpha/TargetInfo/Makefile
index de01d7f..6f7b898 100644
--- a/lib/Target/Alpha/TargetInfo/Makefile
+++ b/lib/Target/Alpha/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMAlphaInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
index 0bd94d4..749f735 100644
--- a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
+++ b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp
@@ -30,7 +30,6 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
@@ -55,13 +54,12 @@ namespace {
void printInstruction(const MachineInstr *MI); // autogenerated.
static const char *getRegisterName(unsigned RegNo);
- void emitLinkage(const std::string &n, GlobalValue::LinkageTypes l);
+ void emitLinkage(const MCSymbol *GVSym, GlobalValue::LinkageTypes l);
bool runOnMachineFunction(MachineFunction &F);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
- void PrintGlobalVariable(const GlobalVariable* GVar);
};
} // end of anonymous namespace
@@ -71,48 +69,27 @@ extern "C" void LLVMInitializeBlackfinAsmPrinter() {
RegisterAsmPrinter<BlackfinAsmPrinter> X(TheBlackfinTarget);
}
-void BlackfinAsmPrinter::emitLinkage(const std::string &name,
- GlobalValue::LinkageTypes l) {
- switch (l) {
+void BlackfinAsmPrinter::emitLinkage(const MCSymbol *GVSym,
+ GlobalValue::LinkageTypes L) {
+ switch (L) {
default: llvm_unreachable("Unknown linkage type!");
case GlobalValue::InternalLinkage: // Symbols default to internal.
case GlobalValue::PrivateLinkage:
case GlobalValue::LinkerPrivateLinkage:
break;
case GlobalValue::ExternalLinkage:
- O << MAI->getGlobalDirective() << name << "\n";
+ O << MAI->getGlobalDirective() << *GVSym << "\n";
break;
case GlobalValue::LinkOnceAnyLinkage:
case GlobalValue::LinkOnceODRLinkage:
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
- O << MAI->getGlobalDirective() << name << "\n";
- O << MAI->getWeakDefDirective() << name << "\n";
+ O << MAI->getGlobalDirective() << *GVSym << "\n";
+ O << MAI->getWeakDefDirective() << *GVSym << "\n";
break;
}
}
-void BlackfinAsmPrinter::PrintGlobalVariable(const GlobalVariable* GV) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GV->hasInitializer() || EmitSpecialLLVMGlobal(GV))
- return;
-
- std::string name = Mang->getMangledName(GV);
- Constant *C = GV->getInitializer();
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,
- TM));
- emitLinkage(name, GV->getLinkage());
- EmitAlignment(TD->getPreferredAlignmentLog(GV), GV);
- printVisibility(name, GV->getVisibility());
-
- O << "\t.type " << name << ", STT_OBJECT\n";
- O << "\t.size " << name << ',' << TD->getTypeAllocSize(C->getType()) << '\n';
- O << name << ":\n";
- EmitGlobalConstant(C);
-}
-
/// runOnMachineFunction - This uses the printInstruction()
/// method to print assembly for each instruction.
///
@@ -124,11 +101,11 @@ bool BlackfinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
const Function *F = MF.getFunction();
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
EmitAlignment(2, F);
- emitLinkage(CurrentFnName, F->getLinkage());
- printVisibility(CurrentFnName, F->getVisibility());
+ emitLinkage(CurrentFnSym, F->getLinkage());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.type\t" << CurrentFnName << ", STT_FUNC\n"
- << CurrentFnName << ":\n";
+ O << "\t.type\t" << *CurrentFnSym << ", STT_FUNC\n";
+ O << *CurrentFnSym << ":\n";
if (DW)
DW->BeginFunction(&MF);
@@ -154,7 +131,7 @@ bool BlackfinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
}
- O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
+ O << "\t.size " << *CurrentFnSym << ", .-" << *CurrentFnSym << "\n";
if (DW)
DW->EndFunction(&MF);
@@ -175,18 +152,15 @@ void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
printOffset(MO.getOffset());
break;
- case MachineOperand::MO_ExternalSymbol: {
- SmallString<60> NameStr;
- Mang->getNameWithPrefix(NameStr, MO.getSymbolName());
- OutContext.GetOrCreateSymbol(NameStr.str())->print(O, MAI);
+ case MachineOperand::MO_ExternalSymbol:
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
break;
- }
case MachineOperand::MO_ConstantPoolIndex:
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
<< MO.getIndex();
diff --git a/lib/Target/Blackfin/AsmPrinter/Makefile b/lib/Target/Blackfin/AsmPrinter/Makefile
index 091d4df..30e8285 100644
--- a/lib/Target/Blackfin/AsmPrinter/Makefile
+++ b/lib/Target/Blackfin/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMBlackfinAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' Blackfin target directory to grab private
# headers
diff --git a/lib/Target/Blackfin/Makefile b/lib/Target/Blackfin/Makefile
index c68760b..4fdaf27 100644
--- a/lib/Target/Blackfin/Makefile
+++ b/lib/Target/Blackfin/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMBlackfinCodeGen
TARGET = Blackfin
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = BlackfinGenRegisterInfo.h.inc BlackfinGenRegisterNames.inc \
diff --git a/lib/Target/Blackfin/TargetInfo/Makefile b/lib/Target/Blackfin/TargetInfo/Makefile
index c49cfbe..5c770cf 100644
--- a/lib/Target/Blackfin/TargetInfo/Makefile
+++ b/lib/Target/Blackfin/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMBlackfinInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 0fd975c..e765655 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -33,6 +33,7 @@
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
@@ -44,7 +45,6 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/InstVisitor.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/System/Host.h"
#include "llvm/Config/config.h"
@@ -58,6 +58,13 @@ extern "C" void LLVMInitializeCBackendTarget() {
}
namespace {
+ class CBEMCAsmInfo : public MCAsmInfo {
+ public:
+ CBEMCAsmInfo() {
+ GlobalPrefix = "";
+ PrivateGlobalPrefix = "";
+ }
+ };
/// CBackendNameAllUsedStructsAndMergeFunctions - This pass inserts names for
/// any unnamed structure types that are used by the program, and merges
/// external functions with the same name.
@@ -344,11 +351,19 @@ namespace {
char CWriter::ID = 0;
-static std::string Mangle(const std::string &S) {
+static std::string CBEMangle(const std::string &S) {
std::string Result;
- raw_string_ostream OS(Result);
- MCSymbol::printMangledName(S, OS, 0);
- return OS.str();
+
+ for (unsigned i = 0, e = S.size(); i != e; ++i)
+ if (isalnum(S[i]) || S[i] == '_') {
+ Result += S[i];
+ } else {
+ Result += '_';
+ Result += 'A'+(S[i]&15);
+ Result += 'A'+((S[i]>>4)&15);
+ Result += '_';
+ }
+ return Result;
}
@@ -1445,7 +1460,7 @@ std::string CWriter::GetValueName(const Value *Operand) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(Operand)) {
SmallString<128> Str;
Mang->getNameWithPrefix(Str, GV, false);
- return Mangle(Str.str().str());
+ return CBEMangle(Str.str().str());
}
std::string Name = Operand->getName();
@@ -1869,8 +1884,17 @@ bool CWriter::doInitialization(Module &M) {
IL = new IntrinsicLowering(*TD);
IL->AddPrototypes(M);
- // Ensure that all structure types have names...
- Mang = new Mangler(M);
+#if 0
+ std::string Triple = TheModule->getTargetTriple();
+ if (Triple.empty())
+ Triple = llvm::sys::getHostTriple();
+
+ std::string E;
+ if (const Target *Match = TargetRegistry::lookupTarget(Triple, E))
+ TAsm = Match->createAsmInfo(Triple);
+#endif
+ TAsm = new CBEMCAsmInfo();
+ Mang = new Mangler(*TAsm);
// Keep track of which functions are static ctors/dtors so they can have
// an attribute added to their prototypes.
@@ -2223,7 +2247,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
// Print out forward declarations for structure types before anything else!
Out << "/* Structure forward decls */\n";
for (; I != End; ++I) {
- std::string Name = "struct " + Mangle("l_"+I->first);
+ std::string Name = "struct " + CBEMangle("l_"+I->first);
Out << Name << ";\n";
TypeNames.insert(std::make_pair(I->second, Name));
}
@@ -2234,7 +2258,7 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) {
// for struct or opaque types.
Out << "/* Typedefs */\n";
for (I = TST.begin(); I != End; ++I) {
- std::string Name = Mangle("l_"+I->first);
+ std::string Name = CBEMangle("l_"+I->first);
Out << "typedef ";
printType(Out, I->second, false, Name);
Out << ";\n";
@@ -3240,30 +3264,31 @@ bool CWriter::visitBuiltinCall(CallInst &I, Intrinsic::ID ID,
// of the per target tables
// handle multiple constraint codes
std::string CWriter::InterpretASMConstraint(InlineAsm::ConstraintInfo& c) {
-
assert(c.Codes.size() == 1 && "Too many asm constraint codes to handle");
- const char *const *table = 0;
-
// Grab the translation table from MCAsmInfo if it exists.
- if (!TAsm) {
- std::string Triple = TheModule->getTargetTriple();
- if (Triple.empty())
- Triple = llvm::sys::getHostTriple();
-
- std::string E;
- if (const Target *Match = TargetRegistry::lookupTarget(Triple, E))
- TAsm = Match->createAsmInfo(Triple);
- }
- if (TAsm)
- table = TAsm->getAsmCBE();
+ const MCAsmInfo *TargetAsm;
+ std::string Triple = TheModule->getTargetTriple();
+ if (Triple.empty())
+ Triple = llvm::sys::getHostTriple();
+
+ std::string E;
+ if (const Target *Match = TargetRegistry::lookupTarget(Triple, E))
+ TargetAsm = Match->createAsmInfo(Triple);
+ else
+ return c.Codes[0];
+
+ const char *const *table = TargetAsm->getAsmCBE();
// Search the translation table if it exists.
for (int i = 0; table && table[i]; i += 2)
- if (c.Codes[0] == table[i])
+ if (c.Codes[0] == table[i]) {
+ delete TargetAsm;
return table[i+1];
+ }
// Default is identity.
+ delete TargetAsm;
return c.Codes[0];
}
diff --git a/lib/Target/CBackend/Makefile b/lib/Target/CBackend/Makefile
index 3b5ef0f..f82d277 100644
--- a/lib/Target/CBackend/Makefile
+++ b/lib/Target/CBackend/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMCBackend
+CXXFLAGS = -fno-rtti
DIRS = TargetInfo
diff --git a/lib/Target/CBackend/TargetInfo/Makefile b/lib/Target/CBackend/TargetInfo/Makefile
index d4d5e15..6407904 100644
--- a/lib/Target/CBackend/TargetInfo/Makefile
+++ b/lib/Target/CBackend/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMCBackendInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/CMakeLists.txt b/lib/Target/CMakeLists.txt
index 8769ee2..10478b4 100644
--- a/lib/Target/CMakeLists.txt
+++ b/lib/Target/CMakeLists.txt
@@ -1,6 +1,8 @@
add_llvm_library(LLVMTarget
+ Mangler.cpp
SubtargetFeature.cpp
Target.cpp
+ TargetAsmLexer.cpp
TargetData.cpp
TargetELFWriterInfo.cpp
TargetFrameInfo.cpp
diff --git a/lib/Target/CellSPU/AsmPrinter/Makefile b/lib/Target/CellSPU/AsmPrinter/Makefile
index 69639ef..aa0db52 100644
--- a/lib/Target/CellSPU/AsmPrinter/Makefile
+++ b/lib/Target/CellSPU/AsmPrinter/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMCellSPUAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' CellSPU target directory to grab
# private headers
diff --git a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
index dc9f81c4..59d6ddd 100644
--- a/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
+++ b/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
@@ -39,9 +39,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
-#include <set>
using namespace llvm;
namespace {
@@ -50,7 +48,6 @@ namespace {
const std::string bss_section(".bss");
class SPUAsmPrinter : public AsmPrinter {
- std::set<std::string> FnStubs, GVStubs;
public:
explicit SPUAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
const MCAsmInfo *T, bool V) :
@@ -302,9 +299,6 @@ namespace {
AU.addRequired<DwarfWriter>();
SPUAsmPrinter::getAnalysisUsage(AU);
}
-
- //! Emit a global variable according to its section and type
- void PrintGlobalVariable(const GlobalVariable* GVar);
};
} // end of anonymous namespace
@@ -318,7 +312,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
@@ -331,32 +325,25 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
case MachineOperand::MO_ExternalSymbol:
// Computing the address of an external symbol, not calling it.
if (TM.getRelocationModel() != Reloc::Static) {
- std::string Name(MAI->getGlobalPrefix()); Name += MO.getSymbolName();
- GVStubs.insert(Name);
- O << "L" << Name << "$non_lazy_ptr";
+ O << "L" << MAI->getGlobalPrefix() << MO.getSymbolName()
+ << "$non_lazy_ptr";
return;
}
- O << MAI->getGlobalPrefix() << MO.getSymbolName();
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
return;
- case MachineOperand::MO_GlobalAddress: {
- // Computing the address of a global symbol, not calling it.
- GlobalValue *GV = MO.getGlobal();
- std::string Name = Mang->getMangledName(GV);
-
+ case MachineOperand::MO_GlobalAddress:
// External or weakly linked global variables need non-lazily-resolved
// stubs
if (TM.getRelocationModel() != Reloc::Static) {
+ GlobalValue *GV = MO.getGlobal();
if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
- GVStubs.insert(Name);
- O << "L" << Name << "$non_lazy_ptr";
+ O << *GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
return;
}
}
- O << Name;
+ O << *GetGlobalValueSymbol(MO.getGlobal());
return;
- }
-
default:
O << "<unknown operand type: " << MO.getType() << ">";
return;
@@ -437,18 +424,19 @@ bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::InternalLinkage: // Symbols default to internal.
break;
case Function::ExternalLinkage:
- O << "\t.global\t" << CurrentFnName << "\n"
- << "\t.type\t" << CurrentFnName << ", @function\n";
+ O << "\t.global\t" << *CurrentFnSym << "\n" << "\t.type\t";
+ O << *CurrentFnSym << ", @function\n";
break;
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
- O << "\t.global\t" << CurrentFnName << "\n";
- O << "\t.weak_definition\t" << CurrentFnName << "\n";
+ O << "\t.global\t" << *CurrentFnSym << "\n";
+ O << "\t.weak_definition\t" << *CurrentFnSym << "\n";
break;
}
- O << CurrentFnName << ":\n";
+
+ O << *CurrentFnSym << ":\n";
// Emit pre-function debug information.
DW->BeginFunction(&MF);
@@ -467,7 +455,7 @@ bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
}
- O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << "\n";
+ O << "\t.size\t" << *CurrentFnSym << ",.-" << *CurrentFnSym << "\n";
// Print out jump tables referenced by the function.
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
@@ -479,93 +467,6 @@ bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
return false;
}
-
-/*!
- Emit a global variable according to its section, alignment, etc.
-
- \note This code was shamelessly copied from the PowerPC's assembly printer,
- which sort of screams for some kind of refactorization of common code.
- */
-void LinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return;
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- std::string name = Mang->getMangledName(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && /* FIXME: Verify correct */
- !GVar->hasSection() &&
- (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
- GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasExternalLinkage()) {
- O << "\t.global " << name << '\n';
- O << "\t.type " << name << ", @object\n";
- O << name << ":\n";
- O << "\t.zero " << Size << '\n';
- } else if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << ',' << Size;
- } else {
- O << ".comm " << name << ',' << Size;
- }
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'\n";
- return;
- }
-
- switch (GVar->getLinkage()) {
- // Should never be seen for the CellSPU platform...
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- O << "\t.global " << name << '\n'
- << "\t.type " << name << ", @object\n"
- << "\t.weak " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.global " << name << '\n'
- << "\t.type " << name << ", @object\n";
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- llvm_report_error("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":\t\t\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'\n";
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
// Force static initialization.
extern "C" void LLVMInitializeCellSPUAsmPrinter() {
RegisterAsmPrinter<LinuxAsmPrinter> X(TheCellSPUTarget);
diff --git a/lib/Target/CellSPU/Makefile b/lib/Target/CellSPU/Makefile
index 8415168..9f3ff74 100644
--- a/lib/Target/CellSPU/Makefile
+++ b/lib/Target/CellSPU/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMCellSPUCodeGen
TARGET = SPU
+CXXFLAGS = -fno-rtti
BUILT_SOURCES = SPUGenInstrNames.inc SPUGenRegisterNames.inc \
SPUGenAsmWriter.inc SPUGenCodeEmitter.inc \
diff --git a/lib/Target/CellSPU/SPUMCAsmInfo.cpp b/lib/Target/CellSPU/SPUMCAsmInfo.cpp
index 1c921ab..03cdb29 100644
--- a/lib/Target/CellSPU/SPUMCAsmInfo.cpp
+++ b/lib/Target/CellSPU/SPUMCAsmInfo.cpp
@@ -19,7 +19,7 @@ SPULinuxMCAsmInfo::SPULinuxMCAsmInfo(const Target &T, const StringRef &TT) {
SetDirective = "\t.set";
Data64bitsDirective = "\t.quad\t";
AlignmentIsInBytes = false;
- LCOMMDirective = "\t.lcomm\t";
+ HasLCOMMDirective = true;
PCSymbol = ".";
CommentString = "#";
diff --git a/lib/Target/CellSPU/TargetInfo/Makefile b/lib/Target/CellSPU/TargetInfo/Makefile
index 9cb6827..30ca5cf 100644
--- a/lib/Target/CellSPU/TargetInfo/Makefile
+++ b/lib/Target/CellSPU/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMCellSPUInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index a872fbd..73272bc 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -472,7 +472,6 @@ namespace {
HANDLE_ATTR(Nest);
HANDLE_ATTR(ReadNone);
HANDLE_ATTR(ReadOnly);
- HANDLE_ATTR(InlineHint);
HANDLE_ATTR(NoInline);
HANDLE_ATTR(AlwaysInline);
HANDLE_ATTR(OptimizeForSize);
diff --git a/lib/Target/CppBackend/Makefile b/lib/Target/CppBackend/Makefile
index dc9cf48..52f2aad 100644
--- a/lib/Target/CppBackend/Makefile
+++ b/lib/Target/CppBackend/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMCppBackend
+CXXFLAGS = -fno-rtti
DIRS = TargetInfo
diff --git a/lib/Target/CppBackend/TargetInfo/Makefile b/lib/Target/CppBackend/TargetInfo/Makefile
index 6e68283..7e44aab 100644
--- a/lib/Target/CppBackend/TargetInfo/Makefile
+++ b/lib/Target/CppBackend/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMCppBackendInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp
index b3b91da..1bc708e 100644
--- a/lib/Target/MSIL/MSILWriter.cpp
+++ b/lib/Target/MSIL/MSILWriter.cpp
@@ -102,7 +102,6 @@ bool MSILWriter::runOnFunction(Function &F) {
bool MSILWriter::doInitialization(Module &M) {
ModulePtr = &M;
- Mang = new Mangler(M);
Out << ".assembly extern mscorlib {}\n";
Out << ".assembly MSIL {}\n\n";
Out << "// External\n";
@@ -118,7 +117,6 @@ bool MSILWriter::doInitialization(Module &M) {
bool MSILWriter::doFinalization(Module &M) {
- delete Mang;
return false;
}
@@ -232,7 +230,7 @@ bool MSILWriter::isZeroValue(const Value* V) {
std::string MSILWriter::getValueName(const Value* V) {
std::string Name;
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
- Name = Mang->getMangledName(GV);
+ Name = GV->getName();
else {
unsigned &No = AnonValueNumbers[V];
if (No == 0) No = ++NextAnonValueNumber;
@@ -259,7 +257,7 @@ std::string MSILWriter::getLabelName(const std::string& Name) {
std::string MSILWriter::getLabelName(const Value* V) {
std::string Name;
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
- Name = Mang->getMangledName(GV);
+ Name = GV->getName();
else {
unsigned &No = AnonValueNumbers[V];
if (No == 0) No = ++NextAnonValueNumber;
@@ -1616,7 +1614,7 @@ const char* MSILWriter::getLibraryName(const Function* F) {
const char* MSILWriter::getLibraryName(const GlobalVariable* GV) {
- return getLibraryForSymbol(Mang->getMangledName(GV), false, CallingConv::C);
+ return getLibraryForSymbol(GV->getName(), false, CallingConv::C);
}
@@ -1674,7 +1672,7 @@ void MSILWriter::printExternals() {
std::string Tmp = getTypeName(I->getType())+getValueName(&*I);
printSimpleInstruction("ldsflda",Tmp.c_str());
Out << "\tldstr\t\"" << getLibraryName(&*I) << "\"\n";
- Out << "\tldstr\t\"" << Mang->getMangledName(&*I) << "\"\n";
+ Out << "\tldstr\t\"" << I->getName() << "\"\n";
printSimpleInstruction("call","void* $MSIL_Import(string,string)");
printIndirectSave(I->getType());
}
diff --git a/lib/Target/MSIL/MSILWriter.h b/lib/Target/MSIL/MSILWriter.h
index 2280a3b..a95ae23 100644
--- a/lib/Target/MSIL/MSILWriter.h
+++ b/lib/Target/MSIL/MSILWriter.h
@@ -27,7 +27,6 @@
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/Mangler.h"
namespace llvm {
extern Target TheMSILTarget;
@@ -78,7 +77,6 @@ namespace llvm {
formatted_raw_ostream &Out;
Module* ModulePtr;
const TargetData* TD;
- Mangler* Mang;
LoopInfo *LInfo;
std::vector<StaticInitializer>* InitListPtr;
std::map<const GlobalVariable*,std::vector<StaticInitializer> >
diff --git a/lib/Target/MSIL/Makefile b/lib/Target/MSIL/Makefile
index 8057cc7..9fecba5 100644
--- a/lib/Target/MSIL/Makefile
+++ b/lib/Target/MSIL/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../..
LIBRARYNAME = LLVMMSIL
+CXXFLAGS = -fno-rtti
DIRS = TargetInfo
diff --git a/lib/Target/MSIL/TargetInfo/Makefile b/lib/Target/MSIL/TargetInfo/Makefile
index 30b0950..710f5a1 100644
--- a/lib/Target/MSIL/TargetInfo/Makefile
+++ b/lib/Target/MSIL/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMSILInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
index 145359f..6033197 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
@@ -38,9 +38,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/ErrorHandling.h"
-
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -80,7 +78,6 @@ namespace {
const char *ExtraCode);
void printInstructionThroughMCStreamer(const MachineInstr *MI);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void emitFunctionHeader(const MachineFunction &MF);
bool runOnMachineFunction(MachineFunction &F);
@@ -91,89 +88,6 @@ namespace {
};
} // end of anonymous namespace
-void MSP430AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- const TargetData *TD = TM.getTargetData();
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- O << "\t.type\t" << name << ",@object\n";
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection() &&
- !GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
-
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << '\n';
-
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- O << "\t.weak\t" << name << '\n';
- break;
- case GlobalValue::DLLExportLinkage:
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << name << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- assert(0 && "Unknown linkage type!");
- }
-
- // Use 16-bit alignment by default to simplify bunch of stuff
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
-
- EmitGlobalConstant(C);
-
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << name << ", " << Size << '\n';
-}
void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
const Function *F = MF.getFunction();
@@ -190,20 +104,20 @@ void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::LinkerPrivateLinkage:
break;
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
break;
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
- O << "\t.weak\t" << CurrentFnName << '\n';
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.type\t" << CurrentFnName << ",@function\n"
- << CurrentFnName << ":\n";
+ O << "\t.type\t" << *CurrentFnSym << ",@function\n";
+ O << *CurrentFnSym << ":\n";
}
bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
@@ -226,7 +140,7 @@ bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
// We didn't modify anything
return false;
@@ -259,18 +173,18 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
- std::string Name = Mang->getMangledName(MO.getGlobal());
uint64_t Offset = MO.getOffset();
O << (isMemOp ? '&' : '#');
if (Offset)
O << '(' << Offset << '+';
- O << Name;
+ O << *GetGlobalValueSymbol(MO.getGlobal());
+
if (Offset)
O << ')';
@@ -278,11 +192,8 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
}
case MachineOperand::MO_ExternalSymbol: {
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
- std::string Name(MAI->getGlobalPrefix());
- Name += MO.getSymbolName();
-
- O << (isMemOp ? '&' : '#') << Name;
-
+ O << (isMemOp ? '&' : '#');
+ O << MAI->getGlobalPrefix() << MO.getSymbolName();
return;
}
default:
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
index 0a403c4..a480307 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
@@ -39,7 +39,7 @@ void MSP430InstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo) {
O << Op.getImm();
else {
assert(Op.isExpr() && "unknown pcrel immediate operand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
@@ -53,8 +53,7 @@ void MSP430InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
O << '#' << Op.getImm();
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
- O << '#';
- Op.getExpr()->print(O, &MAI);
+ O << '#' << *Op.getExpr();
}
}
@@ -65,8 +64,7 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
// Print displacement first
if (Disp.isExpr()) {
- O << '&';
- Disp.getExpr()->print(O, &MAI);
+ O << '&' << *Disp.getExpr();
} else {
assert(Disp.isImm() && "Expected immediate in displacement field");
if (!Base.getReg())
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp b/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
index 595b7e7..e1f80b7 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430MCInstLower.cpp
@@ -22,37 +22,27 @@
#include "llvm/MC/MCInst.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/SmallString.h"
using namespace llvm;
MCSymbol *MSP430MCInstLower::
GetGlobalAddressSymbol(const MachineOperand &MO) const {
- const GlobalValue *GV = MO.getGlobal();
-
- SmallString<128> Name;
- Mang.getNameWithPrefix(Name, GV, false);
-
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
case 0: break;
}
- return Ctx.GetOrCreateSymbol(Name.str());
+ return Printer.GetGlobalValueSymbol(MO.getGlobal());
}
MCSymbol *MSP430MCInstLower::
GetExternalSymbolSymbol(const MachineOperand &MO) const {
- SmallString<128> Name;
- Name += Printer.MAI->getGlobalPrefix();
- Name += MO.getSymbolName();
-
switch (MO.getTargetFlags()) {
default: assert(0 && "Unknown target flag on GV operand");
case 0: break;
}
- return Ctx.GetOrCreateSymbol(Name.str());
+ return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
}
MCSymbol *MSP430MCInstLower::
diff --git a/lib/Target/MSP430/AsmPrinter/Makefile b/lib/Target/MSP430/AsmPrinter/Makefile
index 4f340c6..c8a44a1 100644
--- a/lib/Target/MSP430/AsmPrinter/Makefile
+++ b/lib/Target/MSP430/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMSP430AsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' MSP430 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/MSP430/CMakeLists.txt b/lib/Target/MSP430/CMakeLists.txt
index 60e0bb1..29abe46 100644
--- a/lib/Target/MSP430/CMakeLists.txt
+++ b/lib/Target/MSP430/CMakeLists.txt
@@ -11,9 +11,10 @@ tablegen(MSP430GenCallingConv.inc -gen-callingconv)
tablegen(MSP430GenSubtarget.inc -gen-subtarget)
add_llvm_target(MSP430CodeGen
- MSP430InstrInfo.cpp
+ MSP430BranchSelector.cpp
MSP430ISelDAGToDAG.cpp
MSP430ISelLowering.cpp
+ MSP430InstrInfo.cpp
MSP430MCAsmInfo.cpp
MSP430RegisterInfo.cpp
MSP430Subtarget.cpp
diff --git a/lib/Target/MSP430/MSP430.h b/lib/Target/MSP430/MSP430.h
index 1ff178d..e742118 100644
--- a/lib/Target/MSP430/MSP430.h
+++ b/lib/Target/MSP430/MSP430.h
@@ -39,6 +39,8 @@ namespace llvm {
FunctionPass *createMSP430ISelDag(MSP430TargetMachine &TM,
CodeGenOpt::Level OptLevel);
+ FunctionPass *createMSP430BranchSelectionPass();
+
extern Target TheMSP430Target;
} // end namespace llvm;
diff --git a/lib/Target/MSP430/MSP430.td b/lib/Target/MSP430/MSP430.td
index 870a3df..fe533d3 100644
--- a/lib/Target/MSP430/MSP430.td
+++ b/lib/Target/MSP430/MSP430.td
@@ -48,8 +48,14 @@ include "MSP430CallingConv.td"
include "MSP430InstrInfo.td"
-def MSP430InstrInfo : InstrInfo {}
-
+def MSP430InstrInfo : InstrInfo {
+ // Define how we want to layout our TargetSpecific information field... This
+ // should be kept up-to-date with the fields in the MSP430InstrInfo.h file.
+ let TSFlagsFields = ["FormBits",
+ "Size"];
+ let TSFlagsShifts = [0,
+ 2];
+}
def MSP430InstPrinter : AsmWriter {
string AsmWriterClassName = "InstPrinter";
diff --git a/lib/Target/MSP430/MSP430BranchSelector.cpp b/lib/Target/MSP430/MSP430BranchSelector.cpp
new file mode 100644
index 0000000..836e425
--- /dev/null
+++ b/lib/Target/MSP430/MSP430BranchSelector.cpp
@@ -0,0 +1,179 @@
+//===-- MSP430BranchSelector.cpp - Emit long conditional branches--*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a pass that scans a machine function to determine which
+// conditional branches need more than 10 bits of displacement to reach their
+// target basic block. It does this in two passes; a calculation of basic block
+// positions pass, and a branch psuedo op to machine branch opcode pass. This
+// pass should be run last, just before the assembly printer.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "msp430-branch-select"
+#include "MSP430.h"
+#include "MSP430InstrInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/MathExtras.h"
+using namespace llvm;
+
+STATISTIC(NumExpanded, "Number of branches expanded to long format");
+
+namespace {
+ struct MSP430BSel : public MachineFunctionPass {
+ static char ID;
+ MSP430BSel() : MachineFunctionPass(&ID) {}
+
+ /// BlockSizes - The sizes of the basic blocks in the function.
+ std::vector<unsigned> BlockSizes;
+
+ virtual bool runOnMachineFunction(MachineFunction &Fn);
+
+ virtual const char *getPassName() const {
+ return "MSP430 Branch Selector";
+ }
+ };
+ char MSP430BSel::ID = 0;
+}
+
+/// createMSP430BranchSelectionPass - returns an instance of the Branch
+/// Selection Pass
+///
+FunctionPass *llvm::createMSP430BranchSelectionPass() {
+ return new MSP430BSel();
+}
+
+bool MSP430BSel::runOnMachineFunction(MachineFunction &Fn) {
+ const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
+ // Give the blocks of the function a dense, in-order, numbering.
+ Fn.RenumberBlocks();
+ BlockSizes.resize(Fn.getNumBlockIDs());
+
+ // Measure each MBB and compute a size for the entire function.
+ unsigned FuncSize = 0;
+ for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
+ ++MFI) {
+ MachineBasicBlock *MBB = MFI;
+
+ unsigned BlockSize = 0;
+ for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
+ MBBI != EE; ++MBBI)
+ BlockSize += TII->GetInstSizeInBytes(MBBI);
+
+ BlockSizes[MBB->getNumber()] = BlockSize;
+ FuncSize += BlockSize;
+ }
+
+ // If the entire function is smaller than the displacement of a branch field,
+ // we know we don't need to shrink any branches in this function. This is a
+ // common case.
+ if (FuncSize < (1 << 9)) {
+ BlockSizes.clear();
+ return false;
+ }
+
+ // For each conditional branch, if the offset to its destination is larger
+ // than the offset field allows, transform it into a long branch sequence
+ // like this:
+ // short branch:
+ // bCC MBB
+ // long branch:
+ // b!CC $PC+6
+ // b MBB
+ //
+ bool MadeChange = true;
+ bool EverMadeChange = false;
+ while (MadeChange) {
+ // Iteratively expand branches until we reach a fixed point.
+ MadeChange = false;
+
+ for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
+ ++MFI) {
+ MachineBasicBlock &MBB = *MFI;
+ unsigned MBBStartOffset = 0;
+ for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
+ I != E; ++I) {
+ if ((I->getOpcode() != MSP430::JCC || I->getOperand(0).isImm()) &&
+ I->getOpcode() != MSP430::JMP) {
+ MBBStartOffset += TII->GetInstSizeInBytes(I);
+ continue;
+ }
+
+ // Determine the offset from the current branch to the destination
+ // block.
+ MachineBasicBlock *Dest = I->getOperand(0).getMBB();
+
+ int BranchSize;
+ if (Dest->getNumber() <= MBB.getNumber()) {
+ // If this is a backwards branch, the delta is the offset from the
+ // start of this block to this branch, plus the sizes of all blocks
+ // from this block to the dest.
+ BranchSize = MBBStartOffset;
+
+ for (unsigned i = Dest->getNumber(), e = MBB.getNumber(); i != e; ++i)
+ BranchSize += BlockSizes[i];
+ } else {
+ // Otherwise, add the size of the blocks between this block and the
+ // dest to the number of bytes left in this block.
+ BranchSize = -MBBStartOffset;
+
+ for (unsigned i = MBB.getNumber(), e = Dest->getNumber(); i != e; ++i)
+ BranchSize += BlockSizes[i];
+ }
+
+ // If this branch is in range, ignore it.
+ if (isInt<10>(BranchSize)) {
+ MBBStartOffset += 2;
+ continue;
+ }
+
+ // Otherwise, we have to expand it to a long branch.
+ unsigned NewSize;
+ MachineInstr *OldBranch = I;
+ DebugLoc dl = OldBranch->getDebugLoc();
+
+ if (I->getOpcode() == MSP430::JMP) {
+ NewSize = 4;
+ } else {
+ // The BCC operands are:
+ // 0. MSP430 branch predicate
+ // 1. Target MBB
+ SmallVector<MachineOperand, 1> Cond;
+ Cond.push_back(I->getOperand(1));
+
+ // Jump over the uncond branch inst (i.e. $+6) on opposite condition.
+ TII->ReverseBranchCondition(Cond);
+ BuildMI(MBB, I, dl, TII->get(MSP430::JCC))
+ .addImm(4).addOperand(Cond[0]);
+
+ NewSize = 6;
+ }
+ // Uncond branch to the real destination.
+ I = BuildMI(MBB, I, dl, TII->get(MSP430::B)).addMBB(Dest);
+
+ // Remove the old branch from the function.
+ OldBranch->eraseFromParent();
+
+ // Remember that this instruction is NewSize bytes, increase the size of the
+ // block by NewSize-2, remember to iterate.
+ BlockSizes[MBB.getNumber()] += NewSize-2;
+ MBBStartOffset += NewSize;
+
+ ++NumExpanded;
+ MadeChange = true;
+ }
+ }
+ EverMadeChange |= MadeChange;
+ }
+
+ BlockSizes.clear();
+ return true;
+}
diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp
index d3dce4b..b794911 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.cpp
+++ b/lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -675,21 +675,53 @@ static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
case ISD::SETULE:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETUGE:
+ // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_LO;
+ break;
+ }
TCC = MSP430CC::COND_HS; // aka COND_C
break;
case ISD::SETUGT:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETULT:
+ // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_HS;
+ break;
+ }
TCC = MSP430CC::COND_LO; // aka COND_NC
break;
case ISD::SETLE:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETGE:
+ // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_L;
+ break;
+ }
TCC = MSP430CC::COND_GE;
break;
case ISD::SETGT:
std::swap(LHS, RHS); // FALLTHROUGH
case ISD::SETLT:
+ // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
+ // fold constant into instruction.
+ if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
+ LHS = RHS;
+ RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
+ TCC = MSP430CC::COND_GE;
+ break;
+ }
TCC = MSP430CC::COND_L;
break;
}
@@ -723,6 +755,8 @@ SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
// If we are doing an AND and testing against zero, then the CMP
// will not be generated. The AND (or BIT) will generate the condition codes,
// but they are different from CMP.
+ // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
+ // lowering & isel wouldn't diverge.
bool andCC = false;
if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
if (RHSC->isNullValue() && LHS.hasOneUse() &&
@@ -750,11 +784,11 @@ SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
case MSP430CC::COND_HS:
// Res = SRW & 1, no processing is required
break;
- case MSP430CC::COND_LO:
+ case MSP430CC::COND_LO:
// Res = ~(SRW & 1)
Invert = true;
break;
- case MSP430CC::COND_NE:
+ case MSP430CC::COND_NE:
if (andCC) {
// C = ~Z, thus Res = SRW & 1, no processing is required
} else {
@@ -762,7 +796,7 @@ SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
Shift = true;
}
break;
- case MSP430CC::COND_E:
+ case MSP430CC::COND_E:
if (andCC) {
// C = ~Z, thus Res = ~(SRW & 1)
} else {
@@ -776,7 +810,7 @@ SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
SDValue One = DAG.getConstant(1, VT);
if (Convert) {
SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
- MVT::i16, Flag);
+ MVT::i16, Flag);
if (Shift)
// FIXME: somewhere this is turned into a SRL, lower it MSP specific?
SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
@@ -933,6 +967,31 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
}
}
+bool MSP430TargetLowering::isTruncateFree(const Type *Ty1,
+ const Type *Ty2) const {
+ if (!Ty1->isInteger() || !Ty2->isInteger())
+ return false;
+
+ return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
+}
+
+bool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
+ if (!VT1.isInteger() || !VT2.isInteger())
+ return false;
+
+ return (VT1.getSizeInBits() > VT2.getSizeInBits());
+}
+
+bool MSP430TargetLowering::isZExtFree(const Type *Ty1, const Type *Ty2) const {
+ // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
+ return 0 && Ty1->isInteger(8) && Ty2->isInteger(16);
+}
+
+bool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
+ // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
+ return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
+}
+
//===----------------------------------------------------------------------===//
// Other Lowering Code
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h
index 4921500..6152a05 100644
--- a/lib/Target/MSP430/MSP430ISelLowering.h
+++ b/lib/Target/MSP430/MSP430ISelLowering.h
@@ -99,6 +99,23 @@ namespace llvm {
std::pair<unsigned, const TargetRegisterClass*>
getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const;
+ /// isTruncateFree - Return true if it's free to truncate a value of type
+ /// Ty1 to type Ty2. e.g. On msp430 it's free to truncate a i16 value in
+ /// register R15W to i8 by referencing its sub-register R15B.
+ virtual bool isTruncateFree(const Type *Ty1, const Type *Ty2) const;
+ virtual bool isTruncateFree(EVT VT1, EVT VT2) const;
+
+ /// isZExtFree - Return true if any actual instruction that defines a value
+ /// of type Ty1 implicit zero-extends the value to Ty2 in the result
+ /// register. This does not necessarily include registers defined in unknown
+ /// ways, such as incoming arguments, or copies from unknown virtual
+ /// registers. Also, if isTruncateFree(Ty2, Ty1) is true, this does not
+ /// necessarily apply to truncate instructions. e.g. on msp430, all
+ /// instructions that define 8-bit values implicit zero-extend the result
+ /// out to 16 bits.
+ virtual bool isZExtFree(const Type *Ty1, const Type *Ty2) const;
+ virtual bool isZExtFree(EVT VT1, EVT VT2) const;
+
MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *BB,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const;
diff --git a/lib/Target/MSP430/MSP430InstrFormats.td b/lib/Target/MSP430/MSP430InstrFormats.td
index 61b3399..4ccc7df 100644
--- a/lib/Target/MSP430/MSP430InstrFormats.td
+++ b/lib/Target/MSP430/MSP430InstrFormats.td
@@ -11,8 +11,48 @@
// Describe MSP430 instructions format here
//
+// Format specifies the encoding used by the instruction. This is part of the
+// ad-hoc solution used to emit machine instruction encodings by our machine
+// code emitter.
+class Format<bits<2> val> {
+ bits<2> Value = val;
+}
+
+def PseudoFrm : Format<0>;
+def SingleOpFrm : Format<1>;
+def DoubleOpFrm : Format<2>;
+def CondJumpFrm : Format<3>;
+
+class SourceMode<bits<2> val> {
+ bits<2> Value = val;
+}
+
+def SrcReg : SourceMode<0>;
+def SrcMem : SourceMode<1>;
+def SrcIndReg : SourceMode<2>;
+def SrcPostInc : SourceMode<3>;
+def SrcImm : SourceMode<3>;
+
+class DestMode<bit val> {
+ bit Value = val;
+}
+
+def DstReg : DestMode<0>;
+def DstMem : DestMode<1>;
+
+class SizeVal<bits<3> val> {
+ bits<3> Value = val;
+}
+
+def SizeUnknown : SizeVal<0>; // Unknown / unset size
+def SizeSpecial : SizeVal<1>; // Special instruction, e.g. pseudo
+def Size2Bytes : SizeVal<2>;
+def Size4Bytes : SizeVal<3>;
+def Size6Bytes : SizeVal<4>;
+
// Generic MSP430 Format
-class MSP430Inst<dag outs, dag ins, string asmstr> : Instruction {
+class MSP430Inst<dag outs, dag ins, SizeVal sz, Format f,
+ string asmstr> : Instruction {
field bits<16> Inst;
let Namespace = "MSP430";
@@ -20,48 +60,150 @@ class MSP430Inst<dag outs, dag ins, string asmstr> : Instruction {
dag OutOperandList = outs;
dag InOperandList = ins;
+ Format Form = f;
+ bits<2> FormBits = Form.Value;
+
+ SizeVal Sz = sz;
+ bits<3> Size = Sz.Value;
+
let AsmString = asmstr;
}
// FIXME: Create different classes for different addressing modes.
// MSP430 Double Operand (Format I) Instructions
-class IForm<bits<4> opcode, bit ad, bit bw, bits<2> as,
+class IForm<bits<4> opcode, DestMode dest, bit bw, SourceMode src, SizeVal sz,
dag outs, dag ins, string asmstr, list<dag> pattern>
- : MSP430Inst<outs, ins, asmstr> {
+ : MSP430Inst<outs, ins, sz, DoubleOpFrm, asmstr> {
let Pattern = pattern;
+
+ DestMode ad = dest;
+ SourceMode as = src;
let Inst{12-15} = opcode;
- let Inst{7} = ad;
+ let Inst{7} = ad.Value;
let Inst{6} = bw;
- let Inst{4-5} = as;
+ let Inst{4-5} = as.Value;
}
+// 8 bit IForm instructions
+class IForm8<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm<opcode, dest, 1, src, sz, outs, ins, asmstr, pattern>;
+
+class I8rr<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstReg, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
+
+class I8ri<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstReg, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I8rm<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstReg, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I8mr<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstMem, SrcReg, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I8mi<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstMem, SrcImm, Size6Bytes, outs, ins, asmstr, pattern>;
+
+class I8mm<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm8<opcode, DstMem, SrcMem, Size6Bytes, outs, ins, asmstr, pattern>;
+
+// 16 bit IForm instructions
+class IForm16<bits<4> opcode, DestMode dest, SourceMode src, SizeVal sz,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm<opcode, dest, 0, src, sz, outs, ins, asmstr, pattern>;
+
+class I16rr<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstReg, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
+
+class I16ri<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstReg, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I16rm<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstReg, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I16mr<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstMem, SrcReg, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class I16mi<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstMem, SrcImm, Size6Bytes, outs, ins, asmstr, pattern>;
+
+class I16mm<bits<4> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IForm16<opcode, DstMem, SrcMem, Size6Bytes, outs, ins, asmstr, pattern>;
+
// MSP430 Single Operand (Format II) Instructions
-class IIForm<bits<9> opcode, bit bw, bits<2> ad,
+class IIForm<bits<9> opcode, bit bw, SourceMode src, SizeVal sz,
dag outs, dag ins, string asmstr, list<dag> pattern>
- : MSP430Inst<outs, ins, asmstr> {
+ : MSP430Inst<outs, ins, sz, SingleOpFrm, asmstr> {
let Pattern = pattern;
+ SourceMode as = src;
+
let Inst{7-15} = opcode;
let Inst{6} = bw;
- let Inst{4-5} = ad;
+ let Inst{4-5} = as.Value;
}
+// 8 bit IIForm instructions
+class IIForm8<bits<9> opcode, SourceMode src, SizeVal sz,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm<opcode, 1, src, sz, outs, ins, asmstr, pattern>;
+
+class II8r<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm8<opcode, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
+
+class II8m<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm8<opcode, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class II8i<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm8<opcode, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>;
+
+// 16 bit IIForm instructions
+class IIForm16<bits<9> opcode, SourceMode src, SizeVal sz,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm<opcode, 0, src, sz, outs, ins, asmstr, pattern>;
+
+class II16r<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm16<opcode, SrcReg, Size2Bytes, outs, ins, asmstr, pattern>;
+
+class II16m<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm16<opcode, SrcMem, Size4Bytes, outs, ins, asmstr, pattern>;
+
+class II16i<bits<9> opcode,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : IIForm16<opcode, SrcImm, Size4Bytes, outs, ins, asmstr, pattern>;
+
// MSP430 Conditional Jumps Instructions
-class CJForm<bits<3> opcode, bits<3> cond, bit s,
+class CJForm<bits<3> opcode, bits<3> cond,
dag outs, dag ins, string asmstr, list<dag> pattern>
- : MSP430Inst<outs, ins, asmstr> {
+ : MSP430Inst<outs, ins, Size2Bytes, CondJumpFrm, asmstr> {
let Pattern = pattern;
let Inst{13-15} = opcode;
let Inst{10-12} = cond;
- let Inst{9} = s;
}
// Pseudo instructions
class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
- : MSP430Inst<outs, ins, asmstr> {
+ : MSP430Inst<outs, ins, SizeSpecial, PseudoFrm, asmstr> {
let Pattern = pattern;
let Inst{15-0} = 0;
}
diff --git a/lib/Target/MSP430/MSP430InstrInfo.cpp b/lib/Target/MSP430/MSP430InstrInfo.cpp
index 2ae6759..9dc69e0 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.cpp
+++ b/lib/Target/MSP430/MSP430InstrInfo.cpp
@@ -344,3 +344,45 @@ MSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
}
return Count;
}
+
+/// GetInstSize - Return the number of bytes of code the specified
+/// instruction may be. This returns the maximum number of bytes.
+///
+unsigned MSP430InstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
+ const TargetInstrDesc &Desc = MI->getDesc();
+
+ switch (Desc.TSFlags & MSP430II::SizeMask) {
+ default:
+ switch (Desc.getOpcode()) {
+ default:
+ assert(0 && "Unknown instruction size!");
+ case TargetInstrInfo::DBG_LABEL:
+ case TargetInstrInfo::EH_LABEL:
+ case TargetInstrInfo::IMPLICIT_DEF:
+ case TargetInstrInfo::KILL:
+ return 0;
+ case TargetInstrInfo::INLINEASM: {
+ const MachineFunction *MF = MI->getParent()->getParent();
+ const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
+ return TII.getInlineAsmLength(MI->getOperand(0).getSymbolName(),
+ *MF->getTarget().getMCAsmInfo());
+ }
+ }
+ case MSP430II::SizeSpecial:
+ switch (MI->getOpcode()) {
+ default:
+ assert(0 && "Unknown instruction size!");
+ case MSP430::SAR8r1c:
+ case MSP430::SAR16r1c:
+ return 4;
+ }
+ case MSP430II::Size2Bytes:
+ return 2;
+ case MSP430II::Size4Bytes:
+ return 4;
+ case MSP430II::Size6Bytes:
+ return 6;
+ }
+
+ return 6;
+}
diff --git a/lib/Target/MSP430/MSP430InstrInfo.h b/lib/Target/MSP430/MSP430InstrInfo.h
index e4ceeb9..6ef4b0a 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.h
+++ b/lib/Target/MSP430/MSP430InstrInfo.h
@@ -21,6 +21,22 @@ namespace llvm {
class MSP430TargetMachine;
+/// MSP430II - This namespace holds all of the target specific flags that
+/// instruction info tracks.
+///
+namespace MSP430II {
+ enum {
+ SizeShift = 2,
+ SizeMask = 7 << SizeShift,
+
+ SizeUnknown = 0 << SizeShift,
+ SizeSpecial = 1 << SizeShift,
+ Size2Bytes = 2 << SizeShift,
+ Size4Bytes = 3 << SizeShift,
+ Size6Bytes = 4 << SizeShift
+ };
+}
+
class MSP430InstrInfo : public TargetInstrInfoImpl {
const MSP430RegisterInfo RI;
MSP430TargetMachine &TM;
@@ -59,6 +75,8 @@ public:
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI) const;
+ unsigned GetInstSizeInBytes(const MachineInstr *MI) const;
+
// Branch folding goodness
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
bool isUnpredicatedTerminator(const MachineInstr *MI) const;
diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td
index 022d171..cd502cf 100644
--- a/lib/Target/MSP430/MSP430InstrInfo.td
+++ b/lib/Target/MSP430/MSP430InstrInfo.td
@@ -157,23 +157,35 @@ def NOP : Pseudo<(outs), (ins), "nop", []>;
// FIXME: Provide proper encoding!
let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
- def RET : Pseudo<(outs), (ins), "ret", [(MSP430retflag)]>;
- def RETI : Pseudo<(outs), (ins), "reti", [(MSP430retiflag)]>;
+ def RET : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs), (ins), "ret", [(MSP430retflag)]>;
+ def RETI : II16r<0x0, (outs), (ins), "reti", [(MSP430retiflag)]>;
}
let isBranch = 1, isTerminator = 1 in {
+// FIXME: expand opcode & cond field for branches!
+
// Direct branch
-let isBarrier = 1 in
- def JMP : Pseudo<(outs), (ins brtarget:$dst),
+let isBarrier = 1 in {
+ // Short branch
+ def JMP : CJForm<0, 0,
+ (outs), (ins brtarget:$dst),
"jmp\t$dst",
[(br bb:$dst)]>;
+ // Long branch
+ def B : I16ri<0,
+ (outs), (ins brtarget:$dst),
+ "br\t$dst",
+ []>;
+}
// Conditional branches
let Uses = [SRW] in
- def JCC : Pseudo<(outs), (ins brtarget:$dst, cc:$cc),
- "j$cc\t$dst",
- [(MSP430brcc bb:$dst, imm:$cc)]>;
+ def JCC : CJForm<0, 0,
+ (outs), (ins brtarget:$dst, cc:$cc),
+ "j$cc\t$dst",
+ [(MSP430brcc bb:$dst, imm:$cc)]>;
} // isBranch, isTerminator
//===----------------------------------------------------------------------===//
@@ -186,12 +198,15 @@ let isCall = 1 in
// registers are added manually.
let Defs = [R12W, R13W, R14W, R15W, SRW],
Uses = [SPW] in {
- def CALLi : Pseudo<(outs), (ins i16imm:$dst, variable_ops),
- "call\t$dst", [(MSP430call imm:$dst)]>;
- def CALLr : Pseudo<(outs), (ins GR16:$dst, variable_ops),
- "call\t$dst", [(MSP430call GR16:$dst)]>;
- def CALLm : Pseudo<(outs), (ins memsrc:$dst, variable_ops),
- "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
+ def CALLi : II16i<0x0,
+ (outs), (ins i16imm:$dst, variable_ops),
+ "call\t$dst", [(MSP430call imm:$dst)]>;
+ def CALLr : II16r<0x0,
+ (outs), (ins GR16:$dst, variable_ops),
+ "call\t$dst", [(MSP430call GR16:$dst)]>;
+ def CALLm : II16m<0x0,
+ (outs), (ins memsrc:$dst, variable_ops),
+ "call\t${dst:mem}", [(MSP430call (load addr:$dst))]>;
}
@@ -200,10 +215,12 @@ let isCall = 1 in
//
let Defs = [SPW], Uses = [SPW], neverHasSideEffects=1 in {
let mayLoad = 1 in
-def POP16r : Pseudo<(outs GR16:$reg), (ins), "pop.w\t$reg", []>;
+def POP16r : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$reg), (ins), "pop.w\t$reg", []>;
let mayStore = 1 in
-def PUSH16r : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
+def PUSH16r : II16r<0x0,
+ (outs), (ins GR16:$reg), "push.w\t$reg",[]>;
}
//===----------------------------------------------------------------------===//
@@ -211,45 +228,55 @@ def PUSH16r : Pseudo<(outs), (ins GR16:$reg), "push.w\t$reg",[]>;
// FIXME: Provide proper encoding!
let neverHasSideEffects = 1 in {
-def MOV8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src),
- "mov.b\t{$src, $dst}",
- []>;
-def MOV16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "mov.w\t{$src, $dst}",
- []>;
+def MOV8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src),
+ "mov.b\t{$src, $dst}",
+ []>;
+def MOV16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "mov.w\t{$src, $dst}",
+ []>;
}
// FIXME: Provide proper encoding!
let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
-def MOV8ri : Pseudo<(outs GR8:$dst), (ins i8imm:$src),
- "mov.b\t{$src, $dst}",
- [(set GR8:$dst, imm:$src)]>;
-def MOV16ri : Pseudo<(outs GR16:$dst), (ins i16imm:$src),
- "mov.w\t{$src, $dst}",
- [(set GR16:$dst, imm:$src)]>;
+def MOV8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins i8imm:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR8:$dst, imm:$src)]>;
+def MOV16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins i16imm:$src),
+ "mov.w\t{$src, $dst}",
+ [(set GR16:$dst, imm:$src)]>;
}
let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in {
-def MOV8rm : Pseudo<(outs GR8:$dst), (ins memsrc:$src),
- "mov.b\t{$src, $dst}",
- [(set GR8:$dst, (load addr:$src))]>;
-def MOV16rm : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
- "mov.w\t{$src, $dst}",
- [(set GR16:$dst, (load addr:$src))]>;
+def MOV8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins memsrc:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR8:$dst, (load addr:$src))]>;
+def MOV16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins memsrc:$src),
+ "mov.w\t{$src, $dst}",
+ [(set GR16:$dst, (load addr:$src))]>;
}
-def MOVZX16rr8 : Pseudo<(outs GR16:$dst), (ins GR8:$src),
- "mov.b\t{$src, $dst}",
- [(set GR16:$dst, (zext GR8:$src))]>;
-def MOVZX16rm8 : Pseudo<(outs GR16:$dst), (ins memsrc:$src),
- "mov.b\t{$src, $dst}",
- [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
+def MOVZX16rr8 : I8rr<0x0,
+ (outs GR16:$dst), (ins GR8:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR16:$dst, (zext GR8:$src))]>;
+def MOVZX16rm8 : I8rm<0x0,
+ (outs GR16:$dst), (ins memsrc:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR16:$dst, (zextloadi16i8 addr:$src))]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1, Constraints = "$base = $base_wb" in {
-def MOV8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
- "mov.b\t{@$base+, $dst}", []>;
-def MOV16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$base),
- "mov.w\t{@$base+, $dst}", []>;
+def MOV8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb), (ins GR16:$base),
+ "mov.b\t{@$base+, $dst}", []>;
+def MOV16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb), (ins GR16:$base),
+ "mov.w\t{@$base+, $dst}", []>;
}
// Any instruction that defines a 8-bit result leaves the high half of the
@@ -267,27 +294,32 @@ def def8 : PatLeaf<(i8 GR8:$src), [{
def : Pat<(i16 (zext def8:$src)),
(SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
-
-def MOV8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "mov.b\t{$src, $dst}",
- [(store (i8 imm:$src), addr:$dst)]>;
-def MOV16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "mov.w\t{$src, $dst}",
- [(store (i16 imm:$src), addr:$dst)]>;
-
-def MOV8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "mov.b\t{$src, $dst}",
- [(store GR8:$src, addr:$dst)]>;
-def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "mov.w\t{$src, $dst}",
- [(store GR16:$src, addr:$dst)]>;
-
-def MOV8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "mov.b\t{$src, $dst}",
- [(store (i8 (load addr:$src)), addr:$dst)]>;
-def MOV16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "mov.w\t{$src, $dst}",
- [(store (i16 (load addr:$src)), addr:$dst)]>;
+def MOV8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "mov.b\t{$src, $dst}",
+ [(store (i8 imm:$src), addr:$dst)]>;
+def MOV16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "mov.w\t{$src, $dst}",
+ [(store (i16 imm:$src), addr:$dst)]>;
+
+def MOV8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "mov.b\t{$src, $dst}",
+ [(store GR8:$src, addr:$dst)]>;
+def MOV16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "mov.w\t{$src, $dst}",
+ [(store GR16:$src, addr:$dst)]>;
+
+def MOV8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "mov.b\t{$src, $dst}",
+ [(store (i8 (load addr:$src)), addr:$dst)]>;
+def MOV16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "mov.w\t{$src, $dst}",
+ [(store (i16 (load addr:$src)), addr:$dst)]>;
//===----------------------------------------------------------------------===//
// Arithmetic Instructions
@@ -297,496 +329,624 @@ let isTwoAddress = 1 in {
let Defs = [SRW] in {
let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y
-// FIXME: Provide proper encoding!
-def ADD8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "add.b\t{$src2, $dst}",
- [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def ADD16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "add.w\t{$src2, $dst}",
- [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+
+def ADD8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "add.b\t{$src2, $dst}",
+ [(set GR8:$dst, (add GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def ADD16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "add.w\t{$src2, $dst}",
+ [(set GR16:$dst, (add GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
}
-def ADD8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "add.b\t{$src2, $dst}",
- [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def ADD16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "add.w\t{$src2, $dst}",
- [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def ADD8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "add.b\t{$src2, $dst}",
+ [(set GR8:$dst, (add GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def ADD16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "add.w\t{$src2, $dst}",
+ [(set GR16:$dst, (add GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def ADD8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
- "add.b\t{@$base+, $dst}", []>;
-def ADD16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
+def ADD8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
+ "add.b\t{@$base+, $dst}", []>;
+def ADD16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
"add.w\t{@$base+, $dst}", []>;
}
-def ADD8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "add.b\t{$src2, $dst}",
- [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def ADD16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "add.w\t{$src2, $dst}",
- [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
+def ADD8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "add.b\t{$src2, $dst}",
+ [(set GR8:$dst, (add GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def ADD16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "add.w\t{$src2, $dst}",
+ [(set GR16:$dst, (add GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
let isTwoAddress = 0 in {
-def ADD8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "add.b\t{$src, $dst}",
- [(store (add (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def ADD16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "add.w\t{$src, $dst}",
- [(store (add (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def ADD8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "add.b\t{$src, $dst}",
- [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def ADD16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "add.w\t{$src, $dst}",
- [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def ADD8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "add.b\t{$src, $dst}",
- [(store (add (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def ADD16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "add.w\t{$src, $dst}",
- [(store (add (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def ADD8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "add.b\t{$src, $dst}",
+ [(store (add (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def ADD16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "add.w\t{$src, $dst}",
+ [(store (add (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def ADD8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "add.b\t{$src, $dst}",
+ [(store (add (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def ADD16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "add.w\t{$src, $dst}",
+ [(store (add (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def ADD8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "add.b\t{$src, $dst}",
+ [(store (add (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def ADD16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "add.w\t{$src, $dst}",
+ [(store (add (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
let Uses = [SRW] in {
let isCommutable = 1 in { // X = ADDC Y, Z == X = ADDC Z, Y
-def ADC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "addc.b\t{$src2, $dst}",
- [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def ADC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "addc.w\t{$src2, $dst}",
- [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+def ADC8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "addc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (adde GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def ADC16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "addc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (adde GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
} // isCommutable
-def ADC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "addc.b\t{$src2, $dst}",
- [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def ADC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "addc.w\t{$src2, $dst}",
- [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def ADC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "addc.b\t{$src2, $dst}",
- [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def ADC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "addc.w\t{$src2, $dst}",
- [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def ADC8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "addc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (adde GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def ADC16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "addc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (adde GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def ADC8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "addc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (adde GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def ADC16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "addc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (adde GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let isTwoAddress = 0 in {
-def ADC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "addc.b\t{$src, $dst}",
- [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def ADC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "addc.w\t{$src, $dst}",
- [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def ADC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "addc.b\t{$src, $dst}",
- [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def ADC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "addc.w\t{$src, $dst}",
- [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def ADC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "addc.b\t{$src, $dst}",
- [(store (adde (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def ADC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "addc.w\t{$src, $dst}",
- [(store (adde (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def ADC8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "addc.b\t{$src, $dst}",
+ [(store (adde (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def ADC16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "addc.w\t{$src, $dst}",
+ [(store (adde (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def ADC8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "addc.b\t{$src, $dst}",
+ [(store (adde (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def ADC16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "addc.w\t{$src, $dst}",
+ [(store (adde (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def ADC8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "addc.b\t{$src, $dst}",
+ [(store (adde (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def ADC16mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "addc.w\t{$src, $dst}",
+ [(store (adde (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
} // Uses = [SRW]
let isCommutable = 1 in { // X = AND Y, Z == X = AND Z, Y
-def AND8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "and.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def AND16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "and.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+def AND8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "and.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def AND16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "and.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
}
-def AND8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "and.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def AND16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "and.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def AND8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "and.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def AND16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "and.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def AND8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "and.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def AND16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "and.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def AND8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "and.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def AND16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "and.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def AND8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
- "and.b\t{@$base+, $dst}", []>;
-def AND16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
- "and.w\t{@$base+, $dst}", []>;
+def AND8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
+ "and.b\t{@$base+, $dst}", []>;
+def AND16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
+ "and.w\t{@$base+, $dst}", []>;
}
let isTwoAddress = 0 in {
-def AND8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "and.b\t{$src, $dst}",
- [(store (and (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def AND16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "and.w\t{$src, $dst}",
- [(store (and (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def AND8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "and.b\t{$src, $dst}",
- [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def AND16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "and.w\t{$src, $dst}",
- [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def AND8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "and.b\t{$src, $dst}",
- [(store (and (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def AND16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "and.w\t{$src, $dst}",
- [(store (and (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def AND8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "and.b\t{$src, $dst}",
+ [(store (and (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def AND16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "and.w\t{$src, $dst}",
+ [(store (and (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def AND8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "and.b\t{$src, $dst}",
+ [(store (and (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def AND16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "and.w\t{$src, $dst}",
+ [(store (and (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def AND8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "and.b\t{$src, $dst}",
+ [(store (and (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def AND16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "and.w\t{$src, $dst}",
+ [(store (and (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
let isCommutable = 1 in { // X = OR Y, Z == X = OR Z, Y
-def OR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "bis.b\t{$src2, $dst}",
- [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
-def OR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "bis.w\t{$src2, $dst}",
- [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
+def OR8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "bis.b\t{$src2, $dst}",
+ [(set GR8:$dst, (or GR8:$src1, GR8:$src2))]>;
+def OR16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "bis.w\t{$src2, $dst}",
+ [(set GR16:$dst, (or GR16:$src1, GR16:$src2))]>;
}
-def OR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "bis.b\t{$src2, $dst}",
- [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
-def OR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "bis.w\t{$src2, $dst}",
- [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
-
-def OR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "bis.b\t{$src2, $dst}",
- [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
-def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "bis.w\t{$src2, $dst}",
- [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
+def OR8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "bis.b\t{$src2, $dst}",
+ [(set GR8:$dst, (or GR8:$src1, imm:$src2))]>;
+def OR16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "bis.w\t{$src2, $dst}",
+ [(set GR16:$dst, (or GR16:$src1, imm:$src2))]>;
+
+def OR8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "bis.b\t{$src2, $dst}",
+ [(set GR8:$dst, (or GR8:$src1, (load addr:$src2)))]>;
+def OR16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "bis.w\t{$src2, $dst}",
+ [(set GR16:$dst, (or GR16:$src1, (load addr:$src2)))]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def OR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
+def OR8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
"bis.b\t{@$base+, $dst}", []>;
-def OR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
- "bis.w\t{@$base+, $dst}", []>;
+def OR16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
+ "bis.w\t{@$base+, $dst}", []>;
}
let isTwoAddress = 0 in {
-def OR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "bis.b\t{$src, $dst}",
- [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
-def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "bis.w\t{$src, $dst}",
- [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>;
-
-def OR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "bis.b\t{$src, $dst}",
- [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>;
-def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "bis.w\t{$src, $dst}",
- [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>;
-
-def OR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "bis.b\t{$src, $dst}",
- [(store (or (i8 (load addr:$dst)),
- (i8 (load addr:$src))), addr:$dst)]>;
-def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "bis.w\t{$src, $dst}",
- [(store (or (i16 (load addr:$dst)),
- (i16 (load addr:$src))), addr:$dst)]>;
+def OR8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "bis.b\t{$src, $dst}",
+ [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>;
+def OR16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "bis.w\t{$src, $dst}",
+ [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>;
+
+def OR8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "bis.b\t{$src, $dst}",
+ [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>;
+def OR16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "bis.w\t{$src, $dst}",
+ [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>;
+
+def OR8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "bis.b\t{$src, $dst}",
+ [(store (or (i8 (load addr:$dst)),
+ (i8 (load addr:$src))), addr:$dst)]>;
+def OR16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "bis.w\t{$src, $dst}",
+ [(store (or (i16 (load addr:$dst)),
+ (i16 (load addr:$src))), addr:$dst)]>;
}
// bic does not modify condition codes
-def BIC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "bic.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, (not GR8:$src2)))]>;
-def BIC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "bic.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, (not GR16:$src2)))]>;
-
-def BIC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "bic.b\t{$src2, $dst}",
- [(set GR8:$dst, (and GR8:$src1, (not (i8 (load addr:$src2)))))]>;
-def BIC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "bic.w\t{$src2, $dst}",
- [(set GR16:$dst, (and GR16:$src1, (not (i16 (load addr:$src2)))))]>;
+def BIC8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "bic.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, (not GR8:$src2)))]>;
+def BIC16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "bic.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, (not GR16:$src2)))]>;
+
+def BIC8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "bic.b\t{$src2, $dst}",
+ [(set GR8:$dst, (and GR8:$src1, (not (i8 (load addr:$src2)))))]>;
+def BIC16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "bic.w\t{$src2, $dst}",
+ [(set GR16:$dst, (and GR16:$src1, (not (i16 (load addr:$src2)))))]>;
let isTwoAddress = 0 in {
-def BIC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "bic.b\t{$src, $dst}",
- [(store (and (load addr:$dst), (not GR8:$src)), addr:$dst)]>;
-def BIC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "bic.w\t{$src, $dst}",
- [(store (and (load addr:$dst), (not GR16:$src)), addr:$dst)]>;
-
-def BIC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "bic.b\t{$src, $dst}",
- [(store (and (load addr:$dst), (not (i8 (load addr:$src)))), addr:$dst)]>;
-def BIC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "bic.w\t{$src, $dst}",
- [(store (and (load addr:$dst), (not (i16 (load addr:$src)))), addr:$dst)]>;
+def BIC8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "bic.b\t{$src, $dst}",
+ [(store (and (load addr:$dst), (not GR8:$src)), addr:$dst)]>;
+def BIC16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "bic.w\t{$src, $dst}",
+ [(store (and (load addr:$dst), (not GR16:$src)), addr:$dst)]>;
+
+def BIC8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "bic.b\t{$src, $dst}",
+ [(store (and (load addr:$dst),
+ (not (i8 (load addr:$src)))), addr:$dst)]>;
+def BIC16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "bic.w\t{$src, $dst}",
+ [(store (and (load addr:$dst),
+ (not (i16 (load addr:$src)))), addr:$dst)]>;
}
let isCommutable = 1 in { // X = XOR Y, Z == X = XOR Z, Y
-def XOR8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "xor.b\t{$src2, $dst}",
- [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def XOR16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "xor.w\t{$src2, $dst}",
- [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+def XOR8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "xor.b\t{$src2, $dst}",
+ [(set GR8:$dst, (xor GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def XOR16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "xor.w\t{$src2, $dst}",
+ [(set GR16:$dst, (xor GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
}
-def XOR8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "xor.b\t{$src2, $dst}",
- [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def XOR16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "xor.w\t{$src2, $dst}",
- [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def XOR8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "xor.b\t{$src2, $dst}",
- [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def XOR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "xor.w\t{$src2, $dst}",
- [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def XOR8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "xor.b\t{$src2, $dst}",
+ [(set GR8:$dst, (xor GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def XOR16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "xor.w\t{$src2, $dst}",
+ [(set GR16:$dst, (xor GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def XOR8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "xor.b\t{$src2, $dst}",
+ [(set GR8:$dst, (xor GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def XOR16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "xor.w\t{$src2, $dst}",
+ [(set GR16:$dst, (xor GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def XOR8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
- "xor.b\t{@$base+, $dst}", []>;
-def XOR16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
- "xor.w\t{@$base+, $dst}", []>;
+def XOR8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
+ "xor.b\t{@$base+, $dst}", []>;
+def XOR16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
+ "xor.w\t{@$base+, $dst}", []>;
}
let isTwoAddress = 0 in {
-def XOR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "xor.b\t{$src, $dst}",
- [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def XOR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "xor.w\t{$src, $dst}",
- [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def XOR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "xor.b\t{$src, $dst}",
- [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def XOR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "xor.w\t{$src, $dst}",
- [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def XOR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "xor.b\t{$src, $dst}",
- [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def XOR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "xor.w\t{$src, $dst}",
- [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def XOR8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "xor.b\t{$src, $dst}",
+ [(store (xor (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def XOR16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "xor.w\t{$src, $dst}",
+ [(store (xor (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def XOR8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "xor.b\t{$src, $dst}",
+ [(store (xor (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def XOR16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "xor.w\t{$src, $dst}",
+ [(store (xor (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def XOR8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "xor.b\t{$src, $dst}",
+ [(store (xor (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def XOR16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "xor.w\t{$src, $dst}",
+ [(store (xor (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
-def SUB8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "sub.b\t{$src2, $dst}",
- [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def SUB16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "sub.w\t{$src2, $dst}",
- [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
-
-def SUB8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "sub.b\t{$src2, $dst}",
- [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def SUB16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "sub.w\t{$src2, $dst}",
- [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def SUB8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "sub.b\t{$src2, $dst}",
- [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def SUB16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "sub.w\t{$src2, $dst}",
- [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def SUB8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "sub.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sub GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def SUB16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "sub.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sub GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
+
+def SUB8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "sub.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sub GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def SUB16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "sub.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sub GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def SUB8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "sub.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sub GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def SUB16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "sub.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sub GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let mayLoad = 1, hasExtraDefRegAllocReq = 1,
Constraints = "$base = $base_wb, $src1 = $dst" in {
-def SUB8rm_POST : Pseudo<(outs GR8:$dst, GR16:$base_wb), (ins GR8:$src1, GR16:$base),
- "sub.b\t{@$base+, $dst}", []>;
-def SUB16rm_POST : Pseudo<(outs GR16:$dst, GR16:$base_wb), (ins GR16:$src1, GR16:$base),
+def SUB8rm_POST : IForm8<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR8:$dst, GR16:$base_wb),
+ (ins GR8:$src1, GR16:$base),
+ "sub.b\t{@$base+, $dst}", []>;
+def SUB16rm_POST : IForm16<0x0, DstReg, SrcPostInc, Size2Bytes,
+ (outs GR16:$dst, GR16:$base_wb),
+ (ins GR16:$src1, GR16:$base),
"sub.w\t{@$base+, $dst}", []>;
}
let isTwoAddress = 0 in {
-def SUB8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "sub.b\t{$src, $dst}",
- [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def SUB16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "sub.w\t{$src, $dst}",
- [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def SUB8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "sub.b\t{$src, $dst}",
- [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def SUB16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "sub.w\t{$src, $dst}",
- [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def SUB8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "sub.b\t{$src, $dst}",
- [(store (sub (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def SUB16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "sub.w\t{$src, $dst}",
- [(store (sub (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def SUB8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "sub.b\t{$src, $dst}",
+ [(store (sub (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def SUB16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "sub.w\t{$src, $dst}",
+ [(store (sub (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def SUB8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "sub.b\t{$src, $dst}",
+ [(store (sub (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def SUB16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "sub.w\t{$src, $dst}",
+ [(store (sub (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def SUB8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "sub.b\t{$src, $dst}",
+ [(store (sub (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def SUB16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "sub.w\t{$src, $dst}",
+ [(store (sub (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
let Uses = [SRW] in {
-def SBC8rr : Pseudo<(outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
- "subc.b\t{$src2, $dst}",
- [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def SBC16rr : Pseudo<(outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
- "subc.w\t{$src2, $dst}",
- [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
-
-def SBC8ri : Pseudo<(outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
- "subc.b\t{$src2, $dst}",
- [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def SBC16ri : Pseudo<(outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
- "subc.w\t{$src2, $dst}",
- [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def SBC8rm : Pseudo<(outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
- "subc.b\t{$src2, $dst}",
- [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def SBC16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
- "subc.w\t{$src2, $dst}",
- [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
+def SBC8rr : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, GR8:$src2),
+ "subc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sube GR8:$src1, GR8:$src2)),
+ (implicit SRW)]>;
+def SBC16rr : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
+ "subc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sube GR16:$src1, GR16:$src2)),
+ (implicit SRW)]>;
+
+def SBC8ri : I8ri<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
+ "subc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sube GR8:$src1, imm:$src2)),
+ (implicit SRW)]>;
+def SBC16ri : I16ri<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
+ "subc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sube GR16:$src1, imm:$src2)),
+ (implicit SRW)]>;
+
+def SBC8rm : I8rm<0x0,
+ (outs GR8:$dst), (ins GR8:$src1, memsrc:$src2),
+ "subc.b\t{$src2, $dst}",
+ [(set GR8:$dst, (sube GR8:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
+def SBC16rm : I16rm<0x0,
+ (outs GR16:$dst), (ins GR16:$src1, memsrc:$src2),
+ "subc.w\t{$src2, $dst}",
+ [(set GR16:$dst, (sube GR16:$src1, (load addr:$src2))),
+ (implicit SRW)]>;
let isTwoAddress = 0 in {
-def SBC8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src),
- "subc.b\t{$src, $dst}",
- [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
- (implicit SRW)]>;
-def SBC16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src),
- "subc.w\t{$src, $dst}",
- [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
- (implicit SRW)]>;
-
-def SBC8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src),
- "subc.b\t{$src, $dst}",
- [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-def SBC16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src),
- "subc.w\t{$src, $dst}",
- [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
- (implicit SRW)]>;
-
-def SBC8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "subc.b\t{$src, $dst}",
- [(store (sube (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
-def SBC16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src),
- "subc.w\t{$src, $dst}",
- [(store (sube (load addr:$dst), (i16 (load addr:$src))), addr:$dst),
- (implicit SRW)]>;
+def SBC8mr : I8mr<0x0,
+ (outs), (ins memdst:$dst, GR8:$src),
+ "subc.b\t{$src, $dst}",
+ [(store (sube (load addr:$dst), GR8:$src), addr:$dst),
+ (implicit SRW)]>;
+def SBC16mr : I16mr<0x0,
+ (outs), (ins memdst:$dst, GR16:$src),
+ "subc.w\t{$src, $dst}",
+ [(store (sube (load addr:$dst), GR16:$src), addr:$dst),
+ (implicit SRW)]>;
+
+def SBC8mi : I8mi<0x0,
+ (outs), (ins memdst:$dst, i8imm:$src),
+ "subc.b\t{$src, $dst}",
+ [(store (sube (load addr:$dst), (i8 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+def SBC16mi : I16mi<0x0,
+ (outs), (ins memdst:$dst, i16imm:$src),
+ "subc.w\t{$src, $dst}",
+ [(store (sube (load addr:$dst), (i16 imm:$src)), addr:$dst),
+ (implicit SRW)]>;
+
+def SBC8mm : I8mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "subc.b\t{$src, $dst}",
+ [(store (sube (load addr:$dst),
+ (i8 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
+def SBC16mm : I16mm<0x0,
+ (outs), (ins memdst:$dst, memsrc:$src),
+ "subc.w\t{$src, $dst}",
+ [(store (sube (load addr:$dst),
+ (i16 (load addr:$src))), addr:$dst),
+ (implicit SRW)]>;
}
} // Uses = [SRW]
-// FIXME: Provide proper encoding!
-def SAR8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src),
- "rra.b\t$dst",
- [(set GR8:$dst, (MSP430rra GR8:$src)),
- (implicit SRW)]>;
-def SAR16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "rra.w\t$dst",
- [(set GR16:$dst, (MSP430rra GR16:$src)),
- (implicit SRW)]>;
-
-def SHL8r1 : Pseudo<(outs GR8:$dst), (ins GR8:$src),
- "rla.b\t$dst",
- [(set GR8:$dst, (MSP430rla GR8:$src)),
- (implicit SRW)]>;
-def SHL16r1 : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "rla.w\t$dst",
- [(set GR16:$dst, (MSP430rla GR16:$src)),
- (implicit SRW)]>;
+// FIXME: memory variant!
+def SAR8r1 : II8r<0x0,
+ (outs GR8:$dst), (ins GR8:$src),
+ "rra.b\t$dst",
+ [(set GR8:$dst, (MSP430rra GR8:$src)),
+ (implicit SRW)]>;
+def SAR16r1 : II16r<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "rra.w\t$dst",
+ [(set GR16:$dst, (MSP430rra GR16:$src)),
+ (implicit SRW)]>;
+
+def SHL8r1 : I8rr<0x0,
+ (outs GR8:$dst), (ins GR8:$src),
+ "rla.b\t$dst",
+ [(set GR8:$dst, (MSP430rla GR8:$src)),
+ (implicit SRW)]>;
+def SHL16r1 : I16rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "rla.w\t$dst",
+ [(set GR16:$dst, (MSP430rla GR16:$src)),
+ (implicit SRW)]>;
def SAR8r1c : Pseudo<(outs GR8:$dst), (ins GR8:$src),
"clrc\n\t"
@@ -799,121 +959,154 @@ def SAR16r1c : Pseudo<(outs GR16:$dst), (ins GR16:$src),
[(set GR16:$dst, (MSP430rrc GR16:$src)),
(implicit SRW)]>;
-def SEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "sxt\t$dst",
- [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
- (implicit SRW)]>;
+// FIXME: Memory sext's ?
+def SEXT16r : II16r<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "sxt\t$dst",
+ [(set GR16:$dst, (sext_inreg GR16:$src, i8)),
+ (implicit SRW)]>;
} // Defs = [SRW]
-def ZEXT16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "mov.b\t{$src, $dst}",
- [(set GR16:$dst, (zext (trunc GR16:$src)))]>;
+def ZEXT16r : I8rr<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "mov.b\t{$src, $dst}",
+ [(set GR16:$dst, (zext (trunc GR16:$src)))]>;
-def SWPB16r : Pseudo<(outs GR16:$dst), (ins GR16:$src),
- "swpb\t$dst",
- [(set GR16:$dst, (bswap GR16:$src))]>;
+// FIXME: Memory bitswaps?
+def SWPB16r : II16r<0x0,
+ (outs GR16:$dst), (ins GR16:$src),
+ "swpb\t$dst",
+ [(set GR16:$dst, (bswap GR16:$src))]>;
} // isTwoAddress = 1
// Integer comparisons
let Defs = [SRW] in {
-def CMP8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
- "cmp.b\t{$src2, $src1}",
- [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
-def CMP16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
-
-def CMP8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2),
+def CMP8rr : I8rr<0x0,
+ (outs), (ins GR8:$src1, GR8:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp GR8:$src1, GR8:$src2), (implicit SRW)]>;
+def CMP16rr : I16rr<0x0,
+ (outs), (ins GR16:$src1, GR16:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp GR16:$src1, GR16:$src2), (implicit SRW)]>;
+
+def CMP8ri : I8ri<0x0,
+ (outs), (ins GR8:$src1, i8imm:$src2),
"cmp.b\t{$src2, $src1}",
[(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>;
-def CMP16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>;
-
-def CMP8mi : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2),
- "cmp.b\t{$src2, $src1}",
- [(MSP430cmp (load addr:$src1),
- (i8 imm:$src2)), (implicit SRW)]>;
-def CMP16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp (load addr:$src1),
- (i16 imm:$src2)), (implicit SRW)]>;
-
-def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2),
- "cmp.b\t{$src2, $src1}",
- [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>;
-def CMP16rm : Pseudo<(outs), (ins GR16:$src1, memsrc:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp GR16:$src1, (load addr:$src2)), (implicit SRW)]>;
-
-def CMP8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
- "cmp.b\t{$src2, $src1}",
- [(MSP430cmp (load addr:$src1), GR8:$src2), (implicit SRW)]>;
-def CMP16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
- "cmp.w\t{$src2, $src1}",
- [(MSP430cmp (load addr:$src1), GR16:$src2), (implicit SRW)]>;
+def CMP16ri : I16ri<0x0,
+ (outs), (ins GR16:$src1, i16imm:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>;
+
+def CMP8mi : I8mi<0x0,
+ (outs), (ins memsrc:$src1, i8imm:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1),
+ (i8 imm:$src2)), (implicit SRW)]>;
+def CMP16mi : I16mi<0x0,
+ (outs), (ins memsrc:$src1, i16imm:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1),
+ (i16 imm:$src2)), (implicit SRW)]>;
+
+def CMP8rm : I8rm<0x0,
+ (outs), (ins GR8:$src1, memsrc:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp GR8:$src1, (load addr:$src2)),
+ (implicit SRW)]>;
+def CMP16rm : I16rm<0x0,
+ (outs), (ins GR16:$src1, memsrc:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp GR16:$src1, (load addr:$src2)),
+ (implicit SRW)]>;
+
+def CMP8mr : I8mr<0x0,
+ (outs), (ins memsrc:$src1, GR8:$src2),
+ "cmp.b\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1), GR8:$src2),
+ (implicit SRW)]>;
+def CMP16mr : I16mr<0x0,
+ (outs), (ins memsrc:$src1, GR16:$src2),
+ "cmp.w\t{$src2, $src1}",
+ [(MSP430cmp (load addr:$src1), GR16:$src2),
+ (implicit SRW)]>;
// BIT TESTS, just sets condition codes
// Note that the C condition is set differently than when using CMP.
let isCommutable = 1 in {
-def BIT8rr : Pseudo<(outs), (ins GR8:$src1, GR8:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR8:$src1, GR8:$src2)),
- (implicit SRW)]>;
-def BIT16rr : Pseudo<(outs), (ins GR16:$src1, GR16:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR16:$src1, GR16:$src2)),
- (implicit SRW)]>;
+def BIT8rr : I8rr<0x0,
+ (outs), (ins GR8:$src1, GR8:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR8:$src1, GR8:$src2), 0),
+ (implicit SRW)]>;
+def BIT16rr : I16rr<0x0,
+ (outs), (ins GR16:$src1, GR16:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR16:$src1, GR16:$src2), 0),
+ (implicit SRW)]>;
}
-def BIT8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR8:$src1, imm:$src2)),
- (implicit SRW)]>;
-def BIT16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR16:$src1, imm:$src2)),
- (implicit SRW)]>;
-
-def BIT8rm : Pseudo<(outs), (ins GR8:$src1, memdst:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR8:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-def BIT16rm : Pseudo<(outs), (ins GR16:$src1, memdst:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su GR16:$src1, (load addr:$src2))),
- (implicit SRW)]>;
-
-def BIT8mr : Pseudo<(outs), (ins memsrc:$src1, GR8:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (load addr:$src1), GR8:$src2)),
- (implicit SRW)]>;
-def BIT16mr : Pseudo<(outs), (ins memsrc:$src1, GR16:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (load addr:$src1), GR16:$src2)),
- (implicit SRW)]>;
-
-def BIT8mi : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (load addr:$src1), (i8 imm:$src2))),
- (implicit SRW)]>;
-def BIT16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (load addr:$src1), (i16 imm:$src2))),
- (implicit SRW)]>;
-
-def BIT8mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
- "bit.b\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (i8 (load addr:$src1)),
- (load addr:$src2))),
- (implicit SRW)]>;
-def BIT16mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
- "bit.w\t{$src2, $src1}",
- [(MSP430cmp 0, (and_su (i16 (load addr:$src1)),
- (load addr:$src2))),
+def BIT8ri : I8ri<0x0,
+ (outs), (ins GR8:$src1, i8imm:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR8:$src1, imm:$src2), 0),
+ (implicit SRW)]>;
+def BIT16ri : I16ri<0x0,
+ (outs), (ins GR16:$src1, i16imm:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR16:$src1, imm:$src2), 0),
+ (implicit SRW)]>;
+
+def BIT8rm : I8rm<0x0,
+ (outs), (ins GR8:$src1, memdst:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR8:$src1, (load addr:$src2)), 0),
+ (implicit SRW)]>;
+def BIT16rm : I16rm<0x0,
+ (outs), (ins GR16:$src1, memdst:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su GR16:$src1, (load addr:$src2)), 0),
+ (implicit SRW)]>;
+
+def BIT8mr : I8mr<0x0,
+ (outs), (ins memsrc:$src1, GR8:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su (load addr:$src1), GR8:$src2), 0),
+ (implicit SRW)]>;
+def BIT16mr : I16mr<0x0,
+ (outs), (ins memsrc:$src1, GR16:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su (load addr:$src1), GR16:$src2), 0),
+ (implicit SRW)]>;
+
+def BIT8mi : I8mi<0x0,
+ (outs), (ins memsrc:$src1, i8imm:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su (load addr:$src1), (i8 imm:$src2)), 0),
+ (implicit SRW)]>;
+def BIT16mi : I16mi<0x0,
+ (outs), (ins memsrc:$src1, i16imm:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su (load addr:$src1), (i16 imm:$src2)), 0),
+ (implicit SRW)]>;
+
+def BIT8mm : I8mm<0x0,
+ (outs), (ins memsrc:$src1, memsrc:$src2),
+ "bit.b\t{$src2, $src1}",
+ [(MSP430cmp (and_su (i8 (load addr:$src1)),
+ (load addr:$src2)),
+ 0),
(implicit SRW)]>;
+def BIT16mm : I16mm<0x0,
+ (outs), (ins memsrc:$src1, memsrc:$src2),
+ "bit.w\t{$src2, $src1}",
+ [(MSP430cmp (and_su (i16 (load addr:$src1)),
+ (load addr:$src2)),
+ 0),
+ (implicit SRW)]>;
} // Defs = [SRW]
//===----------------------------------------------------------------------===//
@@ -923,7 +1116,8 @@ def BIT16mm : Pseudo<(outs), (ins memsrc:$src1, memsrc:$src2),
def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
// anyext
-def : Pat<(anyext addr:$src), (MOVZX16rr8 GR8:$src)>;
+def : Pat<(i16 (anyext GR8:$src)),
+ (SUBREG_TO_REG (i16 0), GR8:$src, subreg_8bit)>;
// truncs
def : Pat<(i8 (trunc GR16:$src)),
@@ -996,6 +1190,6 @@ def : Pat<(store (subc (load addr:$dst), (i8 (load addr:$src))), addr:$dst),
// peephole patterns
def : Pat<(and GR16:$src, 255), (ZEXT16r GR16:$src)>;
-def : Pat<(MSP430cmp 0, (trunc (and_su GR16:$src1, GR16:$src2))),
+def : Pat<(MSP430cmp (trunc (and_su GR16:$src1, GR16:$src2)), 0),
(BIT8rr (EXTRACT_SUBREG GR16:$src1, subreg_8bit),
(EXTRACT_SUBREG GR16:$src2, subreg_8bit))>;
diff --git a/lib/Target/MSP430/MSP430TargetMachine.cpp b/lib/Target/MSP430/MSP430TargetMachine.cpp
index 14db406..a0dbac2 100644
--- a/lib/Target/MSP430/MSP430TargetMachine.cpp
+++ b/lib/Target/MSP430/MSP430TargetMachine.cpp
@@ -44,3 +44,9 @@ bool MSP430TargetMachine::addInstSelector(PassManagerBase &PM,
return false;
}
+bool MSP430TargetMachine::addPreEmitPass(PassManagerBase &PM,
+ CodeGenOpt::Level OptLevel) {
+ // Must run branch selection immediately preceding the asm printer.
+ PM.add(createMSP430BranchSelectionPass());
+ return false;
+}
diff --git a/lib/Target/MSP430/MSP430TargetMachine.h b/lib/Target/MSP430/MSP430TargetMachine.h
index d386140..d93ac5c 100644
--- a/lib/Target/MSP430/MSP430TargetMachine.h
+++ b/lib/Target/MSP430/MSP430TargetMachine.h
@@ -55,6 +55,7 @@ public:
}
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
+ virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
}; // MSP430TargetMachine.
} // end namespace llvm
diff --git a/lib/Target/MSP430/Makefile b/lib/Target/MSP430/Makefile
index 4b18bc9..11195a4 100644
--- a/lib/Target/MSP430/Makefile
+++ b/lib/Target/MSP430/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMMSP430CodeGen
TARGET = MSP430
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = MSP430GenRegisterInfo.h.inc MSP430GenRegisterNames.inc \
diff --git a/lib/Target/MSP430/TargetInfo/Makefile b/lib/Target/MSP430/TargetInfo/Makefile
index abb08f2..d17fa7b 100644
--- a/lib/Target/MSP430/TargetInfo/Makefile
+++ b/lib/Target/MSP430/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMSP430Info
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Makefile b/lib/Target/Makefile
index 50a360f..281d58b 100644
--- a/lib/Target/Makefile
+++ b/lib/Target/Makefile
@@ -10,6 +10,7 @@
LEVEL = ../..
LIBRARYNAME = LLVMTarget
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
# We include this early so we can access the value of TARGETS_TO_BUILD as the
# value for PARALLEL_DIRS which must be set before Makefile.rules is included
diff --git a/lib/Target/Mangler.cpp b/lib/Target/Mangler.cpp
new file mode 100644
index 0000000..ef6defc
--- /dev/null
+++ b/lib/Target/Mangler.cpp
@@ -0,0 +1,179 @@
+//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unified name mangler for assembly backends.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/Mangler.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+using namespace llvm;
+
+static bool isAcceptableChar(char C) {
+ if ((C < 'a' || C > 'z') &&
+ (C < 'A' || C > 'Z') &&
+ (C < '0' || C > '9') &&
+ C != '_' && C != '$' && C != '.' && C != '@')
+ return false;
+ return true;
+}
+
+static char HexDigit(int V) {
+ return V < 10 ? V+'0' : V+'A'-10;
+}
+
+static void MangleLetter(SmallVectorImpl<char> &OutName, unsigned char C) {
+ OutName.push_back('_');
+ OutName.push_back(HexDigit(C >> 4));
+ OutName.push_back(HexDigit(C & 15));
+ OutName.push_back('_');
+}
+
+/// NameNeedsEscaping - Return true if the identifier \arg Str needs quotes
+/// for this assembler.
+static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
+ assert(!Str.empty() && "Cannot create an empty MCSymbol");
+
+ // If the first character is a number and the target does not allow this, we
+ // need quotes.
+ if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9')
+ return true;
+
+ // If any of the characters in the string is an unacceptable character, force
+ // quotes.
+ for (unsigned i = 0, e = Str.size(); i != e; ++i)
+ if (!isAcceptableChar(Str[i]))
+ return true;
+ return false;
+}
+
+/// 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) {
+ // 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') {
+ MangleLetter(OutName, Str[0]);
+ Str = Str.substr(1);
+ }
+
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ if (!isAcceptableChar(Str[i]))
+ MangleLetter(OutName, Str[i]);
+ else
+ OutName.push_back(Str[i]);
+ }
+}
+
+
+/// appendMangledQuotedName - On systems that support quoted symbols, we still
+/// have to escape some (obscure) characters like " and \n which would break the
+/// assembler's lexing.
+static void appendMangledQuotedName(SmallVectorImpl<char> &OutName,
+ StringRef Str) {
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ if (Str[i] == '"' || Str[i] == '\n')
+ MangleLetter(OutName, Str[i]);
+ else
+ OutName.push_back(Str[i]);
+ }
+}
+
+
+/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
+/// and the specified name as the global variable name. GVName must not be
+/// empty.
+void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
+ const Twine &GVName, ManglerPrefixTy PrefixTy) {
+ SmallString<256> TmpData;
+ StringRef Name = GVName.toStringRef(TmpData);
+ assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
+
+ // If the global name is not led with \1, add the appropriate prefixes.
+ if (Name[0] == '\1') {
+ Name = Name.substr(1);
+ } else {
+ if (PrefixTy == Mangler::Private) {
+ const char *Prefix = MAI.getPrivateGlobalPrefix();
+ OutName.append(Prefix, Prefix+strlen(Prefix));
+ } else if (PrefixTy == Mangler::LinkerPrivate) {
+ const char *Prefix = MAI.getLinkerPrivateGlobalPrefix();
+ OutName.append(Prefix, Prefix+strlen(Prefix));
+ }
+
+ const char *Prefix = MAI.getGlobalPrefix();
+ if (Prefix[0] == 0)
+ ; // Common noop, no prefix.
+ else if (Prefix[1] == 0)
+ OutName.push_back(Prefix[0]); // Common, one character prefix.
+ else
+ OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary length prefix.
+ }
+
+ // If this is a simple string that doesn't need escaping, just append it.
+ if (!NameNeedsEscaping(Name, MAI) ||
+ // If quotes are supported, they can be used unless the string contains
+ // a quote or newline.
+ (MAI.doesAllowQuotesInName() &&
+ Name.find_first_of("\n\"") == StringRef::npos)) {
+ OutName.append(Name.begin(), Name.end());
+ return;
+ }
+
+ // On systems that do not allow quoted names, we need to mangle most
+ // strange characters.
+ if (!MAI.doesAllowQuotesInName())
+ 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.
+ assert(Name.find_first_of("\n\"") != StringRef::npos);
+ return appendMangledQuotedName(OutName, Name);
+}
+
+
+/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
+/// and the specified global variable's name. If the global variable doesn't
+/// have a name, this fills in a unique name for the global.
+void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
+ const GlobalValue *GV,
+ bool isImplicitlyPrivate) {
+ ManglerPrefixTy PrefixTy = Mangler::Default;
+ if (GV->hasPrivateLinkage() || isImplicitlyPrivate)
+ PrefixTy = Mangler::Private;
+ else if (GV->hasLinkerPrivateLinkage())
+ PrefixTy = Mangler::LinkerPrivate;
+
+ // If this global has a name, handle it simply.
+ if (GV->hasName())
+ return getNameWithPrefix(OutName, GV->getName(), PrefixTy);
+
+ // 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);
+}
+
+/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
+/// and the specified global variable's name. If the global variable doesn't
+/// have a name, this fills in a unique name for the global.
+std::string Mangler::getNameWithPrefix(const GlobalValue *GV,
+ bool isImplicitlyPrivate) {
+ SmallString<64> Buf;
+ getNameWithPrefix(Buf, GV, isImplicitlyPrivate);
+ return std::string(Buf.begin(), Buf.end());
+}
diff --git a/lib/Target/Mips/AsmPrinter/Makefile b/lib/Target/Mips/AsmPrinter/Makefile
index a2fecf4..aed801e 100644
--- a/lib/Target/Mips/AsmPrinter/Makefile
+++ b/lib/Target/Mips/AsmPrinter/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMMipsAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' Mips target directory to grab
# private headers
diff --git a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
index efd3fb7..9af9bd8 100644
--- a/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/AsmPrinter/MipsAsmPrinter.cpp
@@ -37,7 +37,6 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
@@ -45,7 +44,6 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MathExtras.h"
#include <cctype>
-
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -72,7 +70,6 @@ namespace {
const char *Modifier = 0);
void printFCCOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
- void PrintGlobalVariable(const GlobalVariable *GVar);
void printSavedRegsBitmask(MachineFunction &MF);
void printHex32(unsigned int Value);
@@ -219,15 +216,15 @@ void MipsAsmPrinter::emitFunctionStart(MachineFunction &MF) {
// 2 bits aligned
EmitAlignment(MF.getAlignment(), F);
- O << "\t.globl\t" << CurrentFnName << '\n';
- O << "\t.ent\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
+ O << "\t.ent\t" << *CurrentFnSym << '\n';
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
if ((MAI->hasDotTypeDotSizeDirective()) && Subtarget->isLinux())
- O << "\t.type\t" << CurrentFnName << ", @function\n";
+ O << "\t.type\t" << *CurrentFnSym << ", @function\n";
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
emitFrameDirective(MF);
printSavedRegsBitmask(MF);
@@ -243,9 +240,9 @@ void MipsAsmPrinter::emitFunctionEnd(MachineFunction &MF) {
O << "\t.set\tmacro\n";
O << "\t.set\treorder\n";
- O << "\t.end\t" << CurrentFnName << '\n';
+ O << "\t.end\t" << *CurrentFnSym << '\n';
if (MAI->hasDotTypeDotSizeDirective() && !Subtarget->isLinux())
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
}
/// runOnMachineFunction - This uses the printMachineInstruction()
@@ -346,20 +343,20 @@ void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
break;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
- O << MO.getSymbolName();
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
break;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << MO.getIndex();
+ << '_' << MO.getIndex();
break;
case MachineOperand::MO_ConstantPoolIndex:
@@ -425,102 +422,6 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
O << "\t.previous" << '\n';
}
-void MipsAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- O << "\n\n";
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- const Type *CTy = C->getType();
- unsigned Size = TD->getTypeAllocSize(CTy);
- const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
- bool printSizeAndType = true;
-
- // A data structure or array is aligned in memory to the largest
- // alignment boundary required by any data type inside it (this matches
- // the Preferred Type Alignment). For integral types, the alignment is
- // the type size.
- unsigned Align;
- if (CTy->getTypeID() == Type::IntegerTyID ||
- CTy->getTypeID() == Type::VoidTyID) {
- assert(!(Size & (Size-1)) && "Alignment is not a power of two!");
- Align = Log2_32(Size);
- } else
- Align = TD->getPreferredTypeAlignmentShift(CTy);
-
- printVisibility(name, GVar->getVisibility());
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection()) {
- if (!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << '\n';
-
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (1 << Align);
-
- O << '\n';
- return;
- }
- }
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::CommonLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- // FIXME: Verify correct for weak.
- // Nonnull linkonce -> weak
- O << "\t.weak " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of their name
- // or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << MAI->getGlobalDirective() << name << '\n';
- // Fall Through
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- if (CVA && CVA->isCString())
- printSizeAndType = false;
- break;
- case GlobalValue::GhostLinkage:
- llvm_unreachable("Should not have any unmaterialized functions!");
- case GlobalValue::DLLImportLinkage:
- llvm_unreachable("DLLImport linkage is not supported by this target!");
- case GlobalValue::DLLExportLinkage:
- llvm_unreachable("DLLExport linkage is not supported by this target!");
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
-
- if (MAI->hasDotTypeDotSizeDirective() && printSizeAndType) {
- O << "\t.type " << name << ",@object\n";
- O << "\t.size " << name << ',' << Size << '\n';
- }
-
- O << name << ":\n";
- EmitGlobalConstant(C);
-}
-
-
// Force static initialization.
extern "C" void LLVMInitializeMipsAsmPrinter() {
RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget);
diff --git a/lib/Target/Mips/Makefile b/lib/Target/Mips/Makefile
index 0780345..4e4d874 100644
--- a/lib/Target/Mips/Makefile
+++ b/lib/Target/Mips/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMMipsCodeGen
TARGET = Mips
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = MipsGenRegisterInfo.h.inc MipsGenRegisterNames.inc \
diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td
index 01fe92e..c2bfb8f 100644
--- a/lib/Target/Mips/MipsCallingConv.td
+++ b/lib/Target/Mips/MipsCallingConv.td
@@ -23,11 +23,11 @@ def RetCC_MipsO32 : CallingConv<[
// i32 are returned in registers V0, V1
CCIfType<[i32], CCAssignToReg<[V0, V1]>>,
- // f32 are returned in registers F0, F1
- CCIfType<[f32], CCAssignToReg<[F0, F1]>>,
+ // f32 are returned in registers F0, F2
+ CCIfType<[f32], CCAssignToReg<[F0, F2]>>,
- // f64 are returned in register D0
- CCIfType<[f64], CCIfSubtarget<"isNotSingleFloat()", CCAssignToReg<[D0]>>>
+ // f64 are returned in register D0, D1
+ CCIfType<[f64], CCIfSubtarget<"isNotSingleFloat()", CCAssignToReg<[D0, D1]>>>
]>;
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index a53e918..e3a45d2 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -396,9 +396,9 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
else
Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV);
- SDNode *Node = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2);
+ SDNode *MulDiv = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2);
- SDValue InFlag = SDValue(Node, 0);
+ SDValue InFlag = SDValue(MulDiv, 0);
SDNode *Lo = CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32,
MVT::Flag, InFlag);
InFlag = SDValue(Lo,1);
@@ -461,9 +461,18 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
case ISD::ConstantFP: {
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);
if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
- SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32);
- ReplaceUses(SDValue(Node, 0), Zero);
- return Zero.getNode();
+ SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
+ Mips::ZERO, MVT::i32);
+ SDValue Undef = SDValue(
+ CurDAG->getMachineNode(
+ TargetInstrInfo::IMPLICIT_DEF, dl, MVT::f64), 0);
+ SDNode *MTC = CurDAG->getMachineNode(Mips::MTC1, dl, MVT::f32, Zero);
+ SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPEVEN, dl,
+ MVT::f64, Undef, SDValue(MTC, 0));
+ SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPODD, dl,
+ MVT::f64, I0, SDValue(MTC, 0));
+ ReplaceUses(SDValue(Node, 0), I1);
+ return I1.getNode();
}
break;
}
@@ -486,10 +495,15 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
/// be loaded with 3 instructions.
case MipsISD::JmpLink: {
if (TM.getRelocationModel() == Reloc::PIC_) {
+ unsigned LastOpNum = Node->getNumOperands()-1;
+
SDValue Chain = Node->getOperand(0);
SDValue Callee = Node->getOperand(1);
- SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
- SDValue InFlag(0, 0);
+ SDValue InFlag;
+
+ // Skip the incomming flag if present
+ if (Node->getOperand(LastOpNum).getValueType() == MVT::Flag)
+ LastOpNum--;
if ( (isa<GlobalAddressSDNode>(Callee)) ||
(isa<ExternalSymbolSDNode>(Callee)) )
@@ -504,18 +518,28 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
Chain = Load.getValue(1);
// Call target must be on T9
- Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Load, InFlag);
+ Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Load, InFlag);
} else
/// Indirect call
- Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Callee, InFlag);
+ Chain = CurDAG->getCopyToReg(Chain, dl, Mips::T9, Callee, InFlag);
+
+ // Map the JmpLink operands to JALR
+ SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Flag);
+ SmallVector<SDValue, 8> Ops;
+ Ops.push_back(CurDAG->getRegister(Mips::T9, MVT::i32));
+
+ for (unsigned i = 2, e = LastOpNum+1; i != e; ++i)
+ Ops.push_back(Node->getOperand(i));
+ Ops.push_back(Chain);
+ Ops.push_back(Chain.getValue(1));
// Emit Jump and Link Register
- SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, MVT::Other,
- MVT::Flag, T9Reg, Chain);
- Chain = SDValue(ResNode, 0);
- InFlag = SDValue(ResNode, 1);
- ReplaceUses(SDValue(Node, 0), Chain);
- ReplaceUses(SDValue(Node, 1), InFlag);
+ SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, NodeTys,
+ &Ops[0], Ops.size());
+
+ // Replace Chain and InFlag
+ ReplaceUses(SDValue(Node, 0), SDValue(ResNode, 0));
+ ReplaceUses(SDValue(Node, 1), SDValue(ResNode, 1));
return ResNode;
}
}
diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp
index 48b9bdf..1a9bffc 100644
--- a/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/lib/Target/Mips/MipsInstrInfo.cpp
@@ -134,8 +134,6 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const {
DebugLoc DL = DebugLoc::getUnknownLoc();
- const MachineFunction *MF = MBB.getParent();
- const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo();
if (I != MBB.end()) DL = I->getDebugLoc();
@@ -156,13 +154,6 @@ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
else if ((DestRC == Mips::FGR32RegisterClass) &&
(SrcRC == Mips::CPURegsRegisterClass))
BuildMI(MBB, I, DL, get(Mips::MTC1), DestReg).addReg(SrcReg);
- else if ((DestRC == Mips::AFGR64RegisterClass) &&
- (SrcRC == Mips::CPURegsRegisterClass) &&
- (SrcReg == Mips::ZERO)) {
- const unsigned *AliasSet = TRI->getAliasSet(DestReg);
- BuildMI(MBB, I, DL, get(Mips::MTC1), AliasSet[0]).addReg(SrcReg);
- BuildMI(MBB, I, DL, get(Mips::MTC1), AliasSet[1]).addReg(SrcReg);
- }
// Move from/to Hi/Lo registers
else if ((DestRC == Mips::HILORegisterClass) &&
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index 46cf43e..e67bcbf 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -28,8 +28,8 @@ def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
def SDT_MipsCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
// Call
-def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain,
- SDNPOutFlag]>;
+def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink,
+ [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>;
// Hi and Lo nodes are used to handle global addresses. Used on
// MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
@@ -306,7 +306,7 @@ let isCall=1, hasDelaySlot=1,
class JumpLink<bits<6> op, string instr_asm>:
FJ< op,
(outs),
- (ins calltarget:$target),
+ (ins calltarget:$target, variable_ops),
!strconcat(instr_asm, "\t$target"),
[(MipsJmpLink imm:$target)], IIBranch>;
@@ -315,14 +315,14 @@ let isCall=1, hasDelaySlot=1,
FR< op,
func,
(outs),
- (ins CPURegs:$rs),
+ (ins CPURegs:$rs, variable_ops),
!strconcat(instr_asm, "\t$rs"),
[(MipsJmpLink CPURegs:$rs)], IIBranch>;
class BranchLink<string instr_asm>:
FI< 0x1,
(outs),
- (ins CPURegs:$rs, brtarget:$target),
+ (ins CPURegs:$rs, brtarget:$target, variable_ops),
!strconcat(instr_asm, "\t$rs, $target"),
[], IIBranch>;
}
diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp
index cae4181..80fd917 100644
--- a/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -172,7 +172,7 @@ getReservedRegs(const MachineFunction &MF) const
//
// The stack is allocated decrementing the stack pointer on
// the first instruction of a function prologue. Once decremented,
-// all stack referencesare are done thought a positive offset
+// all stack references are done thought a positive offset
// from the stack/frame pointer, so the stack is considering
// to grow up! Otherwise terrible hacks would have to be made
// to get this stack ABI compliant :)
diff --git a/lib/Target/Mips/TargetInfo/Makefile b/lib/Target/Mips/TargetInfo/Makefile
index 32f4e16..f27d49e 100644
--- a/lib/Target/Mips/TargetInfo/Makefile
+++ b/lib/Target/Mips/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMMipsInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PIC16/AsmPrinter/Makefile b/lib/Target/PIC16/AsmPrinter/Makefile
index f4db57e..27c4045 100644
--- a/lib/Target/PIC16/AsmPrinter/Makefile
+++ b/lib/Target/PIC16/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPIC16AsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' pic16 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
index 87f5aad..0463596 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
@@ -29,7 +29,6 @@
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include <cstring>
using namespace llvm;
@@ -82,7 +81,7 @@ static int getFunctionColor(const Function *F) {
// Color the Auto section of the given function.
void PIC16AsmPrinter::ColorAutoSection(const Function *F) {
- std::string SectionName = PAN::getAutosSectionName(CurrentFnName);
+ std::string SectionName = PAN::getAutosSectionName(CurrentFnSym->getName());
PIC16Section* Section = PTOF->findPIC16Section(SectionName);
if (Section != NULL) {
int Color = getFunctionColor(F);
@@ -103,11 +102,8 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// of runOnMachineFunction.
SetupMachineFunction(MF);
- // Get the mangled name.
- const Function *F = MF.getFunction();
- CurrentFnName = Mang->getMangledName(F);
-
// Put the color information from function to its auto section.
+ const Function *F = MF.getFunction();
ColorAutoSection(F);
// Emit the function frame (args and temps).
@@ -117,18 +113,18 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// Now emit the instructions of function in its code section.
const MCSection *fCodeSection
- = getObjFileLowering().SectionForCode(CurrentFnName);
+ = getObjFileLowering().SectionForCode(CurrentFnSym->getName());
// Start the Code Section.
O << "\n";
OutStreamer.SwitchSection(fCodeSection);
// Emit the frame address of the function at the beginning of code.
- O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
- O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnName) << ")\n";
+ O << "\tretlw low(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
+ O << "\tretlw high(" << PAN::getFrameLabel(CurrentFnSym->getName()) << ")\n";
// Emit function start label.
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
DebugLoc CurDL;
O << "\n";
@@ -187,24 +183,22 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
return;
case MachineOperand::MO_GlobalAddress: {
- std::string Sname = Mang->getMangledName(MO.getGlobal());
+ MCSymbol *Sym = GetGlobalValueSymbol(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.
- if (PAN::isMemIntrinsic(Sname)) {
- LibcallDecls.push_back(createESName(Sname));
- }
+ if (PAN::isMemIntrinsic(Sym->getName()))
+ LibcallDecls.push_back(createESName(Sym->getName()));
- O << Sname;
+ O << *Sym;
break;
}
case MachineOperand::MO_ExternalSymbol: {
const char *Sname = MO.getSymbolName();
// If its a libcall name, record it to decls section.
- if (PAN::getSymbolTag(Sname) == PAN::LIBCALL) {
+ if (PAN::getSymbolTag(Sname) == PAN::LIBCALL)
LibcallDecls.push_back(Sname);
- }
// Record a call to intrinsic to print the extern declaration for it.
std::string Sym = Sname;
@@ -213,11 +207,11 @@ void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
LibcallDecls.push_back(createESName(Sym));
}
- O << Sym;
+ O << Sym;
break;
}
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
default:
@@ -319,16 +313,14 @@ void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
// Emit declarations for external functions.
O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
- if (I->isIntrinsic())
- continue;
-
- std::string Name = Mang->getMangledName(I);
- if (Name.compare("@abort") == 0)
+ if (I->isIntrinsic() || I->getName() == "@abort")
continue;
if (!I->isDeclaration() && !I->hasExternalLinkage())
continue;
+ MCSymbol *Sym = GetGlobalValueSymbol(I);
+
// Do not emit memcpy, memset, and memmove here.
// Calls to these routines can be generated in two ways,
// 1. User calling the standard lib function
@@ -337,14 +329,14 @@ void PIC16AsmPrinter::EmitFunctionDecls(Module &M) {
// second case the call is via and externalsym and the prototype is missing.
// So declarations for these are currently always getting printing by
// tracking both kind of references in printInstrunction.
- if (I->isDeclaration() && PAN::isMemIntrinsic(Name)) continue;
+ if (I->isDeclaration() && PAN::isMemIntrinsic(Sym->getName())) continue;
const char *directive = I->isDeclaration() ? MAI->getExternDirective() :
MAI->getGlobalDirective();
- O << directive << Name << "\n";
- O << directive << PAN::getRetvalLabel(Name) << "\n";
- O << directive << PAN::getArgsLabel(Name) << "\n";
+ O << directive << Sym->getName() << "\n";
+ O << directive << PAN::getRetvalLabel(Sym->getName()) << "\n";
+ O << directive << PAN::getArgsLabel(Sym->getName()) << "\n";
}
O << MAI->getCommentString() << "Function Declarations - END." <<"\n";
@@ -356,9 +348,8 @@ void PIC16AsmPrinter::EmitUndefinedVars(Module &M) {
if (!Items.size()) return;
O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n";
- for (unsigned j = 0; j < Items.size(); j++) {
- O << MAI->getExternDirective() << Mang->getMangledName(Items[j]) << "\n";
- }
+ for (unsigned j = 0; j < Items.size(); j++)
+ O << MAI->getExternDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
O << MAI->getCommentString() << "Imported Variables - END" << "\n";
}
@@ -368,9 +359,8 @@ void PIC16AsmPrinter::EmitDefinedVars(Module &M) {
if (!Items.size()) return;
O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n";
- for (unsigned j = 0; j < Items.size(); j++) {
- O << MAI->getGlobalDirective() << Mang->getMangledName(Items[j]) << "\n";
- }
+ for (unsigned j = 0; j < Items.size(); j++)
+ O << MAI->getGlobalDirective() << *GetGlobalValueSymbol(Items[j]) << "\n";
O << MAI->getCommentString() << "Exported Variables - END" << "\n";
}
@@ -394,19 +384,19 @@ bool PIC16AsmPrinter::doFinalization(Module &M) {
void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
const Function *F = MF.getFunction();
- std::string FuncName = Mang->getMangledName(F);
const TargetData *TD = TM.getTargetData();
// Emit the data section name.
O << "\n";
- PIC16Section *fPDataSection = const_cast<PIC16Section *>(getObjFileLowering().
- SectionForFrame(CurrentFnName));
+ PIC16Section *fPDataSection =
+ const_cast<PIC16Section *>(getObjFileLowering().
+ SectionForFrame(CurrentFnSym->getName()));
fPDataSection->setColor(getFunctionColor(F));
OutStreamer.SwitchSection(fPDataSection);
// Emit function frame label
- O << PAN::getFrameLabel(CurrentFnName) << ":\n";
+ O << PAN::getFrameLabel(CurrentFnSym->getName()) << ":\n";
const Type *RetType = F->getReturnType();
unsigned RetSize = 0;
@@ -418,9 +408,10 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
// we will need to avoid printing a global directive for Retval label
// in emitExternandGloblas.
if(RetSize > 0)
- O << PAN::getRetvalLabel(CurrentFnName) << " RES " << RetSize << "\n";
+ O << PAN::getRetvalLabel(CurrentFnSym->getName())
+ << " RES " << RetSize << "\n";
else
- O << PAN::getRetvalLabel(CurrentFnName) << ": \n";
+ O << PAN::getRetvalLabel(CurrentFnSym->getName()) << ": \n";
// Emit variable to hold the space for function arguments
unsigned ArgSize = 0;
@@ -430,12 +421,13 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
ArgSize += TD->getTypeAllocSize(Ty);
}
- O << PAN::getArgsLabel(CurrentFnName) << " RES " << ArgSize << "\n";
+ O << PAN::getArgsLabel(CurrentFnSym->getName()) << " RES " << ArgSize << "\n";
// Emit temporary space
int TempSize = PTLI->GetTmpSize();
if (TempSize > 0)
- O << PAN::getTempdataLabel(CurrentFnName) << " RES " << TempSize << '\n';
+ O << PAN::getTempdataLabel(CurrentFnSym->getName()) << " RES "
+ << TempSize << '\n';
}
@@ -445,10 +437,9 @@ void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) {
std::vector<const GlobalVariable*> Items = S->Items;
for (unsigned j = 0; j < Items.size(); j++) {
- std::string Name = Mang->getMangledName(Items[j]);
Constant *C = Items[j]->getInitializer();
int AddrSpace = Items[j]->getType()->getAddressSpace();
- O << Name;
+ O << *GetGlobalValueSymbol(Items[j]);
EmitGlobalConstant(C, AddrSpace);
}
}
@@ -464,11 +455,10 @@ EmitUninitializedDataSection(const PIC16Section *S) {
OutStreamer.SwitchSection(S);
std::vector<const GlobalVariable*> Items = S->Items;
for (unsigned j = 0; j < Items.size(); j++) {
- std::string Name = Mang->getMangledName(Items[j]);
Constant *C = Items[j]->getInitializer();
const Type *Ty = C->getType();
unsigned Size = TD->getTypeAllocSize(Ty);
- O << Name << " RES " << Size << "\n";
+ O << *GetGlobalValueSymbol(Items[j]) << " RES " << Size << "\n";
}
}
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
index 838c970..74ab72c 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
@@ -69,9 +69,9 @@ namespace llvm {
bool doInitialization(Module &M);
bool doFinalization(Module &M);
- /// PrintGlobalVariable - Emit the specified global variable and its
+ /// EmitGlobalVariable - Emit the specified global variable and its
/// initializer to the output stream.
- virtual void PrintGlobalVariable(const GlobalVariable *GV) {
+ virtual void EmitGlobalVariable(const GlobalVariable *GV) {
// PIC16 doesn't use normal hooks for this.
}
diff --git a/lib/Target/PIC16/Makefile b/lib/Target/PIC16/Makefile
index 4382eba7..a1dbde5 100644
--- a/lib/Target/PIC16/Makefile
+++ b/lib/Target/PIC16/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMPIC16CodeGen
TARGET = PIC16
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = PIC16GenRegisterInfo.h.inc PIC16GenRegisterNames.inc \
diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp
index 6e0e3ce..8368a3c 100644
--- a/lib/Target/PIC16/PIC16DebugInfo.cpp
+++ b/lib/Target/PIC16/PIC16DebugInfo.cpp
@@ -259,8 +259,9 @@ void PIC16DbgInfo::ChangeDebugLoc(const MachineFunction &MF,
if (! EmitDebugDirectives) return;
assert (! DL.isUnknown() && "can't change to invalid debug loc");
- MDNode *CU = MF.getDebugLocTuple(DL).Scope;
- unsigned line = MF.getDebugLocTuple(DL).Line;
+ DILocation Loc = MF.getDILocation(DL);
+ MDNode *CU = Loc.getScope().getNode();
+ unsigned line = Loc.getLineNumber();
SwitchToCU(CU);
SwitchToLine(line, IsInBeginFunction);
diff --git a/lib/Target/PIC16/PIC16Passes/Makefile b/lib/Target/PIC16/PIC16Passes/Makefile
index 9684b8d..fb45d71 100644
--- a/lib/Target/PIC16/PIC16Passes/Makefile
+++ b/lib/Target/PIC16/PIC16Passes/Makefile
@@ -10,6 +10,7 @@ LEVEL = ../../../..
TARGET = PIC16
LIBRARYNAME = LLVMpic16passes
BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/PIC16/TargetInfo/Makefile b/lib/Target/PIC16/TargetInfo/Makefile
index 76609f6..9004be8 100644
--- a/lib/Target/PIC16/TargetInfo/Makefile
+++ b/lib/Target/PIC16/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPIC16Info
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PowerPC/AsmPrinter/Makefile b/lib/Target/PowerPC/AsmPrinter/Makefile
index 269ef92..4378151 100644
--- a/lib/Target/PowerPC/AsmPrinter/Makefile
+++ b/lib/Target/PowerPC/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPowerPCAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' PowerPC target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index d505d38..b89c2b4 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -27,21 +27,21 @@
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DwarfWriter.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
@@ -58,48 +58,7 @@ STATISTIC(EmittedInsts, "Number of machine instrs printed");
namespace {
class PPCAsmPrinter : public AsmPrinter {
protected:
- struct FnStubInfo {
- MCSymbol *Stub, *LazyPtr, *AnonSymbol;
-
- FnStubInfo() {
- Stub = LazyPtr = AnonSymbol = 0;
- }
-
- void Init(const GlobalValue *GV, Mangler *Mang, MCContext &Ctx) {
- // Already initialized.
- if (Stub != 0) return;
-
- // Get the names.
- SmallString<128> TmpStr;
- Mang->getNameWithPrefix(TmpStr, GV, true);
- MakeSymbols(TmpStr, Ctx);
- }
-
- void Init(StringRef GVName, Mangler *Mang, MCContext &Ctx) {
- assert(!GVName.empty() && "external symbol name shouldn't be empty");
- if (Stub != 0) return; // Already initialized.
- // Get the names for the external symbol name.
- SmallString<128> TmpStr;
- Mang->getNameWithPrefix(TmpStr, GVName, Mangler::Private);
- MakeSymbols(TmpStr, Ctx);
- }
-
- void MakeSymbols(SmallString<128> &TmpStr, MCContext &Ctx) {
- TmpStr += "$stub";
- Stub = Ctx.GetOrCreateSymbol(TmpStr.str());
- TmpStr.erase(TmpStr.end()-5, TmpStr.end()); // Remove $stub
-
- TmpStr += "$lazy_ptr";
- LazyPtr = Ctx.GetOrCreateSymbol(TmpStr.str());
- TmpStr.erase(TmpStr.end()-9, TmpStr.end()); // Remove $lazy_ptr
-
- TmpStr += "$stub$tmp";
- AnonSymbol = Ctx.GetOrCreateSymbol(TmpStr.str());
- }
- };
-
- StringMap<FnStubInfo> FnStubs;
- StringMap<std::string> GVStubs, HiddenGVStubs, TOC;
+ DenseMap<const MCSymbol*, const MCSymbol*> TOC;
const PPCSubtarget &Subtarget;
uint64_t LabelID;
public:
@@ -240,18 +199,26 @@ namespace {
GlobalValue *GV = MO.getGlobal();
if (GV->isDeclaration() || GV->isWeakForLinker()) {
// Dynamically-resolved functions need a stub for the function.
- FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)];
- FnInfo.Init(GV, Mang, OutContext);
- FnInfo.Stub->print(O, MAI);
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
+ O << *Sym;
return;
}
}
if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
- SmallString<128> MangledName;
- Mang->getNameWithPrefix(MangledName, MO.getSymbolName());
- FnStubInfo &FnInfo = FnStubs[MangledName.str()];
- FnInfo.Init(MO.getSymbolName(), Mang, OutContext);
- FnInfo.Stub->print(O, MAI);
+ SmallString<128> TempNameStr;
+ TempNameStr += StringRef(MO.getSymbolName());
+ TempNameStr += StringRef("$stub");
+
+ const MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
+ if (StubSym == 0)
+ StubSym = GetExternalSymbolSymbol(MO.getSymbolName());
+ O << *Sym;
return;
}
}
@@ -338,21 +305,16 @@ namespace {
assert(MO.getType() == MachineOperand::MO_GlobalAddress);
- GlobalValue *GV = MO.getGlobal();
-
- std::string Name = Mang->getMangledName(GV);
+ const MCSymbol *Sym = GetGlobalValueSymbol(MO.getGlobal());
// Map symbol -> label of TOC entry.
- if (TOC.count(Name) == 0) {
- std::string Label;
- Label += MAI->getPrivateGlobalPrefix();
- Label += "C";
- Label += utostr(LabelID++);
+ const MCSymbol *&TOCEntry = TOC[Sym];
+ if (TOCEntry == 0)
+ TOCEntry = OutContext.
+ GetOrCreateSymbol(StringRef(MAI->getPrivateGlobalPrefix()) + "C" +
+ Twine(LabelID++));
- TOC[Name] = Label;
- }
-
- O << TOC[Name] << "@toc";
+ O << *TOCEntry << "@toc";
}
void printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
@@ -381,8 +343,6 @@ namespace {
AU.addRequired<DwarfWriter>();
PPCAsmPrinter::getAnalysisUsage(AU);
}
-
- void PrintGlobalVariable(const GlobalVariable *GVar);
};
/// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
@@ -402,14 +362,14 @@ namespace {
bool doFinalization(Module &M);
void EmitStartOfAsmFile(Module &M);
+ void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
+
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineModuleInfo>();
AU.addRequired<DwarfWriter>();
PPCAsmPrinter::getAnalysisUsage(AU);
}
-
- void PrintGlobalVariable(const GlobalVariable *GVar);
};
} // end of anonymous namespace
@@ -422,7 +382,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
llvm_unreachable("printOp() does not handle immediate values");
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
@@ -434,42 +394,57 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
<< '_' << MO.getIndex();
return;
case MachineOperand::MO_BlockAddress:
- GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
+ O << *GetBlockAddressSymbol(MO.getBlockAddress());
return;
case MachineOperand::MO_ExternalSymbol: {
// Computing the address of an external symbol, not calling it.
- std::string Name(MAI->getGlobalPrefix());
- Name += MO.getSymbolName();
-
- if (TM.getRelocationModel() != Reloc::Static) {
- GVStubs[Name] = Name+"$non_lazy_ptr";
- Name += "$non_lazy_ptr";
+ if (TM.getRelocationModel() == Reloc::Static) {
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
+ return;
}
- O << Name;
+
+ const MCSymbol *NLPSym =
+ OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
+ MO.getSymbolName()+"$non_lazy_ptr");
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
+ if (StubSym == 0)
+ StubSym = GetExternalSymbolSymbol(MO.getSymbolName());
+
+ O << *NLPSym;
return;
}
case MachineOperand::MO_GlobalAddress: {
// Computing the address of a global symbol, not calling it.
GlobalValue *GV = MO.getGlobal();
- std::string Name;
+ MCSymbol *SymToPrint;
// External or weakly linked global variables need non-lazily-resolved stubs
if (TM.getRelocationModel() != Reloc::Static &&
(GV->isDeclaration() || GV->isWeakForLinker())) {
if (!GV->hasHiddenVisibility()) {
- Name = Mang->getMangledName(GV, "$non_lazy_ptr", true);
- GVStubs[Mang->getMangledName(GV)] = Name;
+ SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(SymToPrint);
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
} else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
GV->hasAvailableExternallyLinkage()) {
- Name = Mang->getMangledName(GV, "$non_lazy_ptr", true);
- HiddenGVStubs[Mang->getMangledName(GV)] = Name;
+ SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
+
+ const MCSymbol *&StubSym =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>().
+ getHiddenGVStubEntry(SymToPrint);
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
} else {
- Name = Mang->getMangledName(GV);
+ SymToPrint = GetGlobalValueSymbol(GV);
}
} else {
- Name = Mang->getMangledName(GV);
+ SymToPrint = GetGlobalValueSymbol(GV);
}
- O << Name;
+
+ O << *SymToPrint;
printOffset(MO.getOffset());
return;
@@ -641,34 +616,34 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::InternalLinkage: // Symbols default to internal.
break;
case Function::ExternalLinkage:
- O << "\t.global\t" << CurrentFnName << '\n'
- << "\t.type\t" << CurrentFnName << ", @function\n";
+ O << "\t.global\t" << *CurrentFnSym << '\n' << "\t.type\t";
+ O << *CurrentFnSym << ", @function\n";
break;
case Function::LinkerPrivateLinkage:
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
- O << "\t.global\t" << CurrentFnName << '\n';
- O << "\t.weak\t" << CurrentFnName << '\n';
+ O << "\t.global\t" << *CurrentFnSym << '\n';
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
EmitAlignment(MF.getAlignment(), F);
if (Subtarget.isPPC64()) {
// Emit an official procedure descriptor.
- // FIXME 64-bit SVR4: Use MCSection here?
+ // FIXME 64-bit SVR4: Use MCSection here!
O << "\t.section\t\".opd\",\"aw\"\n";
O << "\t.align 3\n";
- O << CurrentFnName << ":\n";
- O << "\t.quad .L." << CurrentFnName << ",.TOC.@tocbase\n";
+ O << *CurrentFnSym << ":\n";
+ O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n";
O << "\t.previous\n";
- O << ".L." << CurrentFnName << ":\n";
+ O << ".L." << *CurrentFnSym << ":\n";
} else {
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
}
// Emit pre-function debug information.
@@ -688,7 +663,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
}
- O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ",.-" << *CurrentFnSym << '\n';
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
@@ -702,92 +677,6 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
return false;
}
-void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- std::string name = Mang->getMangledName(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && /* FIXME: Verify correct */
- !GVar->hasSection() &&
- (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
- GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasExternalLinkage()) {
- O << "\t.global " << name << '\n';
- O << "\t.type " << name << ", @object\n";
- O << name << ":\n";
- O << "\t.zero " << Size << '\n';
- } else if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << ',' << Size;
- } else {
- O << ".comm " << name << ',' << Size;
- }
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- O << "\t.global " << name << '\n'
- << "\t.type " << name << ", @object\n"
- << "\t.weak " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.global " << name << '\n'
- << "\t.type " << name << ", @object\n";
- // FALL THROUGH
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
-
- EmitGlobalConstant(C);
- O << '\n';
-}
-
bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
const TargetData *TD = TM.getTargetData();
@@ -797,10 +686,11 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
// FIXME 64-bit SVR4: Use MCSection here?
O << "\t.section\t\".toc\",\"aw\"\n";
- for (StringMap<std::string>::iterator I = TOC.begin(), E = TOC.end();
- I != E; ++I) {
- O << I->second << ":\n";
- O << "\t.tc " << I->getKeyData() << "[TC]," << I->getKeyData() << '\n';
+ // FIXME: This is nondeterminstic!
+ for (DenseMap<const MCSymbol*, const MCSymbol*>::iterator I = TOC.begin(),
+ E = TOC.end(); I != E; ++I) {
+ O << *I->second << ":\n";
+ O << "\t.tc " << *I->first << "[TC]," << *I->first << '\n';
}
}
@@ -829,22 +719,22 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
case Function::InternalLinkage: // Symbols default to internal.
break;
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
break;
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
case Function::LinkerPrivateLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
- O << "\t.weak_definition\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
+ O << "\t.weak_definition\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
EmitAlignment(MF.getAlignment(), F);
- O << CurrentFnName << ":\n";
+ O << *CurrentFnSym << ":\n";
// Emit pre-function debug information.
DW->BeginFunction(&MF);
@@ -926,203 +816,110 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
}
-void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar)) {
- if (TM.getRelocationModel() == Reloc::Static) {
- if (GVar->getName() == "llvm.global_ctors")
- O << ".reference .constructors_used\n";
- else if (GVar->getName() == "llvm.global_dtors")
- O << ".reference .destructors_used\n";
- }
- return;
- }
-
- std::string name = Mang->getMangledName(GVar);
- printVisibility(name, GVar->getVisibility());
-
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
- /// FIXME: Drive this off the section!
- if (C->isNullValue() && /* FIXME: Verify correct */
- !GVar->hasSection() &&
- (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
- GVar->isWeakForLinker()) &&
- // Don't put things that should go in the cstring section into "comm".
- !TheSection->getKind().isMergeableCString()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasExternalLinkage()) {
- O << "\t.globl " << name << '\n';
- O << "\t.zerofill __DATA, __common, " << name << ", "
- << Size << ", " << Align;
- } else if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << ',' << Size << ',' << Align;
- } else if (!GVar->hasCommonLinkage()) {
- O << "\t.globl " << name << '\n'
- << MAI->getWeakDefDirective() << name << '\n';
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << " ";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- EmitGlobalConstant(C);
- return;
- } else {
- O << ".comm " << name << ',' << Size;
- // Darwin 9 and above support aligned common data.
- if (Subtarget.isDarwin9())
- O << ',' << Align;
- }
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- O << "\t.globl " << name << '\n'
- << "\t.weak_definition " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << name << '\n';
- // FALL THROUGH
- case GlobalValue::InternalLinkage:
- case GlobalValue::PrivateLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
-
- EmitGlobalConstant(C);
- O << '\n';
+static const MCSymbol *GetLazyPtr(const MCSymbol *Sym, MCContext &Ctx) {
+ // Remove $stub suffix, add $lazy_ptr.
+ SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5);
+ TmpStr += "$lazy_ptr";
+ return Ctx.GetOrCreateSymbol(TmpStr.str());
}
-bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
- const TargetData *TD = TM.getTargetData();
-
- bool isPPC64 = TD->getPointerSizeInBits() == 64;
+static const MCSymbol *GetAnonSym(const MCSymbol *Sym, MCContext &Ctx) {
+ // Add $tmp suffix to $stub, yielding $stub$tmp.
+ SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end());
+ TmpStr += "$tmp";
+ return Ctx.GetOrCreateSymbol(TmpStr.str());
+}
- // Darwin/PPC always uses mach-o.
+void PPCDarwinAsmPrinter::
+EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
+ bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
+
TargetLoweringObjectFileMachO &TLOFMacho =
static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
-
- const MCSection *LSPSection = 0;
- if (!FnStubs.empty()) // .lazy_symbol_pointer
- LSPSection = TLOFMacho.getLazySymbolPointerSection();
-
+ // .lazy_symbol_pointer
+ const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
// Output stubs for dynamically-linked functions
- if (TM.getRelocationModel() == Reloc::PIC_ && !FnStubs.empty()) {
+ if (TM.getRelocationModel() == Reloc::PIC_) {
const MCSection *StubSection =
- TLOFMacho.getMachOSection("__TEXT", "__picsymbolstub1",
- MCSectionMachO::S_SYMBOL_STUBS |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 32, SectionKind::getText());
- for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
- I != E; ++I) {
+ TLOFMacho.getMachOSection("__TEXT", "__picsymbolstub1",
+ MCSectionMachO::S_SYMBOL_STUBS |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ 32, SectionKind::getText());
+ for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
OutStreamer.SwitchSection(StubSection);
EmitAlignment(4);
- const FnStubInfo &Info = I->second;
- Info.Stub->print(O, MAI);
- O << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
+
+ const MCSymbol *Stub = Stubs[i].first;
+ const MCSymbol *RawSym = Stubs[i].second;
+ const MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
+ const MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
+
+ O << *Stub << ":\n";
+ O << "\t.indirect_symbol " << *RawSym << '\n';
O << "\tmflr r0\n";
- O << "\tbcl 20,31,";
- Info.AnonSymbol->print(O, MAI);
- O << '\n';
- Info.AnonSymbol->print(O, MAI);
- O << ":\n";
+ O << "\tbcl 20,31," << *AnonSymbol << '\n';
+ O << *AnonSymbol << ":\n";
O << "\tmflr r11\n";
- O << "\taddis r11,r11,ha16(";
- Info.LazyPtr->print(O, MAI);
- O << '-';
- Info.AnonSymbol->print(O, MAI);
- O << ")\n";
+ O << "\taddis r11,r11,ha16(" << *LazyPtr << '-' << *AnonSymbol
+ << ")\n";
O << "\tmtlr r0\n";
- O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(";
- Info.LazyPtr->print(O, MAI);
- O << '-';
- Info.AnonSymbol->print(O, MAI);
- O << ")(r11)\n";
+ O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(" << *LazyPtr
+ << '-' << *AnonSymbol << ")(r11)\n";
O << "\tmtctr r12\n";
O << "\tbctr\n";
OutStreamer.SwitchSection(LSPSection);
- Info.LazyPtr->print(O, MAI);
- O << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
- O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
- }
- } else if (!FnStubs.empty()) {
- const MCSection *StubSection =
- TLOFMacho.getMachOSection("__TEXT","__symbol_stub1",
- MCSectionMachO::S_SYMBOL_STUBS |
- MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
- 16, SectionKind::getText());
-
- for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
- I != E; ++I) {
- OutStreamer.SwitchSection(StubSection);
- EmitAlignment(4);
- const FnStubInfo &Info = I->second;
- Info.Stub->print(O, MAI);
- O << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
- O << "\tlis r11,ha16(";
- Info.LazyPtr->print(O, MAI);
- O << ")\n";
- O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(";
- Info.LazyPtr->print(O, MAI);
- O << ")(r11)\n";
- O << "\tmtctr r12\n";
- O << "\tbctr\n";
- OutStreamer.SwitchSection(LSPSection);
- Info.LazyPtr->print(O, MAI);
- O << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
+ O << *LazyPtr << ":\n";
+ O << "\t.indirect_symbol " << *RawSym << '\n';
O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
}
+ O << '\n';
+ return;
}
-
+
+ const MCSection *StubSection =
+ TLOFMacho.getMachOSection("__TEXT","__symbol_stub1",
+ MCSectionMachO::S_SYMBOL_STUBS |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ 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 *LazyPtr = GetLazyPtr(Stub, OutContext);
+
+ OutStreamer.SwitchSection(StubSection);
+ EmitAlignment(4);
+ O << *Stub << ":\n";
+ O << "\t.indirect_symbol " << *RawSym << '\n';
+ O << "\tlis r11,ha16(" << *LazyPtr << ")\n";
+ O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(" << *LazyPtr
+ << ")(r11)\n";
+ O << "\tmtctr r12\n";
+ O << "\tbctr\n";
+ OutStreamer.SwitchSection(LSPSection);
+ O << *LazyPtr << ":\n";
+ O << "\t.indirect_symbol " << *RawSym << '\n';
+ O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
+ }
+
O << '\n';
+}
+
+
+bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
+ bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
+
+ // Darwin/PPC always uses mach-o.
+ TargetLoweringObjectFileMachO &TLOFMacho =
+ static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
+ MachineModuleInfoMachO &MMIMacho =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>();
+
+ MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
+ if (!Stubs.empty())
+ EmitFunctionStubs(Stubs);
if (MAI->doesSupportExceptionHandling() && MMI) {
// Add the (possibly multiple) personalities to the set of global values.
@@ -1130,33 +927,39 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
const std::vector<Function *> &Personalities = MMI->getPersonalities();
for (std::vector<Function *>::const_iterator I = Personalities.begin(),
E = Personalities.end(); I != E; ++I) {
- if (*I)
- GVStubs[Mang->getMangledName(*I)] =
- Mang->getMangledName(*I, "$non_lazy_ptr", true);
+ if (*I) {
+ const MCSymbol *NLPSym =
+ GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
+ const MCSymbol *&StubSym = MMIMacho.getGVStubEntry(NLPSym);
+ StubSym = GetGlobalValueSymbol(*I);
+ }
}
}
+ // Output stubs for dynamically-linked functions.
+ Stubs = MMIMacho.GetGVStubList();
+
// Output macho stubs for external and common global variables.
- if (!GVStubs.empty()) {
+ if (!Stubs.empty()) {
// Switch with ".non_lazy_symbol_pointer" directive.
OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
EmitAlignment(isPPC64 ? 3 : 2);
- for (StringMap<std::string>::iterator I = GVStubs.begin(),
- E = GVStubs.end(); I != E; ++I) {
- O << I->second << ":\n";
- O << "\t.indirect_symbol " << I->getKeyData() << '\n';
+ 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");
}
}
- if (!HiddenGVStubs.empty()) {
+ Stubs = MMIMacho.GetHiddenGVStubList();
+ if (!Stubs.empty()) {
OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
EmitAlignment(isPPC64 ? 3 : 2);
- for (StringMap<std::string>::iterator I = HiddenGVStubs.begin(),
- E = HiddenGVStubs.end(); I != E; ++I) {
- O << I->second << ":\n";
- O << (isPPC64 ? "\t.quad\t" : "\t.long\t") << I->getKeyData() << '\n';
+
+ 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';
}
}
@@ -1165,7 +968,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
// implementation of multiple entry points). If this doesn't occur, the
// linker can safely perform dead code stripping. Since LLVM never generates
// code that does this, it is always safe to set.
- OutStreamer.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
+ OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
return AsmPrinter::doFinalization(M);
}
diff --git a/lib/Target/PowerPC/Makefile b/lib/Target/PowerPC/Makefile
index 4015d4a..cd30011 100644
--- a/lib/Target/PowerPC/Makefile
+++ b/lib/Target/PowerPC/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMPowerPCCodeGen
TARGET = PPC
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = PPCGenInstrNames.inc PPCGenRegisterNames.inc \
diff --git a/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
index ee6deb5..d2ff3b7 100644
--- a/lib/Target/PowerPC/PPCMCAsmInfo.cpp
+++ b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
@@ -29,7 +29,6 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
CommentString = "#";
GlobalPrefix = "";
PrivateGlobalPrefix = ".L";
- UsedDirective = "\t# .no_dead_strip\t";
WeakRefDirective = "\t.weak\t";
// Uses '.section' before '.bss' directive
@@ -53,7 +52,7 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
SetDirective = "\t.set";
Data64bitsDirective = is64Bit ? "\t.quad\t" : 0;
AlignmentIsInBytes = false;
- LCOMMDirective = "\t.lcomm\t";
+ HasLCOMMDirective = true;
AssemblerDialect = 0; // Old-Style mnemonics.
}
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index 8079c6e..c7f7882 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -194,4 +194,31 @@ bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
return false;
}
-
+/// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are 4-byte,
+/// 8-byte, and target default. The CIE is hard-coded to indicate that the LSDA
+/// pointer in the FDE section is an "sdata4", and should be encoded as a 4-byte
+/// pointer by default. However, some systems may require a different size due
+/// to bugs or other conditions. We will default to a 4-byte encoding unless the
+/// system tells us otherwise.
+///
+/// The issue is when the CIE says their is an LSDA. That mandates that every
+/// FDE have an LSDA slot. But if the function does not need an LSDA. There
+/// needs to be some way to signify there is none. The LSDA is encoded as
+/// pc-rel. But you don't look for some magic value after adding the pc. You
+/// have to look for a zero before adding the pc. The problem is that the size
+/// of the zero to look for depends on the encoding. The unwinder bug in SL is
+/// that it always checks for a pointer-size zero. So on x86_64 it looks for 8
+/// bytes of zero. If you have an LSDA, it works fine since the 8-bytes are
+/// non-zero so it goes ahead and then reads the value based on the encoding.
+/// But if you use sdata4 and there is no LSDA, then the test for zero gives a
+/// false negative and the unwinder thinks there is an LSDA.
+///
+/// FIXME: This call-back isn't good! We should be using the correct encoding
+/// regardless of the system. However, there are some systems which have bugs
+/// that prevent this from occuring.
+DwarfLSDAEncoding::Encoding PPCTargetMachine::getLSDAEncoding() const {
+ if (Subtarget.isDarwin() && Subtarget.getDarwinVers() != 10)
+ return DwarfLSDAEncoding::Default;
+
+ return DwarfLSDAEncoding::EightByte;
+}
diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h
index 3399ac8..4afcb23 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.h
+++ b/lib/Target/PowerPC/PPCTargetMachine.h
@@ -62,6 +62,18 @@ public:
return &MachOWriterInfo;
}
+ /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are
+ /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that
+ /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded
+ /// as a 4-byte pointer by default. However, some systems may require a
+ /// different size due to bugs or other conditions. We will default to a
+ /// 4-byte encoding unless the system tells us otherwise.
+ ///
+ /// FIXME: This call-back isn't good! We should be using the correct encoding
+ /// regardless of the system. However, there are some systems which have bugs
+ /// that prevent this from occuring.
+ virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const;
+
// Pass Pipeline Configuration
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
diff --git a/lib/Target/PowerPC/TargetInfo/Makefile b/lib/Target/PowerPC/TargetInfo/Makefile
index a101aa4..16d0167 100644
--- a/lib/Target/PowerPC/TargetInfo/Makefile
+++ b/lib/Target/PowerPC/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMPowerPCInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/README.txt b/lib/Target/README.txt
index 69da35f..080ea42 100644
--- a/lib/Target/README.txt
+++ b/lib/Target/README.txt
@@ -1665,3 +1665,54 @@ int foo() {
//===---------------------------------------------------------------------===//
+Missed instcombine transformation:
+define i1 @a(i32 %x) nounwind readnone {
+entry:
+ %cmp = icmp eq i32 %x, 30
+ %sub = add i32 %x, -30
+ %cmp2 = icmp ugt i32 %sub, 9
+ %or = or i1 %cmp, %cmp2
+ ret i1 %or
+}
+This should be optimized to a single compare. Testcase derived from gcc.
+
+//===---------------------------------------------------------------------===//
+
+Missed instcombine transformation:
+void b();
+void a(int x) { if (((1<<x)&8)==0) b(); }
+
+The shift should be optimized out. Testcase derived from gcc.
+
+//===---------------------------------------------------------------------===//
+
+Missed instcombine or reassociate transformation:
+int a(int a, int b) { return (a==12)&(b>47)&(b<58); }
+
+The sgt and slt should be combined into a single comparison. Testcase derived
+from gcc.
+
+//===---------------------------------------------------------------------===//
+
+Missed instcombine transformation:
+define i32 @a(i32 %x) nounwind readnone {
+entry:
+ %shr = lshr i32 %x, 5 ; <i32> [#uses=1]
+ %xor = xor i32 %shr, 67108864 ; <i32> [#uses=1]
+ %sub = add i32 %xor, -67108864 ; <i32> [#uses=1]
+ ret i32 %sub
+}
+
+This function is equivalent to "ashr i32 %x, 5". Testcase derived from gcc.
+
+//===---------------------------------------------------------------------===//
+
+isSafeToLoadUnconditionally should allow a GEP of a global/alloca with constant
+indicies within the bounds of the allocated object. Reduced example:
+
+const int a[] = {3,6};
+int b(int y) { int* x = y ? &a[0] : &a[1]; return *x; }
+
+All the loads should be eliminated. Testcase derived from gcc.
+
+//===---------------------------------------------------------------------===//
diff --git a/lib/Target/Sparc/AsmPrinter/Makefile b/lib/Target/Sparc/AsmPrinter/Makefile
index a856828..404fad1 100644
--- a/lib/Target/Sparc/AsmPrinter/Makefile
+++ b/lib/Target/Sparc/AsmPrinter/Makefile
@@ -8,6 +8,8 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSparcAsmPrinter
+CXXFLAGS = -fno-rtti
+
# Hack: we need to include 'main' Sparc target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
index cd85dd4..8fc4e5a 100644
--- a/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
+++ b/lib/Target/Sparc/AsmPrinter/SparcAsmPrinter.cpp
@@ -34,7 +34,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include <cctype>
#include <cstring>
@@ -61,7 +60,6 @@ namespace {
return "Sparc Assembly Printer";
}
- void PrintGlobalVariable(const GlobalVariable *GVar);
void printOperand(const MachineInstr *MI, int opNum);
void printMemOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
@@ -138,7 +136,7 @@ bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
DW->EndFunction(&MF);
// We didn't modify anything.
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
return false;
}
@@ -156,7 +154,7 @@ void SparcAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::DLLExportLinkage:
case Function::ExternalLinkage:
// Function is externally visible
- O << "\t.global\t" << CurrentFnName << '\n';
+ O << "\t.global\t" << *CurrentFnSym << '\n';
break;
case Function::LinkerPrivateLinkage:
case Function::LinkOnceAnyLinkage:
@@ -164,14 +162,14 @@ void SparcAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
// Function is weak
- O << "\t.weak\t" << CurrentFnName << '\n' ;
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.type\t" << CurrentFnName << ", #function\n";
- O << CurrentFnName << ":\n";
+ O << "\t.type\t" << *CurrentFnSym << ", #function\n";
+ O << *CurrentFnSym << ":\n";
}
@@ -195,10 +193,10 @@ void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << (int)MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
O << MO.getSymbolName();
@@ -277,85 +275,6 @@ void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
O << SPARCCondCodeToString((SPCC::CondCodes)CC);
}
-void SparcAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- O << "\n\n";
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = TD->getPreferredAlignment(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection()) {
- if (!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local " << name << '\n';
-
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (1 << Align);
-
- O << '\n';
- return;
- }
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage: // FIXME: Verify correct for weak.
- case GlobalValue::WeakODRLinkage: // FIXME: Verify correct for weak.
- // Nonnull linkonce -> weak
- O << "\t.weak " << name << '\n';
- break;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << MAI->getGlobalDirective() << name << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- case GlobalValue::GhostLinkage:
- llvm_unreachable("Should not have any unmaterialized functions!");
- case GlobalValue::DLLImportLinkage:
- llvm_unreachable("DLLImport linkage is not supported by this target!");
- case GlobalValue::DLLExportLinkage:
- llvm_unreachable("DLLExport linkage is not supported by this target!");
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
-
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type " << name << ",#object\n";
- O << "\t.size " << name << ',' << Size << '\n';
- }
-
- O << name << ":\n";
- EmitGlobalConstant(C);
-}
-
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
diff --git a/lib/Target/Sparc/Makefile b/lib/Target/Sparc/Makefile
index 6714b4d..d3e2a89 100644
--- a/lib/Target/Sparc/Makefile
+++ b/lib/Target/Sparc/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMSparcCodeGen
TARGET = Sparc
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = SparcGenRegisterInfo.h.inc SparcGenRegisterNames.inc \
diff --git a/lib/Target/Sparc/TargetInfo/Makefile b/lib/Target/Sparc/TargetInfo/Makefile
index 641ed87..0827fdb 100644
--- a/lib/Target/Sparc/TargetInfo/Makefile
+++ b/lib/Target/Sparc/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSparcInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/SystemZ/AsmPrinter/Makefile b/lib/Target/SystemZ/AsmPrinter/Makefile
index 9a350df..36cd6f8 100644
--- a/lib/Target/SystemZ/AsmPrinter/Makefile
+++ b/lib/Target/SystemZ/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSystemZAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' SystemZ target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
index e97e7ca..5c3fe37 100644
--- a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
+++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
@@ -35,8 +35,6 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
-
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -73,7 +71,6 @@ namespace {
void emitFunctionHeader(const MachineFunction &MF);
bool runOnMachineFunction(MachineFunction &F);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void getAnalysisUsage(AnalysisUsage &AU) const {
AsmPrinter::getAnalysisUsage(AU);
@@ -99,20 +96,20 @@ void SystemZAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::LinkerPrivateLinkage:
break;
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
+ O << "\t.globl\t" << *CurrentFnSym << '\n';
break;
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
- O << "\t.weak\t" << CurrentFnName << '\n';
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- O << "\t.type\t" << CurrentFnName << ",@function\n"
- << CurrentFnName << ":\n";
+ O << "\t.type\t" << *CurrentFnSym << ",@function\n";
+ O << *CurrentFnSym << ":\n";
}
bool SystemZAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
@@ -138,7 +135,7 @@ bool SystemZAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
// Print out jump tables referenced by the function.
EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
@@ -169,13 +166,11 @@ void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum){
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress: {
const GlobalValue *GV = MO.getGlobal();
- std::string Name = Mang->getMangledName(GV);
-
- O << Name;
+ O << *GetGlobalValueSymbol(GV);
// Assemble calls via PLT for externally visible symbols if PIC.
if (TM.getRelocationModel() == Reloc::PIC_ &&
@@ -226,7 +221,7 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
@@ -239,17 +234,11 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
printOffset(MO.getOffset());
break;
- case MachineOperand::MO_GlobalAddress: {
- const GlobalValue *GV = MO.getGlobal();
- std::string Name = Mang->getMangledName(GV);
-
- O << Name;
+ case MachineOperand::MO_GlobalAddress:
+ O << *GetGlobalValueSymbol(MO.getGlobal());
break;
- }
case MachineOperand::MO_ExternalSymbol: {
- std::string Name(MAI->getGlobalPrefix());
- Name += MO.getSymbolName();
- O << Name;
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
break;
}
default:
@@ -304,87 +293,6 @@ void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr *MI, int OpNum,
assert(!Index.getReg() && "Should allocate base register first!");
}
-void SystemZAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- const TargetData *TD = TM.getTargetData();
-
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar))
- return;
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- unsigned Size = TD->getTypeAllocSize(C->getType());
- unsigned Align = std::max(1U, TD->getPreferredAlignmentLog(GVar));
-
- printVisibility(name, GVar->getVisibility());
-
- O << "\t.type\t" << name << ",@object\n";
-
- OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
- TM));
-
- if (C->isNullValue() && !GVar->hasSection() &&
- !GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
-
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << '\n';
-
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
-
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- return;
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- O << "\t.weak\t" << name << '\n';
- break;
- case GlobalValue::DLLExportLinkage:
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << name << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- assert(0 && "Unknown linkage type!");
- }
-
- // Use 16-bit alignment by default to simplify bunch of stuff
- EmitAlignment(Align, GVar, 1);
- O << name << ":";
- if (VerboseAsm) {
- O << "\t\t\t\t" << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << name << ", " << Size << '\n';
-
- EmitGlobalConstant(C);
-}
-
// Force static initialization.
extern "C" void LLVMInitializeSystemZAsmPrinter() {
RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
diff --git a/lib/Target/SystemZ/Makefile b/lib/Target/SystemZ/Makefile
index f1097eb..6d0cbbd 100644
--- a/lib/Target/SystemZ/Makefile
+++ b/lib/Target/SystemZ/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMSystemZCodeGen
TARGET = SystemZ
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = SystemZGenRegisterInfo.h.inc SystemZGenRegisterNames.inc \
diff --git a/lib/Target/SystemZ/SystemZMCAsmInfo.cpp b/lib/Target/SystemZ/SystemZMCAsmInfo.cpp
index 8ea11c9..ba392bb 100644
--- a/lib/Target/SystemZ/SystemZMCAsmInfo.cpp
+++ b/lib/Target/SystemZ/SystemZMCAsmInfo.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "SystemZMCAsmInfo.h"
+#include "llvm/MC/MCSectionELF.h"
using namespace llvm;
SystemZMCAsmInfo::SystemZMCAsmInfo(const Target &T, const StringRef &TT) {
@@ -21,6 +22,9 @@ SystemZMCAsmInfo::SystemZMCAsmInfo(const Target &T, const StringRef &TT) {
WeakRefDirective = "\t.weak\t";
SetDirective = "\t.set\t";
PCSymbol = ".";
+}
- NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits";
+MCSection *SystemZMCAsmInfo::getNonexecutableStackSection(MCContext &Ctx) const{
+ return MCSectionELF::Create(".note.GNU-stack", MCSectionELF::SHT_PROGBITS,
+ 0, SectionKind::getMetadata(), false, Ctx);
}
diff --git a/lib/Target/SystemZ/SystemZMCAsmInfo.h b/lib/Target/SystemZ/SystemZMCAsmInfo.h
index 3bebcb7..00cb99b 100644
--- a/lib/Target/SystemZ/SystemZMCAsmInfo.h
+++ b/lib/Target/SystemZ/SystemZMCAsmInfo.h
@@ -22,8 +22,9 @@ namespace llvm {
struct SystemZMCAsmInfo : public MCAsmInfo {
explicit SystemZMCAsmInfo(const Target &T, const StringRef &TT);
+ virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const;
};
-
+
} // namespace llvm
#endif
diff --git a/lib/Target/SystemZ/TargetInfo/Makefile b/lib/Target/SystemZ/TargetInfo/Makefile
index 0be80eb..9f36b2c 100644
--- a/lib/Target/SystemZ/TargetInfo/Makefile
+++ b/lib/Target/SystemZ/TargetInfo/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMSystemZInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/TargetAsmLexer.cpp b/lib/Target/TargetAsmLexer.cpp
new file mode 100644
index 0000000..0ae6c14
--- /dev/null
+++ b/lib/Target/TargetAsmLexer.cpp
@@ -0,0 +1,14 @@
+//===-- llvm/Target/TargetAsmLexer.cpp - Target Assembly Lexer ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetAsmLexer.h"
+using namespace llvm;
+
+TargetAsmLexer::TargetAsmLexer(const Target &T) : TheTarget(T) {}
+TargetAsmLexer::~TargetAsmLexer() {}
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index 70e8008..a231ebc 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -22,11 +22,11 @@
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionELF.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"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
@@ -141,9 +141,18 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
return SectionKind::getThreadData();
}
+ // Variables with common linkage always get classified as common.
+ if (GVar->hasCommonLinkage())
+ return SectionKind::getCommon();
+
// Variable can be easily put to BSS section.
- if (isSuitableForBSS(GVar))
+ if (isSuitableForBSS(GVar)) {
+ if (GVar->hasLocalLinkage())
+ return SectionKind::getBSSLocal();
+ else if (GVar->hasExternalLinkage())
+ return SectionKind::getBSSExtern();
return SectionKind::getBSS();
+ }
Constant *C = GVar->getInitializer();
@@ -300,6 +309,7 @@ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
IsIndirect = false;
IsPCRel = false;
+ // FIXME: Use GetGlobalValueSymbol.
SmallString<128> Name;
Mang->getNameWithPrefix(Name, GV, false);
return MCSymbolRefExpr::Create(Name.str(), getContext());
@@ -464,30 +474,30 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
static SectionKind
-getELFKindForNamedSection(const char *Name, SectionKind K) {
- if (Name[0] != '.') return K;
+getELFKindForNamedSection(StringRef Name, SectionKind K) {
+ if (Name.empty() || Name[0] != '.') return K;
// Some lame default implementation based on some magic section names.
- if (strcmp(Name, ".bss") == 0 ||
- strncmp(Name, ".bss.", 5) == 0 ||
- strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
- strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
- strcmp(Name, ".sbss") == 0 ||
- strncmp(Name, ".sbss.", 6) == 0 ||
- strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
- strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
+ if (Name == ".bss" ||
+ Name.startswith(".bss.") ||
+ Name.startswith(".gnu.linkonce.b.") ||
+ Name.startswith(".llvm.linkonce.b.") ||
+ Name == ".sbss" ||
+ Name.startswith(".sbss.") ||
+ Name.startswith(".gnu.linkonce.sb.") ||
+ Name.startswith(".llvm.linkonce.sb."))
return SectionKind::getBSS();
- if (strcmp(Name, ".tdata") == 0 ||
- strncmp(Name, ".tdata.", 7) == 0 ||
- strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
- strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
+ if (Name == ".tdata" ||
+ Name.startswith(".tdata.") ||
+ Name.startswith(".gnu.linkonce.td.") ||
+ Name.startswith(".llvm.linkonce.td."))
return SectionKind::getThreadData();
- if (strcmp(Name, ".tbss") == 0 ||
- strncmp(Name, ".tbss.", 6) == 0 ||
- strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
- strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
+ if (Name == ".tbss" ||
+ Name.startswith(".tbss.") ||
+ Name.startswith(".gnu.linkonce.tb.") ||
+ Name.startswith(".llvm.linkonce.tb."))
return SectionKind::getThreadBSS();
return K;
@@ -543,7 +553,7 @@ getELFSectionFlags(SectionKind K) {
const MCSection *TargetLoweringObjectFileELF::
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
- const char *SectionName = GV->getSection().c_str();
+ StringRef SectionName = GV->getSection();
// Infer section flags from the section name if we can.
Kind = getELFKindForNamedSection(SectionName, Kind);
@@ -560,7 +570,6 @@ static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
if (Kind.isThreadData()) return ".gnu.linkonce.td.";
if (Kind.isThreadBSS()) return ".gnu.linkonce.tb.";
- if (Kind.isBSS()) return ".gnu.linkonce.b.";
if (Kind.isDataNoRel()) return ".gnu.linkonce.d.";
if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local.";
if (Kind.isDataRel()) return ".gnu.linkonce.d.rel.";
@@ -576,20 +585,13 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
// If this global is linkonce/weak and the target handles this by emitting it
// into a 'uniqued' section name, create and return the section now.
- if (GV->isWeakForLinker()) {
+ if (GV->isWeakForLinker() && !Kind.isCommon() && !Kind.isBSS()) {
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
- SmallString<128> Name, MangledName;
+ SmallString<128> Name;
Name.append(Prefix, Prefix+strlen(Prefix));
Mang->getNameWithPrefix(Name, GV, false);
-
- raw_svector_ostream OS(MangledName);
- MCSymbol::printMangledName(Name, OS, 0);
- OS.flush();
-
- return getELFSection(MangledName.str(),
- getELFSectionType(MangledName.str(), Kind),
- getELFSectionFlags(Kind),
- Kind);
+ return getELFSection(Name.str(), getELFSectionType(Name.str(), Kind),
+ getELFSectionFlags(Kind), Kind);
}
if (Kind.isText()) return TextSection;
@@ -614,7 +616,7 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
std::string Name = SizeSpec + utostr(Align);
- return getELFSection(Name.c_str(), MCSectionELF::SHT_PROGBITS,
+ return getELFSection(Name, MCSectionELF::SHT_PROGBITS,
MCSectionELF::SHF_ALLOC |
MCSectionELF::SHF_MERGE |
MCSectionELF::SHF_STRINGS,
@@ -636,7 +638,10 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
if (Kind.isThreadData()) return TLSDataSection;
if (Kind.isThreadBSS()) return TLSBSSSection;
- if (Kind.isBSS()) return BSSSection;
+ // Note: we claim that common symbols are put in BSSSection, but they are
+ // really emitted with the magic .comm directive, which creates a symbol table
+ // entry but not a section.
+ if (Kind.isBSS() || Kind.isCommon()) return BSSSection;
if (Kind.isDataNoRel()) return DataSection;
if (Kind.isDataRelLocal()) return DataRelLocalSection;
@@ -762,7 +767,13 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
DataCoalSection
= getMachOSection("__DATA","__datacoal_nt", MCSectionMachO::S_COALESCED,
SectionKind::getDataRel());
-
+ DataCommonSection
+ = getMachOSection("__DATA","__common", MCSectionMachO::S_ZEROFILL,
+ SectionKind::getBSS());
+ DataBSSSection
+ = getMachOSection("__DATA","__bss", MCSectionMachO::S_ZEROFILL,
+ SectionKind::getBSS());
+
LazySymbolPointerSection
= getMachOSection("__DATA", "__la_symbol_ptr",
@@ -921,6 +932,16 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
if (Kind.isReadOnlyWithRel())
return ConstDataSection;
+ // Put zero initialized globals with strong external linkage in the
+ // DATA, __common section with the .zerofill directive.
+ if (Kind.isBSSExtern())
+ return DataCommonSection;
+
+ // Put zero initialized globals with local linkage in __DATA,__bss directive
+ // with the .zerofill directive (aka .lcomm).
+ if (Kind.isBSSLocal())
+ return DataBSSSection;
+
// Otherwise, just drop the variable in the normal data section.
return DataSection;
}
@@ -955,7 +976,8 @@ shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const {
// FIXME: ObjC metadata is currently emitted as internal symbols that have
// \1L and \0l prefixes on them. Fix them to be Private/LinkerPrivate and
// this horrible hack can go away.
- const std::string &Name = Mang->getMangledName(GV);
+ SmallString<64> Name;
+ Mang->getNameWithPrefix(Name, GV, false);
if (Name[0] == 'L' || Name[0] == 'l')
return false;
}
@@ -1064,7 +1086,7 @@ void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
const MCSection *TargetLoweringObjectFileCOFF::
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
- return getCOFFSection(GV->getSection().c_str(), false, Kind);
+ return getCOFFSection(GV->getSection(), false, Kind);
}
static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp
index 46bc9a3..fec59b5 100644
--- a/lib/Target/TargetMachine.cpp
+++ b/lib/Target/TargetMachine.cpp
@@ -46,7 +46,6 @@ namespace llvm {
bool DisableJumpTables;
bool StrongPHIElim;
bool AsmVerbosityDefault(false);
- bool DisableScheduling;
}
static cl::opt<bool, true>
@@ -198,11 +197,6 @@ EnableStrongPHIElim(cl::Hidden, "strong-phi-elim",
cl::desc("Use strong PHI elimination."),
cl::location(StrongPHIElim),
cl::init(false));
-static cl::opt<bool, true>
-DisableInstScheduling("disable-scheduling",
- cl::desc("Disable instruction scheduling"),
- cl::location(DisableScheduling),
- cl::init(false));
//---------------------------------------------------------------------------
// TargetMachine Class
diff --git a/lib/Target/X86/AsmParser/CMakeLists.txt b/lib/Target/X86/AsmParser/CMakeLists.txt
index 034d5ab..40dbdd7 100644
--- a/lib/Target/X86/AsmParser/CMakeLists.txt
+++ b/lib/Target/X86/AsmParser/CMakeLists.txt
@@ -1,6 +1,7 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
add_llvm_library(LLVMX86AsmParser
+ X86AsmLexer.cpp
X86AsmParser.cpp
)
add_dependencies(LLVMX86AsmParser X86CodeGenTable_gen)
diff --git a/lib/Target/X86/AsmParser/Makefile b/lib/Target/X86/AsmParser/Makefile
index 25fb0a2..288b985 100644
--- a/lib/Target/X86/AsmParser/Makefile
+++ b/lib/Target/X86/AsmParser/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMX86AsmParser
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' x86 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/AsmParser/X86AsmLexer.cpp b/lib/Target/X86/AsmParser/X86AsmLexer.cpp
new file mode 100644
index 0000000..1a62044
--- /dev/null
+++ b/lib/Target/X86/AsmParser/X86AsmLexer.cpp
@@ -0,0 +1,43 @@
+//===-- X86AsmLexer.cpp - Tokenize X86 assembly to AsmTokens --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetAsmLexer.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
+#include "X86.h"
+
+using namespace llvm;
+
+namespace {
+
+class X86AsmLexer : public TargetAsmLexer {
+ const MCAsmInfo &AsmInfo;
+protected:
+ AsmToken LexToken();
+public:
+ X86AsmLexer(const Target &T, const MCAsmInfo &MAI)
+ : TargetAsmLexer(T), AsmInfo(MAI) {
+ }
+};
+
+}
+
+AsmToken X86AsmLexer::LexToken() {
+ return AsmToken(AsmToken::Error, "", 0);
+}
+
+extern "C" void LLVMInitializeX86AsmLexer() {
+ RegisterAsmLexer<X86AsmLexer> X(TheX86_32Target);
+ RegisterAsmLexer<X86AsmLexer> Y(TheX86_64Target);
+}
+
+//#define REGISTERS_ONLY
+//#include "../X86GenAsmMatcher.inc"
+//#undef REGISTERS_ONLY
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp
index c4ae5d2..7a9218e 100644
--- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -11,12 +11,12 @@
#include "X86.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/MC/MCAsmLexer.h"
-#include "llvm/MC/MCAsmParser.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCParsedAsmOperand.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetAsmParser.h"
@@ -37,11 +37,10 @@ private:
bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
- bool ParseRegister(X86Operand &Op);
+ bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
- bool ParseOperand(X86Operand &Op);
-
- bool ParseMemOperand(X86Operand &Op);
+ X86Operand *ParseOperand();
+ X86Operand *ParseMemOperand();
bool ParseDirectiveWord(unsigned Size, SMLoc L);
@@ -51,10 +50,6 @@ private:
bool MatchInstruction(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCInst &Inst);
- /// MatchRegisterName - Match the given string to a register name, or 0 if
- /// there is no match.
- unsigned MatchRegisterName(const StringRef &Name);
-
/// }
public:
@@ -69,19 +64,27 @@ public:
} // end anonymous namespace
+/// @name Auto-generated Match Functions
+/// {
+
+static unsigned MatchRegisterName(const StringRef &Name);
+
+/// }
namespace {
/// X86Operand - Instances of this class represent a parsed X86 machine
/// instruction.
struct X86Operand : public MCParsedAsmOperand {
- enum {
+ enum KindTy {
Token,
Register,
Immediate,
Memory
} Kind;
+ SMLoc StartLoc, EndLoc;
+
union {
struct {
const char *Data;
@@ -105,6 +108,14 @@ struct X86Operand : public MCParsedAsmOperand {
} Mem;
};
+ X86Operand(KindTy K, SMLoc Start, SMLoc End)
+ : Kind(K), StartLoc(Start), EndLoc(End) {}
+
+ /// getStartLoc - Get the location of the first token of this operand.
+ SMLoc getStartLoc() const { return StartLoc; }
+ /// getEndLoc - Get the location of the last token of this operand.
+ SMLoc getEndLoc() const { return EndLoc; }
+
StringRef getToken() const {
assert(Kind == Token && "Invalid access!");
return StringRef(Tok.Data, Tok.Length);
@@ -192,44 +203,40 @@ struct X86Operand : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
}
- static X86Operand CreateToken(StringRef Str) {
- X86Operand Res;
- Res.Kind = Token;
- Res.Tok.Data = Str.data();
- Res.Tok.Length = Str.size();
+ static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
+ X86Operand *Res = new X86Operand(Token, Loc, Loc);
+ Res->Tok.Data = Str.data();
+ Res->Tok.Length = Str.size();
return Res;
}
- static X86Operand CreateReg(unsigned RegNo) {
- X86Operand Res;
- Res.Kind = Register;
- Res.Reg.RegNo = RegNo;
+ static X86Operand *CreateReg(unsigned RegNo, SMLoc StartLoc, SMLoc EndLoc) {
+ X86Operand *Res = new X86Operand(Register, StartLoc, EndLoc);
+ Res->Reg.RegNo = RegNo;
return Res;
}
- static X86Operand CreateImm(const MCExpr *Val) {
- X86Operand Res;
- Res.Kind = Immediate;
- Res.Imm.Val = Val;
+ static X86Operand *CreateImm(const MCExpr *Val, SMLoc StartLoc, SMLoc EndLoc){
+ X86Operand *Res = new X86Operand(Immediate, StartLoc, EndLoc);
+ Res->Imm.Val = Val;
return Res;
}
- static X86Operand CreateMem(unsigned SegReg, const MCExpr *Disp,
- unsigned BaseReg, unsigned IndexReg,
- unsigned Scale) {
+ static X86Operand *CreateMem(unsigned SegReg, const MCExpr *Disp,
+ unsigned BaseReg, unsigned IndexReg,
+ unsigned Scale, SMLoc StartLoc, SMLoc EndLoc) {
// We should never just have a displacement, that would be an immediate.
assert((SegReg || BaseReg || IndexReg) && "Invalid memory operand!");
// The scale should always be one of {1,2,4,8}.
assert(((Scale == 1 || Scale == 2 || Scale == 4 || Scale == 8)) &&
"Invalid scale!");
- X86Operand Res;
- Res.Kind = Memory;
- Res.Mem.SegReg = SegReg;
- Res.Mem.Disp = Disp;
- Res.Mem.BaseReg = BaseReg;
- Res.Mem.IndexReg = IndexReg;
- Res.Mem.Scale = Scale;
+ X86Operand *Res = new X86Operand(Memory, StartLoc, EndLoc);
+ Res->Mem.SegReg = SegReg;
+ Res->Mem.Disp = Disp;
+ Res->Mem.BaseReg = BaseReg;
+ Res->Mem.IndexReg = IndexReg;
+ Res->Mem.Scale = Scale;
return Res;
}
};
@@ -237,52 +244,57 @@ struct X86Operand : public MCParsedAsmOperand {
} // end anonymous namespace.
-bool X86ATTAsmParser::ParseRegister(X86Operand &Op) {
- const AsmToken &TokPercent = getLexer().getTok();
- (void)TokPercent; // Avoid warning when assertions are disabled.
+bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
+ SMLoc &StartLoc, SMLoc &EndLoc) {
+ RegNo = 0;
+ const AsmToken &TokPercent = Parser.getTok();
assert(TokPercent.is(AsmToken::Percent) && "Invalid token kind!");
- getLexer().Lex(); // Eat percent token.
+ StartLoc = TokPercent.getLoc();
+ Parser.Lex(); // Eat percent token.
- const AsmToken &Tok = getLexer().getTok();
+ const AsmToken &Tok = Parser.getTok();
if (Tok.isNot(AsmToken::Identifier))
return Error(Tok.getLoc(), "invalid register name");
// FIXME: Validate register for the current architecture; we have to do
// validation later, so maybe there is no need for this here.
- unsigned RegNo;
-
RegNo = MatchRegisterName(Tok.getString());
if (RegNo == 0)
return Error(Tok.getLoc(), "invalid register name");
- Op = X86Operand::CreateReg(RegNo);
- getLexer().Lex(); // Eat identifier token.
-
+ EndLoc = Tok.getLoc();
+ Parser.Lex(); // Eat identifier token.
return false;
}
-bool X86ATTAsmParser::ParseOperand(X86Operand &Op) {
+X86Operand *X86ATTAsmParser::ParseOperand() {
switch (getLexer().getKind()) {
default:
- return ParseMemOperand(Op);
- case AsmToken::Percent:
+ return ParseMemOperand();
+ case AsmToken::Percent: {
// FIXME: if a segment register, this could either be just the seg reg, or
// the start of a memory operand.
- return ParseRegister(Op);
+ unsigned RegNo;
+ SMLoc Start, End;
+ if (ParseRegister(RegNo, Start, End)) return 0;
+ return X86Operand::CreateReg(RegNo, Start, End);
+ }
case AsmToken::Dollar: {
// $42 -> immediate.
- getLexer().Lex();
+ SMLoc Start = Parser.getTok().getLoc(), End;
+ Parser.Lex();
const MCExpr *Val;
- if (getParser().ParseExpression(Val))
- return true;
- Op = X86Operand::CreateImm(Val);
- return false;
+ if (getParser().ParseExpression(Val, End))
+ return 0;
+ return X86Operand::CreateImm(Val, Start, End);
}
}
}
/// ParseMemOperand: segment: disp(basereg, indexreg, scale)
-bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
+X86Operand *X86ATTAsmParser::ParseMemOperand() {
+ SMLoc MemStart = Parser.getTok().getLoc();
+
// FIXME: If SegReg ':' (e.g. %gs:), eat and remember.
unsigned SegReg = 0;
@@ -292,47 +304,47 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
// it.
const MCExpr *Disp = MCConstantExpr::Create(0, getParser().getContext());
if (getLexer().isNot(AsmToken::LParen)) {
- if (getParser().ParseExpression(Disp)) return true;
+ SMLoc ExprEnd;
+ if (getParser().ParseExpression(Disp, ExprEnd)) return 0;
// After parsing the base expression we could either have a parenthesized
// memory address or not. If not, return now. If so, eat the (.
if (getLexer().isNot(AsmToken::LParen)) {
// Unless we have a segment register, treat this as an immediate.
- if (SegReg)
- Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
- else
- Op = X86Operand::CreateImm(Disp);
- return false;
+ if (SegReg == 0)
+ return X86Operand::CreateImm(Disp, MemStart, ExprEnd);
+ return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
}
// Eat the '('.
- getLexer().Lex();
+ Parser.Lex();
} else {
// Okay, we have a '('. We don't know if this is an expression or not, but
// so we have to eat the ( to see beyond it.
- getLexer().Lex(); // Eat the '('.
+ SMLoc LParenLoc = Parser.getTok().getLoc();
+ Parser.Lex(); // Eat the '('.
if (getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::Comma)) {
// Nothing to do here, fall into the code below with the '(' part of the
// memory operand consumed.
} else {
+ SMLoc ExprEnd;
+
// It must be an parenthesized expression, parse it now.
- if (getParser().ParseParenExpression(Disp))
- return true;
+ if (getParser().ParseParenExpression(Disp, ExprEnd))
+ return 0;
// After parsing the base expression we could either have a parenthesized
// memory address or not. If not, return now. If so, eat the (.
if (getLexer().isNot(AsmToken::LParen)) {
// Unless we have a segment register, treat this as an immediate.
- if (SegReg)
- Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 1);
- else
- Op = X86Operand::CreateImm(Disp);
- return false;
+ if (SegReg == 0)
+ return X86Operand::CreateImm(Disp, LParenLoc, ExprEnd);
+ return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, MemStart, ExprEnd);
}
// Eat the '('.
- getLexer().Lex();
+ Parser.Lex();
}
}
@@ -341,13 +353,12 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
unsigned BaseReg = 0, IndexReg = 0, Scale = 1;
if (getLexer().is(AsmToken::Percent)) {
- if (ParseRegister(Op))
- return true;
- BaseReg = Op.getReg();
+ SMLoc L;
+ if (ParseRegister(BaseReg, L, L)) return 0;
}
if (getLexer().is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat the comma.
+ Parser.Lex(); // Eat the comma.
// Following the comma we should have either an index register, or a scale
// value. We don't support the later form, but we want to parse it
@@ -356,82 +367,89 @@ bool X86ATTAsmParser::ParseMemOperand(X86Operand &Op) {
// Not that even though it would be completely consistent to support syntax
// like "1(%eax,,1)", the assembler doesn't.
if (getLexer().is(AsmToken::Percent)) {
- if (ParseRegister(Op))
- return true;
- IndexReg = Op.getReg();
+ SMLoc L;
+ if (ParseRegister(IndexReg, L, L)) return 0;
if (getLexer().isNot(AsmToken::RParen)) {
// Parse the scale amount:
// ::= ',' [scale-expression]
- if (getLexer().isNot(AsmToken::Comma))
- return true;
- getLexer().Lex(); // Eat the comma.
+ if (getLexer().isNot(AsmToken::Comma)) {
+ Error(Parser.getTok().getLoc(),
+ "expected comma in scale expression");
+ return 0;
+ }
+ Parser.Lex(); // Eat the comma.
if (getLexer().isNot(AsmToken::RParen)) {
- SMLoc Loc = getLexer().getTok().getLoc();
+ SMLoc Loc = Parser.getTok().getLoc();
int64_t ScaleVal;
if (getParser().ParseAbsoluteExpression(ScaleVal))
- return true;
+ return 0;
// Validate the scale amount.
- if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8)
- return Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
+ if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8){
+ Error(Loc, "scale factor in address must be 1, 2, 4 or 8");
+ return 0;
+ }
Scale = (unsigned)ScaleVal;
}
}
} else if (getLexer().isNot(AsmToken::RParen)) {
// Otherwise we have the unsupported form of a scale amount without an
// index.
- SMLoc Loc = getLexer().getTok().getLoc();
+ SMLoc Loc = Parser.getTok().getLoc();
int64_t Value;
if (getParser().ParseAbsoluteExpression(Value))
- return true;
+ return 0;
- return Error(Loc, "cannot have scale factor without index register");
+ Error(Loc, "cannot have scale factor without index register");
+ return 0;
}
}
// Ok, we've eaten the memory operand, verify we have a ')' and eat it too.
- if (getLexer().isNot(AsmToken::RParen))
- return Error(getLexer().getTok().getLoc(),
- "unexpected token in memory operand");
- getLexer().Lex(); // Eat the ')'.
+ if (getLexer().isNot(AsmToken::RParen)) {
+ Error(Parser.getTok().getLoc(), "unexpected token in memory operand");
+ return 0;
+ }
+ SMLoc MemEnd = Parser.getTok().getLoc();
+ Parser.Lex(); // Eat the ')'.
- Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale);
- return false;
+ return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
+ MemStart, MemEnd);
}
bool X86ATTAsmParser::
ParseInstruction(const StringRef &Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- Operands.push_back(new X86Operand(X86Operand::CreateToken(Name)));
+ Operands.push_back(X86Operand::CreateToken(Name, NameLoc));
- SMLoc Loc = getLexer().getTok().getLoc();
if (getLexer().isNot(AsmToken::EndOfStatement)) {
// Parse '*' modifier.
if (getLexer().is(AsmToken::Star)) {
- getLexer().Lex(); // Eat the star.
- Operands.push_back(new X86Operand(X86Operand::CreateToken("*")));
+ SMLoc Loc = Parser.getTok().getLoc();
+ Operands.push_back(X86Operand::CreateToken("*", Loc));
+ Parser.Lex(); // Eat the star.
}
// Read the first operand.
- X86Operand Op;
- if (ParseOperand(Op))
+ if (X86Operand *Op = ParseOperand())
+ Operands.push_back(Op);
+ else
return true;
-
- Operands.push_back(new X86Operand(Op));
-
+
while (getLexer().is(AsmToken::Comma)) {
- getLexer().Lex(); // Eat the comma.
+ Parser.Lex(); // Eat the comma.
// Parse and remember the operand.
- if (ParseOperand(Op))
+ if (X86Operand *Op = ParseOperand())
+ Operands.push_back(Op);
+ else
return true;
- Operands.push_back(new X86Operand(Op));
}
}
@@ -454,7 +472,7 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
if (getParser().ParseExpression(Value))
return true;
- getParser().getStreamer().EmitValue(Value, Size);
+ getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/);
if (getLexer().is(AsmToken::EndOfStatement))
break;
@@ -462,18 +480,21 @@ bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
// FIXME: Improve diagnostic.
if (getLexer().isNot(AsmToken::Comma))
return Error(L, "unexpected token in directive");
- getLexer().Lex();
+ Parser.Lex();
}
}
- getLexer().Lex();
+ Parser.Lex();
return false;
}
+extern "C" void LLVMInitializeX86AsmLexer();
+
// Force static initialization.
extern "C" void LLVMInitializeX86AsmParser() {
RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
RegisterAsmParser<X86ATTAsmParser> Y(TheX86_64Target);
+ LLVMInitializeX86AsmLexer();
}
#include "X86GenAsmMatcher.inc"
diff --git a/lib/Target/X86/AsmPrinter/Makefile b/lib/Target/X86/AsmPrinter/Makefile
index 2368761..326a22f 100644
--- a/lib/Target/X86/AsmPrinter/Makefile
+++ b/lib/Target/X86/AsmPrinter/Makefile
@@ -8,6 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ../../../..
LIBRARYNAME = LLVMX86AsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' x86 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
index c74b97a..804dbb9 100644
--- a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
@@ -55,7 +55,7 @@ void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
O << (int)Op.getImm();
else {
assert(Op.isExpr() && "unknown pcrel immediate operand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
@@ -68,8 +68,7 @@ void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo) {
O << '$' << Op.getImm();
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
- O << '$';
- Op.getExpr()->print(O, &MAI);
+ O << '$' << *Op.getExpr();
}
}
@@ -84,7 +83,7 @@ void X86ATTInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
O << DispVal;
} else {
assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
- DispSpec.getExpr()->print(O, &MAI);
+ O << *DispSpec.getExpr();
}
if (IndexReg.getReg() || BaseReg.getReg()) {
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index 70c6dd0..2ffa18f 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -36,7 +36,6 @@
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
@@ -61,7 +60,7 @@ void X86AsmPrinter::printMCInst(const MCInst *MI) {
void X86AsmPrinter::PrintPICBaseSymbol() const {
// FIXME: Gross const cast hack.
X86AsmPrinter *AP = const_cast<X86AsmPrinter*>(this);
- X86MCInstLower(OutContext, 0, *AP).GetPICBaseSymbol()->print(O, MAI);
+ O << *X86MCInstLower(OutContext, 0, *AP).GetPICBaseSymbol();
}
void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
@@ -71,7 +70,8 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
if (Subtarget->isTargetCygMing()) {
X86COFFMachineModuleInfo &COFFMMI =
MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(CurrentFnName, F, *TM.getTargetData());
+ COFFMMI.DecorateCygMingName(CurrentFnSym, OutContext, F,
+ *TM.getTargetData());
}
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
@@ -84,7 +84,7 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
break;
case Function::DLLExportLinkage:
case Function::ExternalLinkage:
- O << "\t.globl\t" << CurrentFnName << '\n';
+ OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
break;
case Function::LinkerPrivateLinkage:
case Function::LinkOnceAnyLinkage:
@@ -92,30 +92,30 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
if (Subtarget->isTargetDarwin()) {
- O << "\t.globl\t" << CurrentFnName << '\n';
- O << MAI->getWeakDefDirective() << CurrentFnName << '\n';
+ OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
+ O << MAI->getWeakDefDirective() << *CurrentFnSym << '\n';
} else if (Subtarget->isTargetCygMing()) {
- O << "\t.globl\t" << CurrentFnName << "\n"
- "\t.linkonce discard\n";
+ OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
+ O << "\t.linkonce discard\n";
} else {
- O << "\t.weak\t" << CurrentFnName << '\n';
+ O << "\t.weak\t" << *CurrentFnSym << '\n';
}
break;
}
- printVisibility(CurrentFnName, F->getVisibility());
+ printVisibility(CurrentFnSym, F->getVisibility());
- if (Subtarget->isTargetELF())
- O << "\t.type\t" << CurrentFnName << ",@function\n";
- else if (Subtarget->isTargetCygMing()) {
- O << "\t.def\t " << CurrentFnName
- << ";\t.scl\t" <<
+ if (Subtarget->isTargetELF()) {
+ O << "\t.type\t" << *CurrentFnSym << ",@function\n";
+ } else if (Subtarget->isTargetCygMing()) {
+ O << "\t.def\t " << *CurrentFnSym;
+ O << ";\t.scl\t" <<
(F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT)
<< ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
<< ";\t.endef\n";
}
- O << CurrentFnName << ':';
+ O << *CurrentFnSym << ':';
if (VerboseAsm) {
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << ' ';
@@ -126,7 +126,7 @@ void X86AsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
// Add some workaround for linkonce linkage on Cygwin\MinGW
if (Subtarget->isTargetCygMing() &&
(F->hasLinkOnceLinkage() || F->hasWeakLinkage()))
- O << "Lllvm$workaround$fake$stub$" << CurrentFnName << ":\n";
+ O << "Lllvm$workaround$fake$stub$" << *CurrentFnSym << ":\n";
}
/// runOnMachineFunction - This uses the printMachineInstruction()
@@ -184,7 +184,7 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
}
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
+ O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
// Emit post-function debug information.
if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
@@ -201,93 +201,78 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
/// jump tables, constant pools, global address and external symbols, all of
/// which print to a label with various suffixes for relocation types etc.
void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
- SmallString<128> TempNameStr;
switch (MO.getType()) {
default: llvm_unreachable("unknown symbol type!");
case MachineOperand::MO_JumpTableIndex:
- O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
- << MO.getIndex();
+ O << *GetJTISymbol(MO.getIndex());
break;
case MachineOperand::MO_ConstantPoolIndex:
- O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
- << MO.getIndex();
+ O << *GetCPISymbol(MO.getIndex());
printOffset(MO.getOffset());
break;
case MachineOperand::MO_GlobalAddress: {
const GlobalValue *GV = MO.getGlobal();
- const char *Suffix = "";
+ MCSymbol *GVSym;
if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
- Suffix = "$stub";
+ GVSym = GetSymbolWithGlobalValueBase(GV, "$stub");
else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
- Suffix = "$non_lazy_ptr";
-
- std::string Name = Mang->getMangledName(GV, Suffix, Suffix[0] != '\0');
+ GVSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
+ else
+ GVSym = GetGlobalValueSymbol(GV);
+
if (Subtarget->isTargetCygMing()) {
X86COFFMachineModuleInfo &COFFMMI =
MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
- COFFMMI.DecorateCygMingName(Name, GV, *TM.getTargetData());
+ COFFMMI.DecorateCygMingName(GVSym, OutContext, GV, *TM.getTargetData());
}
// Handle dllimport linkage.
if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
- Name = "__imp_" + Name;
+ GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName());
if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
- Mang->getNameWithPrefix(TempNameStr, GV, true);
- TempNameStr += "$non_lazy_ptr";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
- if (StubSym == 0) {
- TempNameStr.clear();
- Mang->getNameWithPrefix(TempNameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
- }
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
+
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
- Mang->getNameWithPrefix(TempNameStr, GV, true);
- TempNameStr += "$non_lazy_ptr";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(Sym);
- if (StubSym == 0) {
- TempNameStr.clear();
- Mang->getNameWithPrefix(TempNameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
- }
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
} else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
- Mang->getNameWithPrefix(TempNameStr, GV, true);
- TempNameStr += "$stub";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub");
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
- if (StubSym == 0) {
- TempNameStr.clear();
- Mang->getNameWithPrefix(TempNameStr, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str());
- }
+ if (StubSym == 0)
+ StubSym = GetGlobalValueSymbol(GV);
}
// If the name begins with a dollar-sign, enclose it in parens. We do this
// to avoid having it look like an integer immediate to the assembler.
- if (Name[0] == '$')
- O << '(' << Name << ')';
+ if (GVSym->getName()[0] != '$')
+ O << *GVSym;
else
- O << Name;
-
+ O << '(' << *GVSym << ')';
printOffset(MO.getOffset());
break;
}
case MachineOperand::MO_ExternalSymbol: {
const MCSymbol *SymToPrint;
if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
- Mang->getNameWithPrefix(TempNameStr,
- StringRef(MO.getSymbolName())+"$stub");
- const MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ SmallString<128> TempNameStr;
+ TempNameStr += StringRef(MO.getSymbolName());
+ TempNameStr += StringRef("$stub");
+
+ const MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str());
const MCSymbol *&StubSym =
MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
if (StubSym == 0) {
@@ -296,19 +281,15 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) {
}
SymToPrint = StubSym;
} else {
- Mang->getNameWithPrefix(TempNameStr, MO.getSymbolName());
- SymToPrint = OutContext.GetOrCreateSymbol(TempNameStr.str());
+ SymToPrint = GetExternalSymbolSymbol(MO.getSymbolName());
}
// If the name begins with a dollar-sign, enclose it in parens. We do this
// to avoid having it look like an integer immediate to the assembler.
if (SymToPrint->getName()[0] != '$')
- SymToPrint->print(O, MAI);
- else {
- O << '(';
- SymToPrint->print(O, MAI);
- O << '(';
- }
+ O << *SymToPrint;
+ else
+ O << '(' << *SymToPrint << '(';
break;
}
}
@@ -357,7 +338,7 @@ void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
O << MO.getImm();
return;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
return;
case MachineOperand::MO_GlobalAddress:
case MachineOperand::MO_ExternalSymbol:
@@ -368,7 +349,7 @@ void X86AsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
void X86AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
- const char *Modifier) {
+ const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
default: llvm_unreachable("unknown operand type!");
@@ -482,11 +463,10 @@ void X86AsmPrinter::printPICJumpTableSetLabel(unsigned uid,
O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix()
<< getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ',';
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MBB->getNumber());
if (Subtarget->isPICStyleRIPRel())
- O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << uid << '\n';
+ O << '-' << *GetJTISymbol(uid) << '\n';
else {
O << '-';
PrintPICBaseSymbol();
@@ -513,11 +493,10 @@ void X86AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
if (Subtarget->isPICStyleRIPRel() || Subtarget->isPICStyleStubPIC()) {
O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
<< '_' << uid << "_set_" << MBB->getNumber();
- } else if (Subtarget->isPICStyleGOT()) {
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
- O << "@GOTOFF";
- } else
- GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+ } else if (Subtarget->isPICStyleGOT())
+ O << *GetMBBSymbol(MBB->getNumber()) << "@GOTOFF";
+ else
+ O << *GetMBBSymbol(MBB->getNumber());
}
bool X86AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) {
@@ -664,147 +643,6 @@ void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
processDebugLoc(MI, false);
}
-void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
- if (!GVar->hasInitializer())
- return; // External global require no code
-
- // Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GVar)) {
- if (Subtarget->isTargetDarwin() &&
- TM.getRelocationModel() == Reloc::Static) {
- if (GVar->getName() == "llvm.global_ctors")
- O << ".reference .constructors_used\n";
- else if (GVar->getName() == "llvm.global_dtors")
- O << ".reference .destructors_used\n";
- }
- return;
- }
-
- const TargetData *TD = TM.getTargetData();
-
- std::string name = Mang->getMangledName(GVar);
- Constant *C = GVar->getInitializer();
- const Type *Type = C->getType();
- unsigned Size = TD->getTypeAllocSize(Type);
- unsigned Align = TD->getPreferredAlignmentLog(GVar);
-
- printVisibility(name, GVar->getVisibility());
-
- if (Subtarget->isTargetELF())
- O << "\t.type\t" << name << ",@object\n";
-
-
- SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
- const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
- OutStreamer.SwitchSection(TheSection);
-
- // FIXME: get this stuff from section kind flags.
- if (C->isNullValue() && !GVar->hasSection() &&
- // Don't put things that should go in the cstring section into "comm".
- !TheSection->getKind().isMergeableCString()) {
- if (GVar->hasExternalLinkage()) {
- if (const char *Directive = MAI->getZeroFillDirective()) {
- O << "\t.globl " << name << '\n';
- O << Directive << "__DATA, __common, " << name << ", "
- << Size << ", " << Align << '\n';
- return;
- }
- }
-
- if (!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (MAI->getLCOMMDirective() != NULL) {
- if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << name << ',' << Size;
- if (Subtarget->isTargetDarwin())
- O << ',' << Align;
- } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) {
- O << "\t.globl " << name << '\n'
- << MAI->getWeakDefDirective() << name << '\n';
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- EmitGlobalConstant(C);
- return;
- } else {
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
- }
- } else {
- if (!Subtarget->isTargetCygMing()) {
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << name << '\n';
- }
- O << MAI->getCOMMDirective() << name << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
- }
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- return;
- }
- }
-
- switch (GVar->getLinkage()) {
- case GlobalValue::CommonLinkage:
- case GlobalValue::LinkOnceAnyLinkage:
- case GlobalValue::LinkOnceODRLinkage:
- case GlobalValue::WeakAnyLinkage:
- case GlobalValue::WeakODRLinkage:
- case GlobalValue::LinkerPrivateLinkage:
- if (Subtarget->isTargetDarwin()) {
- O << "\t.globl " << name << '\n'
- << MAI->getWeakDefDirective() << name << '\n';
- } else if (Subtarget->isTargetCygMing()) {
- O << "\t.globl\t" << name << "\n"
- "\t.linkonce same_size\n";
- } else {
- O << "\t.weak\t" << name << '\n';
- }
- break;
- case GlobalValue::DLLExportLinkage:
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
- case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol
- O << "\t.globl " << name << '\n';
- // FALL THROUGH
- case GlobalValue::PrivateLinkage:
- case GlobalValue::InternalLinkage:
- break;
- default:
- llvm_unreachable("Unknown linkage type!");
- }
-
- EmitAlignment(Align, GVar);
- O << name << ":";
- if (VerboseAsm){
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
-
- EmitGlobalConstant(C);
-
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << name << ", " << Size << '\n';
-}
-
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetDarwin()) {
// All darwin targets use mach-o.
@@ -828,10 +666,9 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TheSection);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n" << "\t.indirect_symbol ";
+ O << *Stubs[i].first << ":\n";
// Get the MCSymbol without the $stub suffix.
- Stubs[i].second->print(O, MAI);
+ O << "\t.indirect_symbol " << *Stubs[i].second;
O << "\n\thlt ; hlt ; hlt ; hlt ; hlt\n";
}
O << '\n';
@@ -849,9 +686,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
OutStreamer.SwitchSection(TheSection);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n\t.indirect_symbol ";
- Stubs[i].second->print(O, MAI);
+ O << *Stubs[i].first << ":\n\t.indirect_symbol " << *Stubs[i].second;
O << "\n\t.long\t0\n";
}
Stubs.clear();
@@ -863,10 +698,8 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
EmitAlignment(2);
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
- Stubs[i].first->print(O, MAI);
- O << ":\n" << MAI->getData32bitsDirective();
- Stubs[i].second->print(O, MAI);
- O << '\n';
+ O << *Stubs[i].first << ":\n" << MAI->getData32bitsDirective();
+ O << *Stubs[i].second << '\n';
}
Stubs.clear();
}
@@ -876,7 +709,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
// implementation of multiple entry points). If this doesn't occur, the
// linker can safely perform dead code stripping. Since LLVM never
// generates code that does this, it is always safe to set.
- OutStreamer.EmitAssemblerFlag(MCStreamer::SubsectionsViaSymbols);
+ OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
}
if (Subtarget->isTargetCOFF()) {
@@ -894,25 +727,22 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
if (Subtarget->isTargetCygMing()) {
// Necessary for dllexport support
- std::vector<std::string> DLLExportedFns, DLLExportedGlobals;
+ std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals;
TargetLoweringObjectFileCOFF &TLOFCOFF =
static_cast<TargetLoweringObjectFileCOFF&>(getObjFileLowering());
for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
if (I->hasDLLExportLinkage()) {
- std::string Name = Mang->getMangledName(I);
- COFFMMI.DecorateCygMingName(Name, I, *TM.getTargetData());
- DLLExportedFns.push_back(Name);
+ MCSymbol *Sym = GetGlobalValueSymbol(I);
+ COFFMMI.DecorateCygMingName(Sym, OutContext, I, *TM.getTargetData());
+ DLLExportedFns.push_back(Sym);
}
for (Module::const_global_iterator I = M.global_begin(),
E = M.global_end(); I != E; ++I)
- if (I->hasDLLExportLinkage()) {
- std::string Name = Mang->getMangledName(I);
- COFFMMI.DecorateCygMingName(Name, I, *TM.getTargetData());
- DLLExportedGlobals.push_back(Mang->getMangledName(I));
- }
+ if (I->hasDLLExportLinkage())
+ DLLExportedGlobals.push_back(GetGlobalValueSymbol(I));
// Output linker support code for dllexported globals on windows.
if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
@@ -920,10 +750,10 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
true,
SectionKind::getMetadata()));
for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i)
- O << "\t.ascii \" -export:" << DLLExportedGlobals[i] << ",data\"\n";
+ O << "\t.ascii \" -export:" << *DLLExportedGlobals[i] << ",data\"\n";
for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i)
- O << "\t.ascii \" -export:" << DLLExportedFns[i] << "\"\n";
+ O << "\t.ascii \" -export:" << *DLLExportedFns[i] << "\"\n";
}
}
}
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
index 0351829..6a9262d 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.h
@@ -135,7 +135,6 @@ class VISIBILITY_HIDDEN X86AsmPrinter : public AsmPrinter {
unsigned uid) const;
void printPICLabel(const MachineInstr *MI, unsigned Op);
- void PrintGlobalVariable(const GlobalVariable* GVar);
void PrintPICBaseSymbol() const;
diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
index fde5902..4efb529 100644
--- a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
@@ -52,7 +52,7 @@ void X86IntelInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
O << Op.getImm();
else {
assert(Op.isExpr() && "unknown pcrel immediate operand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
@@ -72,7 +72,7 @@ void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
O << Op.getImm();
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
- Op.getExpr()->print(O, &MAI);
+ O << *Op.getExpr();
}
}
@@ -102,7 +102,7 @@ void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
if (!DispSpec.isImm()) {
if (NeedPlus) O << " + ";
assert(DispSpec.isExpr() && "non-immediate displacement for LEA?");
- DispSpec.getExpr()->print(O, &MAI);
+ O << *DispSpec.getExpr();
} else {
int64_t DispVal = DispSpec.getImm();
if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) {
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
index 9ee118c..b970d46 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
@@ -16,16 +16,15 @@
#include "X86AsmPrinter.h"
#include "X86MCAsmInfo.h"
#include "X86COFFMachineModuleInfo.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/Support/ErrorHandling.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/Analysis/DebugInfo.h"
using namespace llvm;
@@ -83,33 +82,24 @@ GetGlobalAddressSymbol(const MachineOperand &MO) const {
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
const MCSymbol *&StubSym = getMachOMMI().getGVStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
Name += "$non_lazy_ptr";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
const MCSymbol *&StubSym = getMachOMMI().getHiddenGVStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
case X86II::MO_DARWIN_STUB: {
Name += "$stub";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
const MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
// FIXME: These probably should be a modifier on the symbol or something??
@@ -173,6 +163,8 @@ GetExternalSymbolSymbol(const MachineOperand &MO) const {
MCSymbol *X86MCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
+ // FIXME: Use AsmPrinter.GetJTISymbol. @TLSGD shouldn't be part of the symbol
+ // name!
raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "JTI"
<< AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
@@ -204,6 +196,8 @@ MCSymbol *X86MCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const {
MCSymbol *X86MCInstLower::
GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
+ // FIXME: USe AsmPrinter.GetCPISymbol. @TLSGD shouldn't be part of the symbol
+ // name!
raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "CPI"
<< AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
@@ -422,22 +416,28 @@ void X86AsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
printLabel(MI);
return;
case TargetInstrInfo::DEBUG_VALUE: {
+ // FIXME: if this is implemented for another target before it goes
+ // away completely, the common part should be moved into AsmPrinter.
if (!VerboseAsm)
return;
O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
- // cast away const; DIetc do not take const operands for some reason
- DIVariable V((MDNode*)(MI->getOperand(2).getMetadata()));
+ unsigned NOps = MI->getNumOperands();
+ // cast away const; DIetc do not take const operands for some reason.
+ DIVariable V((MDNode*)(MI->getOperand(NOps-1).getMetadata()));
O << V.getName();
O << " <- ";
- if (MI->getOperand(0).getType()==MachineOperand::MO_Register)
+ if (NOps==3) {
+ // Variable is in register
+ assert(MI->getOperand(0).getType()==MachineOperand::MO_Register);
printOperand(MI, 0);
- else {
- assert(MI->getOperand(0).getType()==MachineOperand::MO_Immediate);
- int64_t imm = MI->getOperand(0).getImm();
- O << '[' << ((imm<0) ? "EBP" : "ESP+") << imm << ']';
+ } else {
+ // Frame address. Currently handles register +- offset only.
+ assert(MI->getOperand(0).getType()==MachineOperand::MO_Register);
+ assert(MI->getOperand(3).getType()==MachineOperand::MO_Immediate);
+ O << '['; printOperand(MI, 0); O << '+'; printOperand(MI, 3); O << ']';
}
O << "+";
- printOperand(MI, 1);
+ printOperand(MI, NOps-2);
return;
}
case TargetInstrInfo::INLINEASM:
diff --git a/lib/Target/X86/Disassembler/Makefile b/lib/Target/X86/Disassembler/Makefile
index b289647..6c26853 100644
--- a/lib/Target/X86/Disassembler/Makefile
+++ b/lib/Target/X86/Disassembler/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMX86Disassembler
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' x86 target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/Makefile b/lib/Target/X86/Makefile
index 6098dbf..5e625dc 100644
--- a/lib/Target/X86/Makefile
+++ b/lib/Target/X86/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMX86CodeGen
TARGET = X86
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
diff --git a/lib/Target/X86/TargetInfo/Makefile b/lib/Target/X86/TargetInfo/Makefile
index 6677d4b..211607f 100644
--- a/lib/Target/X86/TargetInfo/Makefile
+++ b/lib/Target/X86/TargetInfo/Makefile
@@ -6,8 +6,10 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../../..
LIBRARYNAME = LLVMX86Info
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.cpp b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
index 01c4fcf..ea52795 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.cpp
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.cpp
@@ -15,6 +15,8 @@
#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"
@@ -23,7 +25,6 @@ using namespace llvm;
X86COFFMachineModuleInfo::X86COFFMachineModuleInfo(const MachineModuleInfo &) {
}
X86COFFMachineModuleInfo::~X86COFFMachineModuleInfo() {
-
}
void X86COFFMachineModuleInfo::AddFunctionInfo(const Function *F,
@@ -114,10 +115,12 @@ void X86COFFMachineModuleInfo::DecorateCygMingName(SmallVectorImpl<char> &Name,
/// DecorateCygMingName - Query FunctionInfoMap and use this information for
/// various name decorations for Cygwin and MingW.
-void X86COFFMachineModuleInfo::DecorateCygMingName(std::string &Name,
+void X86COFFMachineModuleInfo::DecorateCygMingName(MCSymbol *&Name,
+ MCContext &Ctx,
const GlobalValue *GV,
const TargetData &TD) {
- SmallString<128> NameStr(Name.begin(), Name.end());
+ SmallString<128> NameStr(Name->getName().begin(), Name->getName().end());
DecorateCygMingName(NameStr, GV, TD);
- Name.assign(NameStr.begin(), NameStr.end());
+
+ Name = Ctx.GetOrCreateSymbol(NameStr.str());
}
diff --git a/lib/Target/X86/X86COFFMachineModuleInfo.h b/lib/Target/X86/X86COFFMachineModuleInfo.h
index 5017af2..0e2009e 100644
--- a/lib/Target/X86/X86COFFMachineModuleInfo.h
+++ b/lib/Target/X86/X86COFFMachineModuleInfo.h
@@ -46,8 +46,8 @@ public:
~X86COFFMachineModuleInfo();
- void DecorateCygMingName(std::string &Name, const GlobalValue *GV,
- const TargetData &TD);
+ void DecorateCygMingName(MCSymbol* &Name, MCContext &Ctx,
+ const GlobalValue *GV, const TargetData &TD);
void DecorateCygMingName(SmallVectorImpl<char> &Name, const GlobalValue *GV,
const TargetData &TD);
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 7e02d59..d5ad61b 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -1153,6 +1153,10 @@ bool X86FastISel::X86VisitIntrinsicCall(IntrinsicInst &I) {
// FIXME: Handle more intrinsics.
switch (I.getIntrinsicID()) {
default: return false;
+ case Intrinsic::trap: {
+ BuildMI(MBB, DL, TII.get(X86::TRAP));
+ return true;
+ }
case Intrinsic::sadd_with_overflow:
case Intrinsic::uadd_with_overflow: {
// Replace "add with overflow" intrinsics with an "add" instruction followed
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index e2a53d1..91e0483 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -384,8 +384,11 @@ static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load,
///
static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address,
SDValue &Load) {
- if (N.getOpcode() == ISD::BIT_CONVERT)
+ if (N.getOpcode() == ISD::BIT_CONVERT) {
+ if (!N.hasOneUse())
+ return false;
N = N.getOperand(0);
+ }
LoadSDNode *LD = dyn_cast<LoadSDNode>(N);
if (!LD || LD->isVolatile())
@@ -595,6 +598,7 @@ void X86DAGToDAGISel::PreprocessForRMW() {
if (RModW) {
MoveBelowTokenFactor(CurDAG, Load, SDValue(I, 0), Chain);
++NumLoadMoved;
+ checkForCycles(I);
}
}
}
@@ -940,7 +944,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
// Okay, we know that we have a scale by now. However, if the scaled
// value is an add of something and a constant, we can fold the
// constant into the disp field here.
- if (ShVal.getNode()->getOpcode() == ISD::ADD && ShVal.hasOneUse() &&
+ if (ShVal.getNode()->getOpcode() == ISD::ADD &&
isa<ConstantSDNode>(ShVal.getNode()->getOperand(1))) {
AM.IndexReg = ShVal.getNode()->getOperand(0);
ConstantSDNode *AddVal =
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 228ec9f..11e07df 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -3390,17 +3390,10 @@ X86TargetLowering::LowerAsSplatVectorLoad(SDValue SrcOp, EVT VT, DebugLoc dl,
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
if (DAG.InferPtrAlignment(Ptr) < 16) {
if (MFI->isFixedObjectIndex(FI)) {
- // Can't change the alignment. Reference stack + offset explicitly
- // if stack pointer is at least 16-byte aligned.
- unsigned StackAlign = Subtarget->getStackAlignment();
- if (StackAlign < 16)
- return SDValue();
- Offset = MFI->getObjectOffset(FI) + Offset;
- SDValue StackPtr = DAG.getCopyFromReg(Chain, dl, X86StackPtr,
- getPointerTy());
- Ptr = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr,
- DAG.getConstant(Offset & ~15, getPointerTy()));
- Offset %= 16;
+ // Can't change the alignment. FIXME: It's possible to compute
+ // the exact stack offset and reference FI + adjust offset instead.
+ // If someone *really* cares about this. That's the way to implement it.
+ return SDValue();
} else {
MFI->setObjectAlignment(FI, 16);
}
@@ -7579,7 +7572,7 @@ bool X86TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
bool X86TargetLowering::isZExtFree(const Type *Ty1, const Type *Ty2) const {
// x86-64 implicitly zero-extends 32-bit results in 64-bit registers.
- return Ty1->isInteger(64) && Ty2->isInteger(64) && Subtarget->is64Bit();
+ return Ty1->isInteger(32) && Ty2->isInteger(64) && Subtarget->is64Bit();
}
bool X86TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 08e1dd1..9037ba6 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -207,7 +207,7 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
// EH Pseudo Instructions
//
let isTerminator = 1, isReturn = 1, isBarrier = 1,
- hasCtrlDep = 1 in {
+ hasCtrlDep = 1, isCodeGenOnly = 1 in {
def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
"ret\t#eh_return, addr: $addr",
[(X86ehret GR64:$addr)]>;
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 7b39fb3..3ae352c 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -402,7 +402,7 @@ X86InstrInfo::X86InstrInfo(X86TargetMachine &tm)
{ X86::MOVSX64rr32, X86::MOVSX64rm32, 0 },
{ X86::MOVSX64rr8, X86::MOVSX64rm8, 0 },
{ X86::MOVUPDrr, X86::MOVUPDrm, 16 },
- { X86::MOVUPSrr, X86::MOVUPSrm, 16 },
+ { X86::MOVUPSrr, X86::MOVUPSrm, 0 },
{ X86::MOVZDI2PDIrr, X86::MOVZDI2PDIrm, 0 },
{ X86::MOVZQI2PQIrr, X86::MOVZQI2PQIrm, 0 },
{ X86::MOVZPQILo2PQIrr, X86::MOVZPQILo2PQIrm, 16 },
@@ -2077,8 +2077,7 @@ void X86InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
unsigned SrcReg, bool isKill, int FrameIdx,
const TargetRegisterClass *RC) const {
const MachineFunction &MF = *MBB.getParent();
- bool isAligned = (RI.getStackAlignment() >= 16) ||
- RI.needsStackRealignment(MF);
+ bool isAligned = (RI.getStackAlignment() >= 16) || RI.canRealignStack(MF);
unsigned Opc = getStoreRegOpcode(SrcReg, RC, isAligned, TM);
DebugLoc DL = DebugLoc::getUnknownLoc();
if (MI != MBB.end()) DL = MI->getDebugLoc();
@@ -2172,8 +2171,7 @@ void X86InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
unsigned DestReg, int FrameIdx,
const TargetRegisterClass *RC) const{
const MachineFunction &MF = *MBB.getParent();
- bool isAligned = (RI.getStackAlignment() >= 16) ||
- RI.needsStackRealignment(MF);
+ bool isAligned = (RI.getStackAlignment() >= 16) || RI.canRealignStack(MF);
unsigned Opc = getLoadRegOpcode(DestReg, RC, isAligned, TM);
DebugLoc DL = DebugLoc::getUnknownLoc();
if (MI != MBB.end()) DL = MI->getDebugLoc();
@@ -2202,8 +2200,7 @@ bool X86InstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
if (CSI.empty())
return false;
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (MI != MBB.end()) DL = MI->getDebugLoc();
+ DebugLoc DL = MBB.findDebugLoc(MI);
bool is64Bit = TM.getSubtarget<X86Subtarget>().is64Bit();
bool isWin64 = TM.getSubtarget<X86Subtarget>().isTargetWin64();
@@ -2241,8 +2238,7 @@ bool X86InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
if (CSI.empty())
return false;
- DebugLoc DL = DebugLoc::getUnknownLoc();
- if (MI != MBB.end()) DL = MI->getDebugLoc();
+ DebugLoc DL = MBB.findDebugLoc(MI);
MachineFunction &MF = *MBB.getParent();
unsigned FPReg = RI.getFrameRegister(MF);
@@ -2872,6 +2868,138 @@ unsigned X86InstrInfo::getOpcodeAfterMemoryUnfold(unsigned Opc,
return I->second.first;
}
+bool
+X86InstrInfo::areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
+ int64_t &Offset1, int64_t &Offset2) const {
+ if (!Load1->isMachineOpcode() || !Load2->isMachineOpcode())
+ return false;
+ unsigned Opc1 = Load1->getMachineOpcode();
+ unsigned Opc2 = Load2->getMachineOpcode();
+ switch (Opc1) {
+ default: return false;
+ case X86::MOV8rm:
+ case X86::MOV16rm:
+ case X86::MOV32rm:
+ case X86::MOV64rm:
+ case X86::LD_Fp32m:
+ case X86::LD_Fp64m:
+ case X86::LD_Fp80m:
+ case X86::MOVSSrm:
+ case X86::MOVSDrm:
+ case X86::MMX_MOVD64rm:
+ case X86::MMX_MOVQ64rm:
+ case X86::FsMOVAPSrm:
+ case X86::FsMOVAPDrm:
+ case X86::MOVAPSrm:
+ case X86::MOVUPSrm:
+ case X86::MOVUPSrm_Int:
+ case X86::MOVAPDrm:
+ case X86::MOVDQArm:
+ case X86::MOVDQUrm:
+ case X86::MOVDQUrm_Int:
+ break;
+ }
+ switch (Opc2) {
+ default: return false;
+ case X86::MOV8rm:
+ case X86::MOV16rm:
+ case X86::MOV32rm:
+ case X86::MOV64rm:
+ case X86::LD_Fp32m:
+ case X86::LD_Fp64m:
+ case X86::LD_Fp80m:
+ case X86::MOVSSrm:
+ case X86::MOVSDrm:
+ case X86::MMX_MOVD64rm:
+ case X86::MMX_MOVQ64rm:
+ case X86::FsMOVAPSrm:
+ case X86::FsMOVAPDrm:
+ case X86::MOVAPSrm:
+ case X86::MOVUPSrm:
+ case X86::MOVUPSrm_Int:
+ case X86::MOVAPDrm:
+ case X86::MOVDQArm:
+ case X86::MOVDQUrm:
+ case X86::MOVDQUrm_Int:
+ break;
+ }
+
+ // Check if chain operands and base addresses match.
+ if (Load1->getOperand(0) != Load2->getOperand(0) ||
+ Load1->getOperand(5) != Load2->getOperand(5))
+ return false;
+ // Segment operands should match as well.
+ if (Load1->getOperand(4) != Load2->getOperand(4))
+ return false;
+ // Scale should be 1, Index should be Reg0.
+ if (Load1->getOperand(1) == Load2->getOperand(1) &&
+ Load1->getOperand(2) == Load2->getOperand(2)) {
+ if (cast<ConstantSDNode>(Load1->getOperand(1))->getZExtValue() != 1)
+ return false;
+ SDValue Op2 = Load1->getOperand(2);
+ if (!isa<RegisterSDNode>(Op2) ||
+ cast<RegisterSDNode>(Op2)->getReg() != 0)
+ return 0;
+
+ // Now let's examine the displacements.
+ if (isa<ConstantSDNode>(Load1->getOperand(3)) &&
+ isa<ConstantSDNode>(Load2->getOperand(3))) {
+ Offset1 = cast<ConstantSDNode>(Load1->getOperand(3))->getSExtValue();
+ Offset2 = cast<ConstantSDNode>(Load2->getOperand(3))->getSExtValue();
+ return true;
+ }
+ }
+ return false;
+}
+
+bool X86InstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
+ int64_t Offset1, int64_t Offset2,
+ unsigned NumLoads) const {
+ assert(Offset2 > Offset1);
+ if ((Offset2 - Offset1) / 8 > 64)
+ return false;
+
+ unsigned Opc1 = Load1->getMachineOpcode();
+ unsigned Opc2 = Load2->getMachineOpcode();
+ if (Opc1 != Opc2)
+ return false; // FIXME: overly conservative?
+
+ switch (Opc1) {
+ default: break;
+ case X86::LD_Fp32m:
+ case X86::LD_Fp64m:
+ case X86::LD_Fp80m:
+ case X86::MMX_MOVD64rm:
+ case X86::MMX_MOVQ64rm:
+ return false;
+ }
+
+ EVT VT = Load1->getValueType(0);
+ switch (VT.getSimpleVT().SimpleTy) {
+ default: {
+ // XMM registers. In 64-bit mode we can be a bit more aggressive since we
+ // have 16 of them to play with.
+ if (TM.getSubtargetImpl()->is64Bit()) {
+ if (NumLoads >= 3)
+ return false;
+ } else if (NumLoads)
+ return false;
+ break;
+ }
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
+ case MVT::i64:
+ case MVT::f32:
+ case MVT::f64:
+ if (NumLoads)
+ return false;
+ }
+
+ return true;
+}
+
+
bool X86InstrInfo::
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
assert(Cond.size() == 1 && "Invalid X86 branch condition!");
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
index 0ab85f4..4f35d0d 100644
--- a/lib/Target/X86/X86InstrInfo.h
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -610,6 +610,26 @@ public:
bool UnfoldLoad, bool UnfoldStore,
unsigned *LoadRegIndex = 0) const;
+ /// areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler
+ /// to determine if two loads are loading from the same base address. It
+ /// should only return true if the base pointers are the same and the
+ /// only differences between the two addresses are the offset. It also returns
+ /// the offsets by reference.
+ virtual bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
+ int64_t &Offset1, int64_t &Offset2) const;
+
+ /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to
+ /// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should
+ /// be scheduled togther. On some targets if two loads are loading from
+ /// addresses in the same cache line, it's better if they are scheduled
+ /// together. This function takes two integers that represent the load offsets
+ /// from the common base address. It returns true if it decides it's desirable
+ /// to schedule the two loads together. "NumLoads" is the number of loads that
+ /// have already been scheduled after Load1.
+ virtual bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
+ int64_t Offset1, int64_t Offset2,
+ unsigned NumLoads) const;
+
virtual
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
diff --git a/lib/Target/X86/X86MCAsmInfo.cpp b/lib/Target/X86/X86MCAsmInfo.cpp
index 9d7e66d..1738d49 100644
--- a/lib/Target/X86/X86MCAsmInfo.cpp
+++ b/lib/Target/X86/X86MCAsmInfo.cpp
@@ -14,6 +14,7 @@
#include "X86MCAsmInfo.h"
#include "X86TargetMachine.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;
@@ -87,10 +88,11 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &Triple) {
// Exceptions handling
ExceptionsType = ExceptionHandling::Dwarf;
AbsoluteEHSectionOffsets = false;
+}
- // On Linux we must declare when we can use a non-executable stack.
- if (Triple.getOS() == Triple::Linux)
- NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits";
+MCSection *X86ELFMCAsmInfo::getNonexecutableStackSection(MCContext &Ctx) const {
+ return MCSectionELF::Create(".note.GNU-stack", MCSectionELF::SHT_PROGBITS,
+ 0, SectionKind::getMetadata(), false, Ctx);
}
X86MCAsmInfoCOFF::X86MCAsmInfoCOFF(const Triple &Triple) {
@@ -109,7 +111,6 @@ X86WinMCAsmInfo::X86WinMCAsmInfo(const Triple &Triple) {
PrivateGlobalPrefix = "$";
AlignDirective = "\tALIGN\t";
ZeroDirective = "\tdb\t";
- ZeroDirectiveSuffix = " dup(0)";
AsciiDirective = "\tdb\t";
AscizDirective = 0;
Data8bitsDirective = "\tdb\t";
diff --git a/lib/Target/X86/X86MCAsmInfo.h b/lib/Target/X86/X86MCAsmInfo.h
index 18e2bdb..ca227b7 100644
--- a/lib/Target/X86/X86MCAsmInfo.h
+++ b/lib/Target/X86/X86MCAsmInfo.h
@@ -27,6 +27,7 @@ namespace llvm {
struct X86ELFMCAsmInfo : public MCAsmInfo {
explicit X86ELFMCAsmInfo(const Triple &Triple);
+ virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const;
};
struct X86MCAsmInfoCOFF : public MCAsmInfoCOFF {
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 9bd96af..f959a2d 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -438,6 +438,12 @@ bool X86RegisterInfo::hasFP(const MachineFunction &MF) const {
(MMI && MMI->callsUnwindInit()));
}
+bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+ return (RealignStack &&
+ !MFI->hasVarSizedObjects());
+}
+
bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
bool requiresRealignment =
@@ -591,15 +597,6 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int FrameIndex = MI.getOperand(i).getIndex();
unsigned BasePtr;
- // DEBUG_VALUE has a special representation, and is only robust enough to
- // represent SP(or BP) +- offset addressing modes. We rewrite the
- // FrameIndex to be a constant; implicitly positive constants are relative
- // to ESP and negative ones to EBP.
- if (MI.getOpcode()==TargetInstrInfo::DEBUG_VALUE) {
- MI.getOperand(i).ChangeToImmediate(getFrameIndexOffset(MF, FrameIndex));
- return 0;
- }
-
if (needsStackRealignment(MF))
BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr);
else
@@ -685,8 +682,7 @@ void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
(Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) :
(Is64Bit ? X86::ADD64ri32 : X86::ADD32ri));
uint64_t Chunk = (1LL << 31) - 1;
- DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
- DebugLoc::getUnknownLoc());
+ DebugLoc DL = MBB.findDebugLoc(MBBI);
while (Offset) {
uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
@@ -1035,8 +1031,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
}
}
- if (MBBI != MBB.end())
- DL = MBBI->getDebugLoc();
+ DL = MBB.findDebugLoc(MBBI);
// Adjust stack pointer: ESP -= numbytes.
if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) {
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index f281a3c..dec3fba 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -128,6 +128,8 @@ public:
bool hasFP(const MachineFunction &MF) const;
+ bool canRealignStack(const MachineFunction &MF) const;
+
bool needsStackRealignment(const MachineFunction &MF) const;
bool hasReservedCallFrame(MachineFunction &MF) const;
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index 962f0f7..731c3ab 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -157,9 +157,6 @@ bool X86TargetMachine::addInstSelector(PassManagerBase &PM,
bool X86TargetMachine::addPreRegAlloc(PassManagerBase &PM,
CodeGenOpt::Level OptLevel) {
- // Calculate and set max stack object alignment early, so we can decide
- // whether we will need stack realignment (and thus FP).
- PM.add(createMaxStackAlignmentCalculatorPass());
return false; // -print-machineinstr shouldn't print after this.
}
@@ -249,3 +246,32 @@ void X86TargetMachine::setCodeModelForJIT() {
else
setCodeModel(CodeModel::Small);
}
+
+/// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are 4-byte,
+/// 8-byte, and target default. The CIE is hard-coded to indicate that the LSDA
+/// pointer in the FDE section is an "sdata4", and should be encoded as a 4-byte
+/// pointer by default. However, some systems may require a different size due
+/// to bugs or other conditions. We will default to a 4-byte encoding unless the
+/// system tells us otherwise.
+///
+/// The issue is when the CIE says their is an LSDA. That mandates that every
+/// FDE have an LSDA slot. But if the function does not need an LSDA. There
+/// needs to be some way to signify there is none. The LSDA is encoded as
+/// pc-rel. But you don't look for some magic value after adding the pc. You
+/// have to look for a zero before adding the pc. The problem is that the size
+/// of the zero to look for depends on the encoding. The unwinder bug in SL is
+/// that it always checks for a pointer-size zero. So on x86_64 it looks for 8
+/// bytes of zero. If you have an LSDA, it works fine since the 8-bytes are
+/// non-zero so it goes ahead and then reads the value based on the encoding.
+/// But if you use sdata4 and there is no LSDA, then the test for zero gives a
+/// false negative and the unwinder thinks there is an LSDA.
+///
+/// FIXME: This call-back isn't good! We should be using the correct encoding
+/// regardless of the system. However, there are some systems which have bugs
+/// that prevent this from occuring.
+DwarfLSDAEncoding::Encoding X86TargetMachine::getLSDAEncoding() const {
+ if (Subtarget.isTargetDarwin() && Subtarget.getDarwinVers() != 10)
+ return DwarfLSDAEncoding::Default;
+
+ return DwarfLSDAEncoding::EightByte;
+}
diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h
index 6183e91..d05bebd 100644
--- a/lib/Target/X86/X86TargetMachine.h
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -62,6 +62,18 @@ public:
return Subtarget.isTargetELF() ? &ELFWriterInfo : 0;
}
+ /// getLSDAEncoding - Returns the LSDA pointer encoding. The choices are
+ /// 4-byte, 8-byte, and target default. The CIE is hard-coded to indicate that
+ /// the LSDA pointer in the FDE section is an "sdata4", and should be encoded
+ /// as a 4-byte pointer by default. However, some systems may require a
+ /// different size due to bugs or other conditions. We will default to a
+ /// 4-byte encoding unless the system tells us otherwise.
+ ///
+ /// FIXME: This call-back isn't good! We should be using the correct encoding
+ /// regardless of the system. However, there are some systems which have bugs
+ /// that prevent this from occuring.
+ virtual DwarfLSDAEncoding::Encoding getLSDAEncoding() const;
+
// Set up the pass pipeline.
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
virtual bool addPreRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp
index d39b3c4..41ad153 100644
--- a/lib/Target/X86/X86TargetObjectFile.cpp
+++ b/lib/Target/X86/X86TargetObjectFile.cpp
@@ -8,11 +8,11 @@
//===----------------------------------------------------------------------===//
#include "X86TargetObjectFile.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/Mangler.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/ADT/SmallString.h"
using namespace llvm;
const MCExpr *X8632_MachoTargetObjectFile::
@@ -27,6 +27,7 @@ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
MachineModuleInfoMachO &MachOMMI =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
+ // FIXME: Use GetSymbolWithGlobalValueBase.
SmallString<128> Name;
Mang->getNameWithPrefix(Name, GV, true);
Name += "$non_lazy_ptr";
diff --git a/lib/Target/XCore/AsmPrinter/Makefile b/lib/Target/XCore/AsmPrinter/Makefile
index 82dc1df..f0e883e 100644
--- a/lib/Target/XCore/AsmPrinter/Makefile
+++ b/lib/Target/XCore/AsmPrinter/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../../..
LIBRARYNAME = LLVMXCoreAsmPrinter
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' XCore target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
diff --git a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
index 2a561c6..40d7160 100644
--- a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
+++ b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp
@@ -37,7 +37,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cctype>
@@ -69,11 +68,10 @@ namespace {
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode);
- void emitGlobalDirective(const std::string &name);
- void emitExternDirective(const std::string &name);
+ void emitGlobalDirective(const MCSymbol *Sym);
- void emitArrayBound(const std::string &name, const GlobalVariable *GV);
- virtual void PrintGlobalVariable(const GlobalVariable *GV);
+ void emitArrayBound(const MCSymbol *Sym, const GlobalVariable *GV);
+ virtual void EmitGlobalVariable(const GlobalVariable *GV);
void emitFunctionStart(MachineFunction &MF);
void emitFunctionEnd(MachineFunction &MF);
@@ -95,55 +93,44 @@ namespace {
#include "XCoreGenAsmWriter.inc"
-void XCoreAsmPrinter::
-emitGlobalDirective(const std::string &name)
-{
- O << MAI->getGlobalDirective() << name;
- O << "\n";
-}
-
-void XCoreAsmPrinter::
-emitExternDirective(const std::string &name)
-{
- O << "\t.extern\t" << name;
- O << '\n';
+void XCoreAsmPrinter::emitGlobalDirective(const MCSymbol *Sym) {
+ O << MAI->getGlobalDirective() << *Sym << "\n";
}
-void XCoreAsmPrinter::
-emitArrayBound(const std::string &name, const GlobalVariable *GV)
-{
+void XCoreAsmPrinter::emitArrayBound(const MCSymbol *Sym,
+ const GlobalVariable *GV) {
assert(((GV->hasExternalLinkage() ||
GV->hasWeakLinkage()) ||
GV->hasLinkOnceLinkage()) && "Unexpected linkage");
if (const ArrayType *ATy = dyn_cast<ArrayType>(
- cast<PointerType>(GV->getType())->getElementType()))
- {
- O << MAI->getGlobalDirective() << name << ".globound" << "\n";
- O << MAI->getSetDirective() << name << ".globound" << ","
- << ATy->getNumElements() << "\n";
+ cast<PointerType>(GV->getType())->getElementType())) {
+ O << MAI->getGlobalDirective() << *Sym;
+ O << ".globound" << "\n";
+ O << MAI->getSetDirective() << *Sym;
+ O << ".globound" << "," << ATy->getNumElements() << "\n";
if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
// TODO Use COMDAT groups for LinkOnceLinkage
- O << MAI->getWeakDefDirective() << name << ".globound" << "\n";
+ O << MAI->getWeakDefDirective() << *Sym << ".globound" << "\n";
}
}
}
-void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
+void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// Check to see if this is a special global used by LLVM, if so, emit it.
if (!GV->hasInitializer() ||
EmitSpecialLLVMGlobal(GV))
return;
const TargetData *TD = TM.getTargetData();
-
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM));
+
- std::string name = Mang->getMangledName(GV);
+ MCSymbol *GVSym = GetGlobalValueSymbol(GV);
Constant *C = GV->getInitializer();
unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());
// Mark the start of the global
- O << "\t.cc_top " << name << ".data," << name << "\n";
+ O << "\t.cc_top " << *GVSym << ".data," << *GVSym << "\n";
switch (GV->getLinkage()) {
case GlobalValue::AppendingLinkage:
@@ -153,12 +140,11 @@ void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
case GlobalValue::ExternalLinkage:
- emitArrayBound(name, GV);
- emitGlobalDirective(name);
+ emitArrayBound(GVSym, GV);
+ emitGlobalDirective(GVSym);
// TODO Use COMDAT groups for LinkOnceLinkage
- if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
- O << MAI->getWeakDefDirective() << name << "\n";
- }
+ if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
+ O << MAI->getWeakDefDirective() << *GVSym << "\n";
// FALL THROUGH
case GlobalValue::InternalLinkage:
case GlobalValue::PrivateLinkage:
@@ -181,25 +167,23 @@ void XCoreAsmPrinter::PrintGlobalVariable(const GlobalVariable *GV) {
Size *= MaxThreads;
}
if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type " << name << ",@object\n";
- O << "\t.size " << name << "," << Size << "\n";
+ O << "\t.type " << *GVSym << ",@object\n";
+ O << "\t.size " << *GVSym << "," << Size << "\n";
}
- O << name << ":\n";
+ O << *GVSym << ":\n";
EmitGlobalConstant(C);
if (GV->isThreadLocal()) {
- for (unsigned i = 1; i < MaxThreads; ++i) {
+ for (unsigned i = 1; i < MaxThreads; ++i)
EmitGlobalConstant(C);
- }
- }
- if (Size < 4) {
- // The ABI requires that unsigned scalar types smaller than 32 bits
- // are are padded to 32 bits.
- EmitZeros(4 - Size);
}
+ // The ABI requires that unsigned scalar types smaller than 32 bits
+ // are padded to 32 bits.
+ if (Size < 4)
+ OutStreamer.EmitZeros(4 - Size, 0);
// Mark the end of the global
- O << "\t.cc_bottom " << name << ".data\n";
+ O << "\t.cc_bottom " << *GVSym << ".data\n";
}
/// Emit the directives on the start of functions
@@ -210,7 +194,7 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
// Mark the start of the function
- O << "\t.cc_top " << CurrentFnName << ".function," << CurrentFnName << "\n";
+ O << "\t.cc_top " << *CurrentFnSym << ".function," << *CurrentFnSym << "\n";
switch (F->getLinkage()) {
default: llvm_unreachable("Unknown linkage type!");
@@ -219,31 +203,29 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
case Function::LinkerPrivateLinkage:
break;
case Function::ExternalLinkage:
- emitGlobalDirective(CurrentFnName);
+ emitGlobalDirective(CurrentFnSym);
break;
case Function::LinkOnceAnyLinkage:
case Function::LinkOnceODRLinkage:
case Function::WeakAnyLinkage:
case Function::WeakODRLinkage:
// TODO Use COMDAT groups for LinkOnceLinkage
- O << MAI->getGlobalDirective() << CurrentFnName << "\n";
- O << MAI->getWeakDefDirective() << CurrentFnName << "\n";
+ O << MAI->getGlobalDirective() << *CurrentFnSym << "\n";
+ O << MAI->getWeakDefDirective() << *CurrentFnSym << "\n";
break;
}
// (1 << 1) byte aligned
EmitAlignment(MF.getAlignment(), F, 1);
- if (MAI->hasDotTypeDotSizeDirective()) {
- O << "\t.type " << CurrentFnName << ",@function\n";
- }
- O << CurrentFnName << ":\n";
+ if (MAI->hasDotTypeDotSizeDirective())
+ O << "\t.type " << *CurrentFnSym << ",@function\n";
+
+ O << *CurrentFnSym << ":\n";
}
/// Emit the directives on the end of functions
-void XCoreAsmPrinter::
-emitFunctionEnd(MachineFunction &MF)
-{
+void XCoreAsmPrinter::emitFunctionEnd(MachineFunction &MF) {
// Mark the end of the function
- O << "\t.cc_bottom " << CurrentFnName << ".function\n";
+ O << "\t.cc_bottom " << *CurrentFnSym << ".function\n";
}
/// runOnMachineFunction - This uses the printMachineInstruction()
@@ -318,10 +300,10 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
O << MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
- GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+ O << *GetMBBSymbol(MO.getMBB()->getNumber());
break;
case MachineOperand::MO_GlobalAddress:
- O << Mang->getMangledName(MO.getGlobal());
+ O << *GetGlobalValueSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
O << MO.getSymbolName();
@@ -333,8 +315,9 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << MO.getIndex();
+ break;
case MachineOperand::MO_BlockAddress:
- GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
+ O << *GetBlockAddressSymbol(MO.getBlockAddress());
break;
default:
llvm_unreachable("not implemented");
diff --git a/lib/Target/XCore/Makefile b/lib/Target/XCore/Makefile
index bd3b52a..3bb127f 100644
--- a/lib/Target/XCore/Makefile
+++ b/lib/Target/XCore/Makefile
@@ -6,9 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../..
LIBRARYNAME = LLVMXCoreCodeGen
TARGET = XCore
+CXXFLAGS = -fno-rtti
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = XCoreGenRegisterInfo.h.inc XCoreGenRegisterNames.inc \
diff --git a/lib/Target/XCore/TargetInfo/Makefile b/lib/Target/XCore/TargetInfo/Makefile
index 07473d2..83bba13 100644
--- a/lib/Target/XCore/TargetInfo/Makefile
+++ b/lib/Target/XCore/TargetInfo/Makefile
@@ -6,8 +6,10 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../../..
LIBRARYNAME = LLVMXCoreInfo
+CXXFLAGS = -fno-rtti
# Hack: we need to include 'main' target directory to grab private headers
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
OpenPOWER on IntegriCloud