mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 22:04:55 +00:00
AArch64: support literal pool access in large memory model.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181120 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cd1b09b25b
commit
79c1c092df
@ -97,7 +97,12 @@ public:
|
||||
|
||||
bool SelectTSTBOperand(SDValue N, SDValue &FixedPos, unsigned RegWidth);
|
||||
|
||||
SDNode *SelectAtomic(SDNode *N, unsigned Op8, unsigned Op16, unsigned Op32, unsigned Op64);
|
||||
SDNode *SelectAtomic(SDNode *N, unsigned Op8, unsigned Op16, unsigned Op32,
|
||||
unsigned Op64);
|
||||
|
||||
/// Put the given constant into a pool and return a DAG which will give its
|
||||
/// address.
|
||||
SDValue getConstantPoolItemAddress(DebugLoc DL, const Constant *CV);
|
||||
|
||||
SDNode *TrySelectToMoveImm(SDNode *N);
|
||||
SDNode *LowerToFPLitPool(SDNode *Node);
|
||||
@ -235,12 +240,51 @@ SDNode *AArch64DAGToDAGISel::TrySelectToMoveImm(SDNode *Node) {
|
||||
return ResNode;
|
||||
}
|
||||
|
||||
SDValue
|
||||
AArch64DAGToDAGISel::getConstantPoolItemAddress(DebugLoc DL,
|
||||
const Constant *CV) {
|
||||
EVT PtrVT = TLI.getPointerTy();
|
||||
|
||||
switch (TLI.getTargetMachine().getCodeModel()) {
|
||||
case CodeModel::Small: {
|
||||
unsigned Alignment =
|
||||
TLI.getDataLayout()->getABITypeAlignment(CV->getType());
|
||||
return CurDAG->getNode(
|
||||
AArch64ISD::WrapperSmall, DL, PtrVT,
|
||||
CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0, AArch64II::MO_NO_FLAG),
|
||||
CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0, AArch64II::MO_LO12),
|
||||
CurDAG->getConstant(Alignment, MVT::i32));
|
||||
}
|
||||
case CodeModel::Large: {
|
||||
SDNode *LitAddr;
|
||||
LitAddr = CurDAG->getMachineNode(
|
||||
AArch64::MOVZxii, DL, PtrVT,
|
||||
CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0, AArch64II::MO_ABS_G3),
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
LitAddr = CurDAG->getMachineNode(
|
||||
AArch64::MOVKxii, DL, PtrVT, SDValue(LitAddr, 0),
|
||||
CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0, AArch64II::MO_ABS_G2_NC),
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
LitAddr = CurDAG->getMachineNode(
|
||||
AArch64::MOVKxii, DL, PtrVT, SDValue(LitAddr, 0),
|
||||
CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0, AArch64II::MO_ABS_G1_NC),
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
LitAddr = CurDAG->getMachineNode(
|
||||
AArch64::MOVKxii, DL, PtrVT, SDValue(LitAddr, 0),
|
||||
CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0, AArch64II::MO_ABS_G0_NC),
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
return SDValue(LitAddr, 0);
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("Only small and large code models supported now");
|
||||
}
|
||||
}
|
||||
|
||||
SDNode *AArch64DAGToDAGISel::SelectToLitPool(SDNode *Node) {
|
||||
DebugLoc DL = Node->getDebugLoc();
|
||||
uint64_t UnsignedVal = cast<ConstantSDNode>(Node)->getZExtValue();
|
||||
int64_t SignedVal = cast<ConstantSDNode>(Node)->getSExtValue();
|
||||
EVT DestType = Node->getValueType(0);
|
||||
EVT PtrVT = TLI.getPointerTy();
|
||||
|
||||
// Since we may end up loading a 64-bit constant from a 32-bit entry the
|
||||
// constant in the pool may have a different type to the eventual node.
|
||||
@ -267,14 +311,8 @@ SDNode *AArch64DAGToDAGISel::SelectToLitPool(SDNode *Node) {
|
||||
Constant *CV = ConstantInt::get(Type::getIntNTy(*CurDAG->getContext(),
|
||||
MemType.getSizeInBits()),
|
||||
UnsignedVal);
|
||||
SDValue PoolAddr;
|
||||
SDValue PoolAddr = getConstantPoolItemAddress(DL, CV);
|
||||
unsigned Alignment = TLI.getDataLayout()->getABITypeAlignment(CV->getType());
|
||||
PoolAddr = CurDAG->getNode(AArch64ISD::WrapperSmall, DL, PtrVT,
|
||||
CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0,
|
||||
AArch64II::MO_NO_FLAG),
|
||||
CurDAG->getTargetConstantPool(CV, PtrVT, 0, 0,
|
||||
AArch64II::MO_LO12),
|
||||
CurDAG->getConstant(Alignment, MVT::i32));
|
||||
|
||||
return CurDAG->getExtLoad(Extension, DL, DestType, CurDAG->getEntryNode(),
|
||||
PoolAddr,
|
||||
@ -287,20 +325,10 @@ SDNode *AArch64DAGToDAGISel::SelectToLitPool(SDNode *Node) {
|
||||
SDNode *AArch64DAGToDAGISel::LowerToFPLitPool(SDNode *Node) {
|
||||
DebugLoc DL = Node->getDebugLoc();
|
||||
const ConstantFP *FV = cast<ConstantFPSDNode>(Node)->getConstantFPValue();
|
||||
EVT PtrVT = TLI.getPointerTy();
|
||||
EVT DestType = Node->getValueType(0);
|
||||
|
||||
unsigned Alignment = TLI.getDataLayout()->getABITypeAlignment(FV->getType());
|
||||
SDValue PoolAddr;
|
||||
|
||||
assert(TM.getCodeModel() == CodeModel::Small &&
|
||||
"Only small code model supported");
|
||||
PoolAddr = CurDAG->getNode(AArch64ISD::WrapperSmall, DL, PtrVT,
|
||||
CurDAG->getTargetConstantPool(FV, PtrVT, 0, 0,
|
||||
AArch64II::MO_NO_FLAG),
|
||||
CurDAG->getTargetConstantPool(FV, PtrVT, 0, 0,
|
||||
AArch64II::MO_LO12),
|
||||
CurDAG->getConstant(Alignment, MVT::i32));
|
||||
SDValue PoolAddr = getConstantPoolItemAddress(DL, FV);
|
||||
|
||||
return CurDAG->getLoad(DestType, DL, CurDAG->getEntryNode(), PoolAddr,
|
||||
MachinePointerInfo::getConstantPool(),
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -code-model=large | FileCheck --check-prefix=CHECK-LARGE %s
|
||||
|
||||
@var32 = global i32 0
|
||||
@var64 = global i64 0
|
||||
@ -13,21 +14,45 @@ define void @foo() {
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI0_[0-9]+]]
|
||||
; CHECK: ldr {{w[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]]
|
||||
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g3:[[CURLIT:.LCPI0_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g0_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: ldr {{w[0-9]+}}, [x[[LITADDR]]]
|
||||
|
||||
%val64_lit32 = and i64 %val64, 305402420
|
||||
store volatile i64 %val64_lit32, i64* @var64
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI0_[0-9]+]]
|
||||
; CHECK: ldr {{w[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]]
|
||||
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g3:[[CURLIT:.LCPI0_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g0_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: ldr {{w[0-9]+}}, [x[[LITADDR]]]
|
||||
|
||||
%val64_lit32signed = and i64 %val64, -12345678
|
||||
store volatile i64 %val64_lit32signed, i64* @var64
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI0_[0-9]+]]
|
||||
; CHECK: ldrsw {{x[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]]
|
||||
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g3:[[CURLIT:.LCPI0_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g0_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: ldrsw {{x[0-9]+}}, [x[[LITADDR]]]
|
||||
|
||||
%val64_lit64 = and i64 %val64, 1234567898765432
|
||||
store volatile i64 %val64_lit64, i64* @var64
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI0_[0-9]+]]
|
||||
; CHECK: ldr {{x[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]]
|
||||
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g3:[[CURLIT:.LCPI0_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g0_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: ldr {{x[0-9]+}}, [x[[LITADDR]]]
|
||||
|
||||
ret void
|
||||
}
|
||||
|
||||
@ -42,6 +67,14 @@ define void @floating_lits() {
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI1_[0-9]+]]
|
||||
; CHECK: ldr {{s[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]]
|
||||
; CHECK: fadd
|
||||
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g3:[[CURLIT:.LCPI1_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g0_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: ldr {{s[0-9]+}}, [x[[LITADDR]]]
|
||||
; CHECK-LARGE: fadd
|
||||
|
||||
store float %newfloat, float* @varfloat
|
||||
|
||||
%doubleval = load double* @vardouble
|
||||
@ -49,6 +82,13 @@ define void @floating_lits() {
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI1_[0-9]+]]
|
||||
; CHECK: ldr {{d[0-9]+}}, [x[[LITBASE]], #:lo12:[[CURLIT]]]
|
||||
; CHECK: fadd
|
||||
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g3:[[CURLIT:.LCPI1_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g0_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: ldr {{d[0-9]+}}, [x[[LITADDR]]]
|
||||
|
||||
store double %newdouble, double* @vardouble
|
||||
|
||||
ret void
|
||||
|
Loading…
Reference in New Issue
Block a user