diff options
Diffstat (limited to 'lib/Target')
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)/.. |