summaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.h2
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp9
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.h2
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp2
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp5
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td87
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td25
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td14
-rw-r--r--lib/Target/ARM/ARMInstrVFP.td48
-rw-r--r--lib/Target/ARM/ARMMCAsmInfo.cpp1
-rw-r--r--lib/Target/ARM/ARMSubtarget.cpp40
-rw-r--r--lib/Target/ARM/ARMSubtarget.h4
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.cpp54
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.h42
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp38
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp4
-rw-r--r--lib/Target/ARM/CMakeLists.txt1
-rw-r--r--lib/Target/ARM/Thumb1RegisterInfo.cpp12
-rw-r--r--lib/Target/ARM/Thumb1RegisterInfo.h2
-rw-r--r--lib/Target/ARM/Thumb2InstrInfo.cpp28
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.
OpenPOWER on IntegriCloud