diff options
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.h | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMBaseRegisterInfo.cpp | 9 | ||||
-rw-r--r-- | lib/Target/ARM/ARMBaseRegisterInfo.h | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 5 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 87 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrNEON.td | 25 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 14 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrVFP.td | 48 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMCAsmInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Target/ARM/ARMSubtarget.cpp | 40 | ||||
-rw-r--r-- | lib/Target/ARM/ARMSubtarget.h | 4 | ||||
-rw-r--r-- | lib/Target/ARM/ARMTargetObjectFile.cpp | 54 | ||||
-rw-r--r-- | lib/Target/ARM/ARMTargetObjectFile.h | 42 | ||||
-rw-r--r-- | lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 38 | ||||
-rw-r--r-- | lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp | 4 | ||||
-rw-r--r-- | lib/Target/ARM/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb1RegisterInfo.cpp | 12 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb1RegisterInfo.h | 2 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb2InstrInfo.cpp | 28 |
20 files changed, 297 insertions, 123 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h index e095acc..0194231 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/lib/Target/ARM/ARMBaseInstrInfo.h @@ -332,7 +332,7 @@ bool isJumpTableBranchOpcode(int Opc) { static inline bool isIndirectBranchOpcode(int Opc) { - return Opc == ARM::BRIND || Opc == ARM::tBRIND; + return Opc == ARM::BRIND || Opc == ARM::MOVPCRX || Opc == ARM::tBRIND; } /// getInstrPredicate - If instruction is predicated, returns its predicate diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 577c363..d9b8323 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -40,7 +40,7 @@ #include "llvm/Support/CommandLine.h" using namespace llvm; -static cl::opt<bool> +cl::opt<bool> ReuseFrameIndexVals("arm-reuse-frame-index-vals", cl::Hidden, cl::init(true), cl::desc("Reuse repeated frame index values")); @@ -1153,7 +1153,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, unsigned ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, int *Value, + int SPAdj, FrameIndexValue *Value, RegScavenger *RS) const { unsigned i = 0; MachineInstr &MI = *II; @@ -1205,7 +1205,10 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false); else { ScratchReg = MF.getRegInfo().createVirtualRegister(ARM::GPRRegisterClass); - if (Value) *Value = Offset; + if (Value) { + Value->first = FrameReg; // use the frame register as a kind indicator + Value->second = Offset; + } if (!AFI->isThumbFunction()) emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg, Offset, Pred, PredReg, TII); diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h index 64f6ff1..456c392 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -145,7 +145,7 @@ public: MachineBasicBlock::iterator I) const; virtual unsigned eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, int *Value = NULL, + int SPAdj, FrameIndexValue *Value = NULL, RegScavenger *RS = NULL) const; virtual void emitPrologue(MachineFunction &MF) const; diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index bd703f4..108a244 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -1138,7 +1138,7 @@ void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) { // Set the conditional execution predicate Binary |= II->getPredicate(&MI) << ARMII::CondShift; - if (TID.Opcode == ARM::BX_RET) + if (TID.Opcode == ARM::BX_RET || TID.Opcode == ARM::MOVPCLR) // The return register is LR. Binary |= ARMRegisterInfo::getRegisterNumbering(ARM::LR); else diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 6a2c6bb..3dd0313 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -37,9 +37,9 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/MC/MCSectionMachO.h" #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/VectorExtras.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" @@ -130,7 +130,8 @@ void ARMTargetLowering::addQRTypeForNEON(EVT VT) { static TargetLoweringObjectFile *createTLOF(TargetMachine &TM) { if (TM.getSubtarget<ARMSubtarget>().isTargetDarwin()) - return new TargetLoweringObjectFileMachO(); + return new ARMMachOTargetObjectFile(); + return new ARMElfTargetObjectFile(); } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 87c6f6e..af82a5f 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -21,7 +21,7 @@ def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>; def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>; -def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisInt<0>]>; +def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; def SDT_ARMCMov : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, @@ -113,6 +113,8 @@ def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>; //===----------------------------------------------------------------------===// // ARM Instruction Predicate Definitions. // +def HasV4T : Predicate<"Subtarget->hasV4TOps()">; +def NoV4T : Predicate<"!Subtarget->hasV4TOps()">; def HasV5T : Predicate<"Subtarget->hasV5TOps()">; def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">; def HasV6 : Predicate<"Subtarget->hasV6Ops()">; @@ -851,24 +853,50 @@ def LEApcrelJT : AXI1<0x0, (outs GPR:$dst), // Control Flow Instructions. // -let isReturn = 1, isTerminator = 1, isBarrier = 1 in +let isReturn = 1, isTerminator = 1, isBarrier = 1 in { + // ARMV4T and above def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, - "bx", "\tlr", [(ARMretflag)]> { - let Inst{3-0} = 0b1110; - let Inst{7-4} = 0b0001; - let Inst{19-8} = 0b111111111111; - let Inst{27-20} = 0b00010010; + "bx", "\tlr", [(ARMretflag)]>, + Requires<[IsARM, HasV4T]> { + let Inst{3-0} = 0b1110; + let Inst{7-4} = 0b0001; + let Inst{19-8} = 0b111111111111; + let Inst{27-20} = 0b00010010; + } + + // ARMV4 only + def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br, + "mov", "\tpc, lr", [(ARMretflag)]>, + Requires<[IsARM, NoV4T]> { + let Inst{11-0} = 0b000000001110; + let Inst{15-12} = 0b1111; + let Inst{19-16} = 0b0000; + let Inst{27-20} = 0b00011010; + } } // Indirect branches let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { + // ARMV4T and above def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst", - [(brind GPR:$dst)]> { + [(brind GPR:$dst)]>, + Requires<[IsARM, HasV4T]> { let Inst{7-4} = 0b0001; let Inst{19-8} = 0b111111111111; let Inst{27-20} = 0b00010010; let Inst{31-28} = 0b1110; } + + // ARMV4 only + def MOVPCRX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "mov\tpc, $dst", + [(brind GPR:$dst)]>, + Requires<[IsARM, NoV4T]> { + let Inst{11-4} = 0b00000000; + let Inst{15-12} = 0b1111; + let Inst{19-16} = 0b0000; + let Inst{27-20} = 0b00011010; + let Inst{31-28} = 0b1110; + } } // FIXME: remove when we have a way to marking a MI with these properties. @@ -913,11 +941,22 @@ let isCall = 1, def BX : ABXIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, "mov\tlr, pc\n\tbx\t$func", [(ARMcall_nolink tGPR:$func)]>, - Requires<[IsARM, IsNotDarwin]> { + Requires<[IsARM, HasV4T, IsNotDarwin]> { let Inst{7-4} = 0b0001; let Inst{19-8} = 0b111111111111; let Inst{27-20} = 0b00010010; } + + // ARMv4 + def BMOVPCRX : ABXIx2<(outs), (ins tGPR:$func, variable_ops), + IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func", + [(ARMcall_nolink tGPR:$func)]>, + Requires<[IsARM, NoV4T, IsNotDarwin]> { + let Inst{11-4} = 0b00000000; + let Inst{15-12} = 0b1111; + let Inst{19-16} = 0b0000; + let Inst{27-20} = 0b00011010; + } } // On Darwin R9 is call-clobbered. @@ -950,11 +989,23 @@ let isCall = 1, // Note: Restrict $func to the tGPR regclass to prevent it being in LR. def BXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, "mov\tlr, pc\n\tbx\t$func", - [(ARMcall_nolink tGPR:$func)]>, Requires<[IsARM, IsDarwin]> { + [(ARMcall_nolink tGPR:$func)]>, + Requires<[IsARM, HasV4T, IsDarwin]> { let Inst{7-4} = 0b0001; let Inst{19-8} = 0b111111111111; let Inst{27-20} = 0b00010010; } + + // ARMv4 + def BMOVPCRXr9 : ABXIx2<(outs), (ins tGPR:$func, variable_ops), + IIC_Br, "mov\tlr, pc\n\tmov\tpc, $func", + [(ARMcall_nolink tGPR:$func)]>, + Requires<[IsARM, NoV4T, IsDarwin]> { + let Inst{11-4} = 0b00000000; + let Inst{15-12} = 0b1111; + let Inst{19-16} = 0b0000; + let Inst{27-20} = 0b00011010; + } } let isBranch = 1, isTerminator = 1 in { @@ -2793,29 +2844,29 @@ def MRSsys : ABI<0b0001,(outs GPR:$dst),(ins), NoItinerary,"mrs","\t$dst, spsr", let Inst{7-4} = 0b0000; } -// FIXME: mask is ignored for the time being. -def MSR : ABI<0b0001,(outs),(ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src", +def MSR : ABI<0b0001, (outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr", + "\tcpsr${mask:msr}, $src", [/* For disassembly only; pattern left blank */]> { let Inst{23-20} = 0b0010; let Inst{7-4} = 0b0000; } -// FIXME: mask is ignored for the time being. -def MSRi : ABI<0b0011,(outs),(ins so_imm:$a), NoItinerary, "msr", "\tcpsr, $a", +def MSRi : ABI<0b0011, (outs), (ins so_imm:$a, i32imm:$mask), NoItinerary,"msr", + "\tcpsr${mask:msr}, $a", [/* For disassembly only; pattern left blank */]> { let Inst{23-20} = 0b0010; let Inst{7-4} = 0b0000; } -// FIXME: mask is ignored for the time being. -def MSRsys : ABI<0b0001,(outs),(ins GPR:$src),NoItinerary,"msr","\tspsr, $src", +def MSRsys : ABI<0b0001, (outs), (ins GPR:$src, i32imm:$mask),NoItinerary,"msr", + "\tspsr${mask:msr}, $src", [/* For disassembly only; pattern left blank */]> { let Inst{23-20} = 0b0110; let Inst{7-4} = 0b0000; } -// FIXME: mask is ignored for the time being. -def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a),NoItinerary,"msr","\tspsr, $a", +def MSRsysi : ABI<0b0011,(outs),(ins so_imm:$a, i32imm:$mask),NoItinerary,"msr", + "\tspsr${mask:msr}, $a", [/* For disassembly only; pattern left blank */]> { let Inst{23-20} = 0b0110; let Inst{7-4} = 0b0000; diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 3aa0810..7c44a2f 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -2707,21 +2707,21 @@ def VSETLNi32 : NVSetLane<{1,1,1,0,0,0,?,0}, 0b1011, 0b00, (outs DPR:$dst), } def : Pat<(vector_insert (v16i8 QPR:$src1), GPR:$src2, imm:$lane), (v16i8 (INSERT_SUBREG QPR:$src1, - (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1, + (v8i8 (VSETLNi8 (v8i8 (EXTRACT_SUBREG QPR:$src1, (DSubReg_i8_reg imm:$lane))), - GPR:$src2, (SubReg_i8_lane imm:$lane)), + GPR:$src2, (SubReg_i8_lane imm:$lane))), (DSubReg_i8_reg imm:$lane)))>; def : Pat<(vector_insert (v8i16 QPR:$src1), GPR:$src2, imm:$lane), (v8i16 (INSERT_SUBREG QPR:$src1, - (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1, + (v4i16 (VSETLNi16 (v4i16 (EXTRACT_SUBREG QPR:$src1, (DSubReg_i16_reg imm:$lane))), - GPR:$src2, (SubReg_i16_lane imm:$lane)), + GPR:$src2, (SubReg_i16_lane imm:$lane))), (DSubReg_i16_reg imm:$lane)))>; def : Pat<(insertelt (v4i32 QPR:$src1), GPR:$src2, imm:$lane), (v4i32 (INSERT_SUBREG QPR:$src1, - (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1, + (v2i32 (VSETLNi32 (v2i32 (EXTRACT_SUBREG QPR:$src1, (DSubReg_i32_reg imm:$lane))), - GPR:$src2, (SubReg_i32_lane imm:$lane)), + GPR:$src2, (SubReg_i32_lane imm:$lane))), (DSubReg_i32_reg imm:$lane)))>; def : Pat<(v2f32 (insertelt DPR:$src1, SPR:$src2, imm:$src3)), @@ -3093,16 +3093,17 @@ def VTBX4 class N2VSPat<SDNode OpNode, ValueType ResTy, ValueType OpTy, NeonI Inst> : NEONFPPat<(ResTy (OpNode SPR:$a)), - (EXTRACT_SUBREG (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)), - SPR:$a, arm_ssubreg_0)), + (EXTRACT_SUBREG (OpTy (Inst (INSERT_SUBREG (OpTy (IMPLICIT_DEF)), + SPR:$a, arm_ssubreg_0))), arm_ssubreg_0)>; class N3VSPat<SDNode OpNode, NeonI Inst> : NEONFPPat<(f32 (OpNode SPR:$a, SPR:$b)), - (EXTRACT_SUBREG (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$a, arm_ssubreg_0), - (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), - SPR:$b, arm_ssubreg_0)), + (EXTRACT_SUBREG (v2f32 + (Inst (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), + SPR:$a, arm_ssubreg_0), + (INSERT_SUBREG (v2f32 (IMPLICIT_DEF)), + SPR:$b, arm_ssubreg_0))), arm_ssubreg_0)>; class N3VSMulOpPat<SDNode MulNode, SDNode OpNode, NeonI Inst> diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 6241766..2fc7d2f 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -331,9 +331,9 @@ multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode, let Inst{15} = 0; } // 12-bit imm - def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi, - !strconcat(opc, "w"), "\t$dst, $lhs, $rhs", - [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> { + def ri12 : T2I<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi, + !strconcat(opc, "w"), "\t$dst, $lhs, $rhs", + [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]> { let Inst{31-27} = 0b11110; let Inst{25} = 1; let Inst{24} = 0; @@ -2637,9 +2637,9 @@ def t2MRSsys : T2I<(outs GPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr", let Inst{12} = 0; } -// FIXME: mask is ignored for the time being. // Rn = Inst{19-16} -def t2MSR : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src", +def t2MSR : T2I<(outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr", + "\tcpsr${mask:msr}, $src", [/* For disassembly only; pattern left blank */]> { let Inst{31-27} = 0b11110; let Inst{26} = 0; @@ -2649,9 +2649,9 @@ def t2MSR : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tcpsr, $src", let Inst{12} = 0; } -// FIXME: mask is ignored for the time being. // Rn = Inst{19-16} -def t2MSRsys : T2I<(outs), (ins GPR:$src), NoItinerary, "msr", "\tspsr, $src", +def t2MSRsys : T2I<(outs), (ins GPR:$src, i32imm:$mask), NoItinerary, "msr", + "\tspsr${mask:msr}, $src", [/* For disassembly only; pattern left blank */]> { let Inst{31-27} = 0b11110; let Inst{26} = 0; diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index 7c117ed..cad24c4 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -57,7 +57,7 @@ def vfp_f64imm : Operand<f64>, let canFoldAsLoad = 1, isReMaterializable = 1 in { def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr), IIC_fpLoad64, "vldr", ".64\t$dst, $addr", - [(set DPR:$dst, (load addrmode5:$addr))]>; + [(set DPR:$dst, (f64 (load addrmode5:$addr)))]>; def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr), IIC_fpLoad32, "vldr", ".32\t$dst, $addr", @@ -66,7 +66,7 @@ def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr), def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr), IIC_fpStore64, "vstr", ".64\t$src, $addr", - [(store DPR:$src, addrmode5:$addr)]>; + [(store (f64 DPR:$src), addrmode5:$addr)]>; def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr), IIC_fpStore32, "vstr", ".32\t$src, $addr", @@ -116,7 +116,7 @@ def VSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb, def VADDD : ADbI<0b11100, 0b11, 0, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b), IIC_fpALU64, "vadd", ".f64\t$dst, $a, $b", - [(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>; + [(set DPR:$dst, (fadd DPR:$a, (f64 DPR:$b)))]>; def VADDS : ASbIn<0b11100, 0b11, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b), IIC_fpALU32, "vadd", ".f32\t$dst, $a, $b", @@ -126,7 +126,7 @@ def VADDS : ASbIn<0b11100, 0b11, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b), let Defs = [FPSCR] in { def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0, (outs), (ins DPR:$a, DPR:$b), IIC_fpCMP64, "vcmpe", ".f64\t$a, $b", - [(arm_cmpfp DPR:$a, DPR:$b)]>; + [(arm_cmpfp DPR:$a, (f64 DPR:$b))]>; def VCMPD : ADuI<0b11101, 0b11, 0b0100, 0b01, 0, (outs), (ins DPR:$a, DPR:$b), IIC_fpCMP64, "vcmp", ".f64\t$a, $b", @@ -143,7 +143,7 @@ def VCMPS : ASuI<0b11101, 0b11, 0b0100, 0b01, 0, (outs), (ins SPR:$a, SPR:$b), def VDIVD : ADbI<0b11101, 0b00, 0, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b), IIC_fpDIV64, "vdiv", ".f64\t$dst, $a, $b", - [(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>; + [(set DPR:$dst, (fdiv DPR:$a, (f64 DPR:$b)))]>; def VDIVS : ASbI<0b11101, 0b00, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b), IIC_fpDIV32, "vdiv", ".f32\t$dst, $a, $b", @@ -151,7 +151,7 @@ def VDIVS : ASbI<0b11101, 0b00, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b), def VMULD : ADbI<0b11100, 0b10, 0, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b), IIC_fpMUL64, "vmul", ".f64\t$dst, $a, $b", - [(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>; + [(set DPR:$dst, (fmul DPR:$a, (f64 DPR:$b)))]>; def VMULS : ASbIn<0b11100, 0b10, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b), IIC_fpMUL32, "vmul", ".f32\t$dst, $a, $b", @@ -159,14 +159,14 @@ def VMULS : ASbIn<0b11100, 0b10, 0, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b), def VNMULD : ADbI<0b11100, 0b10, 1, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b), IIC_fpMUL64, "vnmul", ".f64\t$dst, $a, $b", - [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]>; + [(set DPR:$dst, (fneg (fmul DPR:$a, (f64 DPR:$b))))]>; def VNMULS : ASbI<0b11100, 0b10, 1, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b), IIC_fpMUL32, "vnmul", ".f32\t$dst, $a, $b", [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]>; // Match reassociated forms only if not sign dependent rounding. -def : Pat<(fmul (fneg DPR:$a), DPR:$b), +def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)), (VNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>; def : Pat<(fmul (fneg SPR:$a), SPR:$b), (VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>; @@ -174,7 +174,7 @@ def : Pat<(fmul (fneg SPR:$a), SPR:$b), def VSUBD : ADbI<0b11100, 0b11, 1, 0, (outs DPR:$dst), (ins DPR:$a, DPR:$b), IIC_fpALU64, "vsub", ".f64\t$dst, $a, $b", - [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]>; + [(set DPR:$dst, (fsub DPR:$a, (f64 DPR:$b)))]>; def VSUBS : ASbIn<0b11100, 0b11, 1, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b), IIC_fpALU32, "vsub", ".f32\t$dst, $a, $b", @@ -186,7 +186,7 @@ def VSUBS : ASbIn<0b11100, 0b11, 1, 0, (outs SPR:$dst), (ins SPR:$a, SPR:$b), def VABSD : ADuI<0b11101, 0b11, 0b0000, 0b11, 0, (outs DPR:$dst), (ins DPR:$a), IIC_fpUNA64, "vabs", ".f64\t$dst, $a", - [(set DPR:$dst, (fabs DPR:$a))]>; + [(set DPR:$dst, (fabs (f64 DPR:$a)))]>; def VABSS : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0,(outs SPR:$dst), (ins SPR:$a), IIC_fpUNA32, "vabs", ".f32\t$dst, $a", @@ -195,7 +195,7 @@ def VABSS : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0,(outs SPR:$dst), (ins SPR:$a), let Defs = [FPSCR] in { def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0, (outs), (ins DPR:$a), IIC_fpCMP64, "vcmpe", ".f64\t$a, #0", - [(arm_cmpfp0 DPR:$a)]>; + [(arm_cmpfp0 (f64 DPR:$a))]>; def VCMPZD : ADuI<0b11101, 0b11, 0b0101, 0b01, 0, (outs), (ins DPR:$a), IIC_fpCMP64, "vcmp", ".f64\t$a, #0", @@ -253,7 +253,7 @@ def VMOVS: ASuI<0b11101, 0b11, 0b0000, 0b01, 0, (outs SPR:$dst), (ins SPR:$a), def VNEGD : ADuI<0b11101, 0b11, 0b0001, 0b01, 0, (outs DPR:$dst), (ins DPR:$a), IIC_fpUNA64, "vneg", ".f64\t$dst, $a", - [(set DPR:$dst, (fneg DPR:$a))]>; + [(set DPR:$dst, (fneg (f64 DPR:$a)))]>; def VNEGS : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0,(outs SPR:$dst), (ins SPR:$a), IIC_fpUNA32, "vneg", ".f32\t$dst, $a", @@ -261,7 +261,7 @@ def VNEGS : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0,(outs SPR:$dst), (ins SPR:$a), def VSQRTD : ADuI<0b11101, 0b11, 0b0001, 0b11, 0, (outs DPR:$dst), (ins DPR:$a), IIC_fpSQRT64, "vsqrt", ".f64\t$dst, $a", - [(set DPR:$dst, (fsqrt DPR:$a))]>; + [(set DPR:$dst, (fsqrt (f64 DPR:$a)))]>; def VSQRTS : ASuI<0b11101, 0b11, 0b0001, 0b11, 0, (outs SPR:$dst), (ins SPR:$a), IIC_fpSQRT32, "vsqrt", ".f32\t$dst, $a", @@ -325,7 +325,7 @@ def VMOVSRR : AVConv5I<0b11000100, 0b1010, def VSITOD : AVConv1I<0b11101, 0b11, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a), IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a", - [(set DPR:$dst, (arm_sitof SPR:$a))]> { + [(set DPR:$dst, (f64 (arm_sitof SPR:$a)))]> { let Inst{7} = 1; // s32 } @@ -339,7 +339,7 @@ def VSITOS : AVConv1In<0b11101, 0b11, 0b1000, 0b1010, def VUITOD : AVConv1I<0b11101, 0b11, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a), IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a", - [(set DPR:$dst, (arm_uitof SPR:$a))]> { + [(set DPR:$dst, (f64 (arm_uitof SPR:$a)))]> { let Inst{7} = 0; // u32 } @@ -356,7 +356,7 @@ def VUITOS : AVConv1In<0b11101, 0b11, 0b1000, 0b1010, def VTOSIZD : AVConv1I<0b11101, 0b11, 0b1101, 0b1011, (outs SPR:$dst), (ins DPR:$a), IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a", - [(set SPR:$dst, (arm_ftosi DPR:$a))]> { + [(set SPR:$dst, (arm_ftosi (f64 DPR:$a)))]> { let Inst{7} = 1; // Z bit } @@ -370,7 +370,7 @@ def VTOSIZS : AVConv1In<0b11101, 0b11, 0b1101, 0b1010, def VTOUIZD : AVConv1I<0b11101, 0b11, 0b1100, 0b1011, (outs SPR:$dst), (ins DPR:$a), IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a", - [(set SPR:$dst, (arm_ftoui DPR:$a))]> { + [(set SPR:$dst, (arm_ftoui (f64 DPR:$a)))]> { let Inst{7} = 1; // Z bit } @@ -514,7 +514,8 @@ def VULTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 1, def VMLAD : ADbI<0b11100, 0b00, 0, 0, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), IIC_fpMAC64, "vmla", ".f64\t$dst, $a, $b", - [(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR:$dstin))]>, + [(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), + (f64 DPR:$dstin)))]>, RegConstraint<"$dstin = $dst">; def VMLAS : ASbIn<0b11100, 0b00, 0, 0, @@ -526,7 +527,8 @@ def VMLAS : ASbIn<0b11100, 0b00, 0, 0, def VNMLSD : ADbI<0b11100, 0b01, 0, 0, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), IIC_fpMAC64, "vnmls", ".f64\t$dst, $a, $b", - [(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR:$dstin))]>, + [(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), + (f64 DPR:$dstin)))]>, RegConstraint<"$dstin = $dst">; def VNMLSS : ASbI<0b11100, 0b01, 0, 0, @@ -538,7 +540,8 @@ def VNMLSS : ASbI<0b11100, 0b01, 0, 0, def VMLSD : ADbI<0b11100, 0b00, 1, 0, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), IIC_fpMAC64, "vmls", ".f64\t$dst, $a, $b", - [(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>, + [(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), + (f64 DPR:$dstin)))]>, RegConstraint<"$dstin = $dst">; def VMLSS : ASbIn<0b11100, 0b00, 1, 0, @@ -547,7 +550,7 @@ def VMLSS : ASbIn<0b11100, 0b00, 1, 0, [(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>, RegConstraint<"$dstin = $dst">; -def : Pat<(fsub DPR:$dstin, (fmul DPR:$a, DPR:$b)), +def : Pat<(fsub DPR:$dstin, (fmul DPR:$a, (f64 DPR:$b))), (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>; def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)), (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>; @@ -555,7 +558,8 @@ def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)), def VNMLAD : ADbI<0b11100, 0b01, 1, 0, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), IIC_fpMAC64, "vnmla", ".f64\t$dst, $a, $b", - [(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>, + [(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), + (f64 DPR:$dstin)))]>, RegConstraint<"$dstin = $dst">; def VNMLAS : ASbI<0b11100, 0b01, 1, 0, diff --git a/lib/Target/ARM/ARMMCAsmInfo.cpp b/lib/Target/ARM/ARMMCAsmInfo.cpp index ccd6add..20197e4 100644 --- a/lib/Target/ARM/ARMMCAsmInfo.cpp +++ b/lib/Target/ARM/ARMMCAsmInfo.cpp @@ -48,7 +48,6 @@ ARMMCAsmInfoDarwin::ARMMCAsmInfoDarwin() { // Exceptions handling ExceptionsType = ExceptionHandling::SjLj; - AbsoluteEHSectionOffsets = false; } ARMELFMCAsmInfo::ARMELFMCAsmInfo() { diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index 426862c..622034b 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -33,7 +33,7 @@ UseMOVT("arm-use-movt", ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS, bool isT) - : ARMArchVersion(V4T) + : ARMArchVersion(V4) , ARMFPUType(None) , UseNEONForSinglePrecisionFP(UseNEONFP) , IsThumb(isT) @@ -54,6 +54,11 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS, // Parse features string. CPUString = ParseSubtargetFeatures(FS, CPUString); + // When no arch is specified either by CPU or by attributes, make the default + // ARMv4T. + if (CPUString == "generic" && (FS.empty() || FS == "generic")) + ARMArchVersion = V4T; + // Set the boolean corresponding to the current target triple, or the default // if one cannot be determined, to true. unsigned Len = TT.length(); @@ -68,25 +73,28 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS, } if (Idx) { unsigned SubVer = TT[Idx]; - if (SubVer > '4' && SubVer <= '9') { - if (SubVer >= '7') { - ARMArchVersion = V7A; - } else if (SubVer == '6') { - ARMArchVersion = V6; - if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') - ARMArchVersion = V6T2; - } else if (SubVer == '5') { - ARMArchVersion = V5T; - if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') - ARMArchVersion = V5TE; - } - if (ARMArchVersion >= V6T2) - ThumbMode = Thumb2; + if (SubVer >= '7' && SubVer <= '9') { + ARMArchVersion = V7A; + } else if (SubVer == '6') { + ARMArchVersion = V6; + if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') + ARMArchVersion = V6T2; + } else if (SubVer == '5') { + ARMArchVersion = V5T; + if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') + ARMArchVersion = V5TE; + } else if (SubVer == '4') { + if (Len >= Idx+2 && TT[Idx+1] == 't') + ARMArchVersion = V4T; + else + ARMArchVersion = V4; } } // Thumb2 implies at least V6T2. - if (ARMArchVersion < V6T2 && ThumbMode >= Thumb2) + if (ARMArchVersion >= V6T2) + ThumbMode = Thumb2; + else if (ThumbMode >= Thumb2) ARMArchVersion = V6T2; if (Len >= 10) { diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index 3f06b7b..6980851 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -26,7 +26,7 @@ class GlobalValue; class ARMSubtarget : public TargetSubtarget { protected: enum ARMArchEnum { - V4T, V5T, V5TE, V6, V6T2, V7A + V4, V4T, V5T, V5TE, V6, V6T2, V7A }; enum ARMFPEnum { @@ -38,7 +38,7 @@ protected: Thumb2 }; - /// ARMArchVersion - ARM architecture version: V4T (base), V5T, V5TE, + /// ARMArchVersion - ARM architecture version: V4, V4T (base), V5T, V5TE, /// V6, V6T2, V7A. ARMArchEnum ARMArchVersion; diff --git a/lib/Target/ARM/ARMTargetObjectFile.cpp b/lib/Target/ARM/ARMTargetObjectFile.cpp new file mode 100644 index 0000000..7463e30 --- /dev/null +++ b/lib/Target/ARM/ARMTargetObjectFile.cpp @@ -0,0 +1,54 @@ +//===-- llvm/Target/ARMTargetObjectFile.cpp - ARM Object Info Impl --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ARMTargetObjectFile.h" +#include "ARMSubtarget.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSectionMachO.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Target/TargetMachine.h" +using namespace llvm; +using namespace dwarf; + +//===----------------------------------------------------------------------===// +// ELF Target +//===----------------------------------------------------------------------===// + +void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, + const TargetMachine &TM) { + TargetLoweringObjectFileELF::Initialize(Ctx, TM); + + if (TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI()) { + StaticCtorSection = + getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY, + MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC, + SectionKind::getDataRel()); + StaticDtorSection = + getELFSection(".fini_array", MCSectionELF::SHT_FINI_ARRAY, + MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC, + SectionKind::getDataRel()); + } +} + +//===----------------------------------------------------------------------===// +// Mach-O Target +//===----------------------------------------------------------------------===// + +void ARMMachOTargetObjectFile::Initialize(MCContext &Ctx, + const TargetMachine &TM) { + TargetLoweringObjectFileMachO::Initialize(Ctx, TM); + + // Exception Handling. + LSDASection = getMachOSection("__TEXT", "__gcc_except_tab", 0, + SectionKind::getReadOnlyWithRel()); +} + +unsigned ARMMachOTargetObjectFile::getTTypeEncoding() const { + return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4; +} diff --git a/lib/Target/ARM/ARMTargetObjectFile.h b/lib/Target/ARM/ARMTargetObjectFile.h index a488c0a..481d7ab 100644 --- a/lib/Target/ARM/ARMTargetObjectFile.h +++ b/lib/Target/ARM/ARMTargetObjectFile.h @@ -11,29 +11,31 @@ #define LLVM_TARGET_ARM_TARGETOBJECTFILE_H #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" -#include "llvm/MC/MCSectionELF.h" namespace llvm { - class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF { - public: - ARMElfTargetObjectFile() : TargetLoweringObjectFileELF() {} - - void Initialize(MCContext &Ctx, const TargetMachine &TM) { - TargetLoweringObjectFileELF::Initialize(Ctx, TM); - - if (TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI()) { - StaticCtorSection = - getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY, - MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC, - SectionKind::getDataRel()); - StaticDtorSection = - getELFSection(".fini_array", MCSectionELF::SHT_FINI_ARRAY, - MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC, - SectionKind::getDataRel()); - } - } - }; +class MCContext; +class TargetMachine; + +class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF { +public: + ARMElfTargetObjectFile() : TargetLoweringObjectFileELF() {} + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); +}; + +// FIXME: This subclass isn't 100% necessary. It will become obsolete once we +// can place all LSDAs into the TEXT section. See +// <rdar://problem/6804645>. +class ARMMachOTargetObjectFile : public TargetLoweringObjectFileMachO { +public: + ARMMachOTargetObjectFile() : TargetLoweringObjectFileMachO() {} + + virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + + virtual unsigned getTTypeEncoding() const; +}; + } // end namespace llvm #endif diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index d6d595c..314114c 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -33,6 +33,7 @@ #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" @@ -848,7 +849,7 @@ GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2, raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << getFunctionNumber() << '_' << uid << '_' << uid2 << "_set_" << MBB->getNumber(); - return OutContext.GetOrCreateSymbol(Name.str()); + return OutContext.GetOrCreateTemporarySymbol(Name.str()); } MCSymbol *ARMAsmPrinter:: @@ -856,7 +857,7 @@ GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const { SmallString<60> Name; raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << uid << '_' << uid2; - return OutContext.GetOrCreateSymbol(Name.str()); + return OutContext.GetOrCreateTemporarySymbol(Name.str()); } void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) { @@ -1128,17 +1129,40 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); EmitAlignment(2); for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { - O << *Stubs[i].first << ":\n\t.indirect_symbol "; - O << *Stubs[i].second << "\n\t.long\t0\n"; + // L_foo$stub: + OutStreamer.EmitLabel(Stubs[i].first); + // .indirect_symbol _foo + MCSymbol *MCSym = Stubs[i].second; + OutStreamer.EmitSymbolAttribute(MCSym, MCSA_IndirectSymbol); + + if (MCSym->isUndefined()) + // External to current translation unit. + OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); + else + // Internal to current translation unit. + OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym, OutContext), + 4/*size*/, 0/*addrspace*/); } + + Stubs.clear(); + OutStreamer.AddBlankLine(); } Stubs = MMIMacho.GetHiddenGVStubList(); if (!Stubs.empty()) { OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); EmitAlignment(2); - for (unsigned i = 0, e = Stubs.size(); i != e; ++i) - O << *Stubs[i].first << ":\n\t.long " << *Stubs[i].second << "\n"; + for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { + // L_foo$stub: + OutStreamer.EmitLabel(Stubs[i].first); + // .long _foo + OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second, + OutContext), + 4/*size*/, 0/*addrspace*/); + } + + Stubs.clear(); + OutStreamer.AddBlankLine(); } // Funny Darwin hack: This flag tells the linker that no global symbols @@ -1168,7 +1192,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) { // FIXME: MOVE TO SHARED PLACE. unsigned Id = (unsigned)MI->getOperand(2).getImm(); const char *Prefix = MAI->getPrivateGlobalPrefix(); - MCSymbol *Label =OutContext.GetOrCreateSymbol(Twine(Prefix) + MCSymbol *Label =OutContext.GetOrCreateTemporarySymbol(Twine(Prefix) + "PC" + Twine(getFunctionNumber()) + "_" + Twine(Id)); OutStreamer.EmitLabel(Label); diff --git a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp index 1b2dd48..5f8705e 100644 --- a/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp @@ -74,7 +74,7 @@ GetJumpTableSymbol(const MachineOperand &MO) const { #endif // Create a symbol for the name. - return Ctx.GetOrCreateSymbol(Name.str()); + return Ctx.GetOrCreateTemporarySymbol(Name.str()); } MCSymbol *ARMMCInstLower:: @@ -90,7 +90,7 @@ GetConstantPoolIndexSymbol(const MachineOperand &MO) const { #endif // Create a symbol for the name. - return Ctx.GetOrCreateSymbol(Name.str()); + return Ctx.GetOrCreateTemporarySymbol(Name.str()); } MCOperand ARMMCInstLower:: diff --git a/lib/Target/ARM/CMakeLists.txt b/lib/Target/ARM/CMakeLists.txt index 964551f..bbc0095 100644 --- a/lib/Target/ARM/CMakeLists.txt +++ b/lib/Target/ARM/CMakeLists.txt @@ -27,6 +27,7 @@ add_llvm_target(ARMCodeGen ARMRegisterInfo.cpp ARMSubtarget.cpp ARMTargetMachine.cpp + ARMTargetObjectFile.cpp NEONMoveFix.cpp NEONPreAllocPass.cpp Thumb1InstrInfo.cpp diff --git a/lib/Target/ARM/Thumb1RegisterInfo.cpp b/lib/Target/ARM/Thumb1RegisterInfo.cpp index 163d1e9..6215d2f 100644 --- a/lib/Target/ARM/Thumb1RegisterInfo.cpp +++ b/lib/Target/ARM/Thumb1RegisterInfo.cpp @@ -33,10 +33,13 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +extern cl::opt<bool> ReuseFrameIndexVals; + Thumb1RegisterInfo::Thumb1RegisterInfo(const ARMBaseInstrInfo &tii, const ARMSubtarget &sti) : ARMBaseRegisterInfo(tii, sti) { @@ -426,7 +429,7 @@ Thumb1RegisterInfo::saveScavengerRegister(MachineBasicBlock &MBB, unsigned Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, int *Value, + int SPAdj, FrameIndexValue *Value, RegScavenger *RS) const{ unsigned VReg = 0; unsigned i = 0; @@ -638,8 +641,10 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, } else if (Desc.mayStore()) { VReg = MF.getRegInfo().createVirtualRegister(ARM::tGPRRegisterClass); assert (Value && "Frame index virtual allocated, but Value arg is NULL!"); - *Value = Offset; bool UseRR = false; + bool TrackVReg = true; + Value->first = FrameReg; // use the frame register as a kind indicator + Value->second = Offset; if (Opcode == ARM::tSpill) { if (FrameReg == ARM::SP) @@ -648,6 +653,7 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, else { emitLoadConstPool(MBB, II, dl, VReg, 0, Offset); UseRR = true; + TrackVReg = false; } } else emitThumbRegPlusImmediate(MBB, II, VReg, FrameReg, Offset, TII, @@ -658,6 +664,8 @@ Thumb1RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); else // tSTR has an extra register operand. MI.addOperand(MachineOperand::CreateReg(0, false)); + if (!ReuseFrameIndexVals || !TrackVReg) + VReg = 0; } else assert(false && "Unexpected opcode!"); diff --git a/lib/Target/ARM/Thumb1RegisterInfo.h b/lib/Target/ARM/Thumb1RegisterInfo.h index 37ad388..4eca367 100644 --- a/lib/Target/ARM/Thumb1RegisterInfo.h +++ b/lib/Target/ARM/Thumb1RegisterInfo.h @@ -59,7 +59,7 @@ public: const TargetRegisterClass *RC, unsigned Reg) const; unsigned eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, int *Value = NULL, + int SPAdj, FrameIndexValue *Value = NULL, RegScavenger *RS = NULL) const; void emitPrologue(MachineFunction &MF) const; diff --git a/lib/Target/ARM/Thumb2InstrInfo.cpp b/lib/Target/ARM/Thumb2InstrInfo.cpp index 20f13f1..e4abcdb 100644 --- a/lib/Target/ARM/Thumb2InstrInfo.cpp +++ b/lib/Target/ARM/Thumb2InstrInfo.cpp @@ -164,6 +164,7 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB, continue; } + bool HasCCOut = true; if (BaseReg == ARM::SP) { // sub sp, sp, #imm7 if (DestReg == ARM::SP && (ThisVal < ((1 << 7)-1) * 4)) { @@ -195,6 +196,7 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB, NumBytes = 0; } else if (ThisVal < 4096) { Opc = isSub ? ARM::t2SUBri12 : ARM::t2ADDri12; + HasCCOut = false; NumBytes = 0; } else { // FIXME: Move this to ARMAddressingModes.h? @@ -207,9 +209,12 @@ void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB, } // Build the new ADD / SUB. - AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) - .addReg(BaseReg, RegState::Kill) - .addImm(ThisVal))); + MachineInstrBuilder MIB = + AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) + .addReg(BaseReg, RegState::Kill) + .addImm(ThisVal)); + if (HasCCOut) + AddDefaultCC(MIB); BaseReg = DestReg; } @@ -328,7 +333,6 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) { Offset += MI.getOperand(FrameRegIdx+1).getImm(); - bool isSP = FrameReg == ARM::SP; unsigned PredReg; if (Offset == 0 && getInstrPredicate(&MI, PredReg) == ARMCC::AL) { // Turn it into a move. @@ -342,6 +346,9 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, return true; } + bool isSP = FrameReg == ARM::SP; + bool HasCCOut = Opcode != ARM::t2ADDri12; + if (Offset < 0) { Offset = -Offset; isSub = true; @@ -354,17 +361,24 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, if (ARM_AM::getT2SOImmVal(Offset) != -1) { MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); + // Add cc_out operand if the original instruction did not have one. + if (!HasCCOut) + MI.addOperand(MachineOperand::CreateReg(0, false)); Offset = 0; return true; } // Another common case: imm12. - if (Offset < 4096) { + if (Offset < 4096 && + (!HasCCOut || MI.getOperand(MI.getNumOperands()-1).getReg() == 0)) { unsigned NewOpc = isSP ? (isSub ? ARM::t2SUBrSPi12 : ARM::t2ADDrSPi12) : (isSub ? ARM::t2SUBri12 : ARM::t2ADDri12); MI.setDesc(TII.get(NewOpc)); MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset); + // Remove the cc_out operand. + if (HasCCOut) + MI.RemoveOperand(MI.getNumOperands()-1); Offset = 0; return true; } @@ -380,6 +394,10 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, assert(ARM_AM::getT2SOImmVal(ThisImmVal) != -1 && "Bit extraction didn't work?"); MI.getOperand(FrameRegIdx+1).ChangeToImmediate(ThisImmVal); + // Add cc_out operand if the original instruction did not have one. + if (!HasCCOut) + MI.addOperand(MachineOperand::CreateReg(0, false)); + } else { // AddrMode4 and AddrMode6 cannot handle any offset. |