diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-23 11:09:33 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-23 11:09:33 +0000 |
commit | 3fd58f91dd318518f7daa4ba64c0aaf31799d89b (patch) | |
tree | 74eecbae571601ec6a626a53374b1eddc7b164a5 /lib/Target/ARM | |
parent | 3fba7d16b41dfbefe3b1be6bc0ab94c017728f79 (diff) | |
download | FreeBSD-src-3fd58f91dd318518f7daa4ba64c0aaf31799d89b.zip FreeBSD-src-3fd58f91dd318518f7daa4ba64c0aaf31799d89b.tar.gz |
Update LLVM to r94309.
Diffstat (limited to 'lib/Target/ARM')
25 files changed, 256 insertions, 351 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 }, |