9 changes: 9 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "AArch64.h"
#include "AArch64RegisterInfo.h"
#include "MCTargetDesc/AArch64FixupKinds.h"
#include "MCTargetDesc/AArch64MCExpr.h"
#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/MC/MCAsmBackend.h"
Expand Down Expand Up @@ -376,6 +377,14 @@ bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
// to the linker -- a relocation!
if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_pcrel_adrp_imm21)
return true;

AArch64MCExpr::VariantKind RefKind =
static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
// LDR GOT relocations need a relocation
if ((uint32_t)Fixup.getKind() == AArch64::fixup_aarch64_ldr_pcrel_imm19 &&
SymLoc == AArch64MCExpr::VK_GOT)
return true;
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
} else
return ELF::R_AARCH64_PREL64;
case AArch64::fixup_aarch64_pcrel_adr_imm21:
assert(SymLoc == AArch64MCExpr::VK_NONE && "unexpected ADR relocation");
if (SymLoc != AArch64MCExpr::VK_ABS)
Ctx.reportError(Fixup.getLoc(),
"invalid symbol kind for ADR relocation");
return R_CLS(ADR_PREL_LO21);
case AArch64::fixup_aarch64_pcrel_adrp_imm21:
if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ StringRef AArch64MCExpr::getVariantKindName() const {
case VK_TLSDESC_LO12: return ":tlsdesc_lo12:";
case VK_ABS_PAGE: return "";
case VK_ABS_PAGE_NC: return ":pg_hi21_nc:";
case VK_GOT: return ":got:";
case VK_GOT_PAGE: return ":got:";
case VK_GOT_LO12: return ":got_lo12:";
case VK_GOTTPREL: return ":gottprel:";
case VK_GOTTPREL_PAGE: return ":gottprel:";
case VK_GOTTPREL_LO12_NC: return ":gottprel_lo12:";
case VK_GOTTPREL_G1: return ":gottprel_g1:";
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/ARM/ARMFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
.setMIFlags(MachineInstr::FrameSetup);

switch (TM.getCodeModel()) {
case CodeModel::Tiny:
llvm_unreachable("Tiny code model not available on ARM.");
case CodeModel::Small:
case CodeModel::Medium:
case CodeModel::Kernel:
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9207,6 +9207,8 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
// IP.

switch (TM.getCodeModel()) {
case CodeModel::Tiny:
llvm_unreachable("Tiny code model not available on ARM.");
case CodeModel::Small:
case CodeModel::Medium:
case CodeModel::Kernel:
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/X86/X86Subtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ X86Subtarget::classifyLocalReference(const GlobalValue *GV) const {
if (isTargetELF()) {
switch (TM.getCodeModel()) {
// 64-bit small code model is simple: All rip-relative.
case CodeModel::Tiny:
llvm_unreachable("Tiny codesize model not supported on X86");
case CodeModel::Small:
case CodeModel::Kernel:
return X86II::MO_NO_FLAG;
Expand Down
56 changes: 56 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-tiny.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple=aarch64-none-eabi -code-model=tiny -run-pass=instruction-select -verify-machineinstrs -O0 %s -o - | FileCheck %s
--- |
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"

@foo1 = common global [1073741824 x i32] zeroinitializer, align 4
@foo2 = common global [1073741824 x i32] zeroinitializer, align 4

define i32 @gv_tiny() {
entry:
%retval = alloca i32, align 4
store i32 0, i32* %retval, align 4
%0 = load i32, i32* getelementptr inbounds ([1073741824 x i32], [1073741824 x i32]* @foo1, i64 0, i64 0), align 4
%1 = load i32, i32* getelementptr inbounds ([1073741824 x i32], [1073741824 x i32]* @foo2, i64 0, i64 0), align 4
%add = add nsw i32 %0, %1
ret i32 %add
}

...
---
name: gv_tiny
legalized: true
regBankSelected: true
stack:
- { id: 0, name: retval, type: default, offset: 0, size: 4, alignment: 4,
stack-id: 0, callee-saved-register: '', callee-saved-restored: true,
debug-info-variable: '', debug-info-expression: '',
debug-info-location: '' }
constants:
body: |
bb.1:
; CHECK-LABEL: name: gv_tiny
; CHECK: [[ADR:%[0-9]+]]:gpr64 = ADR @foo1
; CHECK: [[COPY:%[0-9]+]]:gpr64sp = COPY [[ADR]]
; CHECK: [[ADR1:%[0-9]+]]:gpr64 = ADR @foo2
; CHECK: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[ADR1]]
; CHECK: STRWui $wzr, %stack.0.retval, 0 :: (store 4 into %ir.retval)
; CHECK: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load 4 from `i32* getelementptr inbounds ([1073741824 x i32], [1073741824 x i32]* @foo1, i64 0, i64 0)`)
; CHECK: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load 4 from `i32* getelementptr inbounds ([1073741824 x i32], [1073741824 x i32]* @foo2, i64 0, i64 0)`)
; CHECK: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRWui]], [[LDRWui1]]
; CHECK: $w0 = COPY [[ADDWrr]]
; CHECK: RET_ReallyLR implicit $w0
%1:gpr(s32) = G_CONSTANT i32 0
%4:gpr(p0) = G_GLOBAL_VALUE @foo1
%3:gpr(p0) = COPY %4(p0)
%7:gpr(p0) = G_GLOBAL_VALUE @foo2
%6:gpr(p0) = COPY %7(p0)
%0:gpr(p0) = G_FRAME_INDEX %stack.0.retval
G_STORE %1(s32), %0(p0) :: (store 4 into %ir.retval)
%2:gpr(s32) = G_LOAD %3(p0) :: (load 4 from `i32* getelementptr inbounds ([1073741824 x i32], [1073741824 x i32]* @foo1, i64 0, i64 0)`)
%5:gpr(s32) = G_LOAD %6(p0) :: (load 4 from `i32* getelementptr inbounds ([1073741824 x i32], [1073741824 x i32]* @foo2, i64 0, i64 0)`)
%8:gpr(s32) = G_ADD %2, %5
$w0 = COPY %8(s32)
RET_ReallyLR implicit $w0
...
6 changes: 6 additions & 0 deletions llvm/test/CodeGen/AArch64/arm64-tls-dynamics.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s
; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-NOLD %s
; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-NOLD-RELOC %s
; FIXME: We currently produce "small" code for the tiny model
; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -code-model=tiny -verify-machineinstrs < %s | FileCheck %s
; FIXME: We currently error for the large code model
; RUN: not llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -code-model=large -verify-machineinstrs < %s 2>&1 | FileCheck %s --check-prefix=CHECK-LARGE

; CHECK-LARGE: ELF TLS only supported in small memory model

@general_dynamic_var = external thread_local global i32

Expand Down
34 changes: 34 additions & 0 deletions llvm/test/CodeGen/AArch64/arm64-tls-execs.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
; RUN: llc -mtriple=arm64-none-linux-gnu -verify-machineinstrs -show-mc-encoding < %s | FileCheck %s
; RUN: llc -mtriple=arm64-none-linux-gnu -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s
; RUN: llc -mtriple=arm64-none-linux-gnu -verify-machineinstrs -show-mc-encoding -code-model=tiny < %s | FileCheck %s --check-prefix=CHECK-TINY
; RUN: llc -mtriple=arm64-none-linux-gnu -filetype=obj < %s -code-model=tiny | llvm-objdump -r - | FileCheck --check-prefix=CHECK-TINY-RELOC %s
; FIXME: We currently error for the large code model
; RUN: not llc -mtriple=arm64-none-linux-gnu -verify-machineinstrs -show-mc-encoding -code-model=large < %s 2>&1 | FileCheck %s --check-prefix=CHECK-LARGE

; CHECK-LARGE: ELF TLS only supported in small memory model

@initial_exec_var = external thread_local(initialexec) global i32

Expand All @@ -15,6 +21,12 @@ define i32 @test_initial_exec() {
; CHECK-RELOC: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
; CHECK-RELOC: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC

; CHECK-TINY: ldr x[[TP_OFFSET:[0-9]+]], :gottprel:initial_exec_var
; CHECK-TINY: mrs x[[TP:[0-9]+]], TPIDR_EL0
; CHECK-TINY: ldr w0, [x[[TP]], x[[TP_OFFSET]]]

; CHECK-TINY-RELOC: R_AARCH64_TLSIE_LD_GOTTPREL_PREL19

ret i32 %val
}

Expand All @@ -30,6 +42,12 @@ define i32* @test_initial_exec_addr() {
; CHECK-RELOC: R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21
; CHECK-RELOC: R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC

; CHECK-TINY: ldr x[[TP_OFFSET:[0-9]+]], :gottprel:initial_exec_var
; CHECK-TINY: mrs [[TP:x[0-9]+]], TPIDR_EL0
; CHECK-TINY: add x0, [[TP]], x[[TP_OFFSET]]

; CHECK-TINY-RELOC: R_AARCH64_TLSIE_LD_GOTTPREL_PREL19

}

@local_exec_var = thread_local(localexec) global i32 0
Expand All @@ -45,6 +63,14 @@ define i32 @test_local_exec() {

; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12
; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC

; CHECK-TINY: mrs x[[R1:[0-9]+]], TPIDR_EL0
; CHECK-TINY: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:local_exec_var
; CHECK-TINY: add x[[R3:[0-9]+]], x[[R2]], :tprel_lo12_nc:local_exec_var
; CHECK-TINY: ldr w0, [x[[R3]]]

; CHECK-TINY-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12
; CHECK-TINY-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
ret i32 %val
}

Expand All @@ -59,4 +85,12 @@ define i32* @test_local_exec_addr() {

; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12
; CHECK-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC

; CHECK-TINY: mrs x[[R1:[0-9]+]], TPIDR_EL0
; CHECK-TINY: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:local_exec_var
; CHECK-TINY: add x0, x[[R2]], :tprel_lo12_nc:local_exec_var
; CHECK-TINY: ret

; CHECK-TINY-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12
; CHECK-TINY-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
}
6 changes: 6 additions & 0 deletions llvm/test/CodeGen/AArch64/blockaddress.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
; RUN: llc -mtriple=aarch64-none-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 -verify-machineinstrs < %s | FileCheck %s
; RUN: llc -code-model=large -mtriple=aarch64-none-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-LARGE %s
; RUN: llc -code-model=tiny -mtriple=aarch64-none-none-eabi -aarch64-enable-atomic-cfg-tidy=0 -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-TINY %s

@addr = global i8* null

Expand All @@ -22,6 +23,11 @@ define void @test_blockaddress() {
; CHECK-LARGE: ldr [[NEWDEST:x[0-9]+]]
; CHECK-LARGE: br [[NEWDEST]]

; CHECK-TINY: adr [[DEST:x[0-9]+]], {{.Ltmp[0-9]+}}
; CHECK-TINY: str [[DEST]],
; CHECK-TINY: ldr [[NEWDEST:x[0-9]+]]
; CHECK-TINY: br [[NEWDEST]]

block:
ret void
}
54 changes: 54 additions & 0 deletions llvm/test/CodeGen/AArch64/code-model-tiny-abs.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
; RUN: llc -mtriple=aarch64-none-eabi -code-model=tiny < %s | FileCheck %s

@var8 = global i8 0
@var16 = global i16 0
@var32 = global i32 0
@var64 = global i64 0

define i8* @global_addr() {
; CHECK-LABEL: global_addr:
ret i8* @var8
; The adr calculation should end up returned directly in x0.
; CHECK: adr x0, var8
; CHECK-NEXT: ret
}

define i8 @global_i8() {
; CHECK-LABEL: global_i8:
%val = load i8, i8* @var8
ret i8 %val
; CHECK: adr x[[ADDR_REG:[0-9]+]], var8
; CHECK: ldrb w0, [x[[ADDR_REG]]]
}

define i16 @global_i16() {
; CHECK-LABEL: global_i16:
%val = load i16, i16* @var16
ret i16 %val
; CHECK: adr x[[ADDR_REG:[0-9]+]], var16
; CHECK: ldrh w0, [x[[ADDR_REG]]]
}

define i32 @global_i32() {
; CHECK-LABEL: global_i32:
%val = load i32, i32* @var32
ret i32 %val
; CHECK: adr x[[ADDR_REG:[0-9]+]], var32
; CHECK: ldr w0, [x[[ADDR_REG]]]
}

define i64 @global_i64() {
; CHECK-LABEL: global_i64:
%val = load i64, i64* @var64
ret i64 %val
; CHECK: adr x[[ADDR_REG:[0-9]+]], var64
; CHECK: ldr x0, [x[[ADDR_REG]]]
}

define <2 x i64> @constpool() {
; CHECK-LABEL: constpool:
ret <2 x i64> <i64 123456789, i64 987654321100>

; CHECK: adr x[[ADDR_REG:[0-9]+]], {{.LCPI[0-9]+_[0-9]+}}
; CHECK: ldr q0, [x[[ADDR_REG]]]
}
9 changes: 9 additions & 0 deletions llvm/test/CodeGen/AArch64/extern-weak.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -o - %s | FileCheck %s
; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=static -o - < %s | FileCheck %s
; RUN: llc -mtriple=aarch64-none-linux-gnu -code-model=large -o - %s | FileCheck --check-prefix=CHECK-LARGE %s
; RUN: llc -mtriple=aarch64-none-none-eabi -code-model=tiny -o - %s | FileCheck --check-prefix=CHECK-TINY %s

declare extern_weak i32 @var()

Expand All @@ -20,6 +21,9 @@ define i32()* @foo() {
; CHECK-LARGE: movk x0, #:abs_g1_nc:var
; CHECK-LARGE: movk x0, #:abs_g2_nc:var
; CHECK-LARGE: movk x0, #:abs_g3:var

; In the tiny codemodel we us a got relocated LDR.
; CHECK-TINY: ldr x0, :got:var
}


Expand All @@ -41,6 +45,9 @@ define i32* @bar() {
; CHECK-LARGE: movk [[ADDR]], #:abs_g1_nc:arr_var
; CHECK-LARGE: movk [[ADDR]], #:abs_g2_nc:arr_var
; CHECK-LARGE: movk [[ADDR]], #:abs_g3:arr_var

; CHECK-TINY: ldr [[BASE:x[0-9]+]], :got:arr_var
; CHECK-TINY: add x0, [[BASE]], #20
}

@defined_weak_var = internal unnamed_addr global i32 0
Expand All @@ -55,4 +62,6 @@ define i32* @wibble() {
; CHECK-LARGE: movk x0, #:abs_g1_nc:defined_weak_var
; CHECK-LARGE: movk x0, #:abs_g2_nc:defined_weak_var
; CHECK-LARGE: movk x0, #:abs_g3:defined_weak_var

; CHECK-TINY: adr x0, defined_weak_var
}
19 changes: 17 additions & 2 deletions llvm/test/CodeGen/AArch64/fpimm.ll
Original file line number Diff line number Diff line change
@@ -1,46 +1,58 @@
; RUN: llc -mtriple=aarch64-linux-gnu -verify-machineinstrs < %s | FileCheck %s
; RUN: llc -mtriple=aarch64-apple-darwin -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix=LARGE
; RUN: llc -mtriple=aarch64-apple-darwin -code-model=large -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s --check-prefix=LARGE
; RUN: llc -mtriple=aarch64-none-eabi -code-model=tiny -verify-machineinstrs < %s | FileCheck %s --check-prefix=TINY

@varf32 = global float 0.0
@varf64 = global double 0.0

define void @check_float() {
; CHECK-LABEL: check_float:
; TINY-LABEL: check_float:

%val = load float, float* @varf32
%newval1 = fadd float %val, 8.5
store volatile float %newval1, float* @varf32
; CHECK-DAG: fmov [[EIGHT5:s[0-9]+]], #8.5
; CHECK-DAG: fmov {{s[0-9]+}}, #8.5
; TINY-DAG: fmov {{s[0-9]+}}, #8.5

%newval2 = fadd float %val, 128.0
store volatile float %newval2, float* @varf32
; CHECK-DAG: ldr [[HARD:s[0-9]+]], [{{x[0-9]+}}, {{#?}}:lo12:.LCPI0_0
; CHECK-DAG: ldr {{s[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:.LCPI0_0
; TINY-DAG: ldr {{s[0-9]+}}, [{{x[0-9]+}}]

; CHECK: ret
; TINY: ret
ret void
}

define void @check_double() {
; CHECK-LABEL: check_double:
; TINY-LABEL: check_double:

%val = load double, double* @varf64
%newval1 = fadd double %val, 8.5
store volatile double %newval1, double* @varf64
; CHECK-DAG: fmov {{d[0-9]+}}, #8.5
; TINY-DAG: fmov {{d[0-9]+}}, #8.5

%newval2 = fadd double %val, 128.0
store volatile double %newval2, double* @varf64
; CHECK-DAG: ldr {{d[0-9]+}}, [{{x[0-9]+}}, {{#?}}:lo12:.LCPI1_0
; TINY-DAG: ldr {{d[0-9]+}}, [{{x[0-9]+}}]

; CHECK: ret
; TINY: ret
ret void
}

; LARGE-LABEL: check_float2
; LARGE: mov [[REG:w[0-9]+]], #4059
; LARGE-NEXT: movk [[REG]], #16457, lsl #16
; LARGE-NEXT: fmov s0, [[REG]]
; TINY-LABEL: check_float2
; TINY: adr x[[REG:[0-9]+]], .LCPI2_0
; TINY-NEXT: ldr s0, [x[[REG]]]
define float @check_float2() {
ret float 3.14159274101257324218750
}
Expand All @@ -51,6 +63,9 @@ define float @check_float2() {
; LARGE-NEXT: movk [[REG]], #8699, lsl #32
; LARGE-NEXT: movk [[REG]], #16393, lsl #48
; LARGE-NEXT: fmov d0, [[REG]]
; TINY-LABEL: check_double2
; TINY: adr x[[REG:[0-9]+]], .LCPI3_0
; TINY-NEXT: ldr d0, [x[[REG]]]
define double @check_double2() {
ret double 3.1415926535897931159979634685441851615905761718750
}
5 changes: 5 additions & 0 deletions llvm/test/CodeGen/AArch64/jump-table.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-none-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck %s
; RUN: llc -code-model=large -verify-machineinstrs -o - %s -mtriple=aarch64-none-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck --check-prefix=CHECK-LARGE %s
; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs -relocation-model=pic -aarch64-enable-atomic-cfg-tidy=0 -o - %s | FileCheck --check-prefix=CHECK-PIC %s
; RUN: llc -code-model=tiny -verify-machineinstrs -o - %s -mtriple=aarch64-none-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck --check-prefix=CHECK-TINY %s

define i32 @test_jumptable(i32 %in) {
; CHECK: test_jumptable
Expand Down Expand Up @@ -29,6 +30,10 @@ define i32 @test_jumptable(i32 %in) {
; CHECK-PIC: add [[TABLE:x[0-9]+]], [[DEST]], x[[JT]]
; CHECK-PIC: br [[TABLE]]

; CHECK-TINY: adr x[[JT:[0-9]+]], .LJTI0_0
; CHECK-TINY: ldr [[DEST:x[0-9]+]], [x[[JT]], {{x[0-9]+}}, lsl #3]
; CHECK-TINY: br [[DEST]]

def:
ret i32 0

Expand Down
11 changes: 11 additions & 0 deletions llvm/test/CodeGen/AArch64/literal_pools_float.ll
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-none-linux-gnu -mcpu=cyclone | FileCheck %s
; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-none-linux-gnu -code-model=large -mcpu=cyclone | FileCheck --check-prefix=CHECK-LARGE %s
; RUN: llc -verify-machineinstrs -o - %s -mtriple=aarch64-none-none-eabi -code-model=tiny -mcpu=cyclone | FileCheck --check-prefix=CHECK-TINY %s
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP %s
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu -code-model=large -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP-LARGE %s
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-none-eabi -code-model=tiny -mattr=-fp-armv8 | FileCheck --check-prefix=CHECK-NOFP-TINY %s

@varfloat = global float 0.0
@vardouble = global double 0.0
Expand All @@ -15,6 +17,10 @@ define void @floating_lits() {
; CHECK: ldr [[LIT128:s[0-9]+]], [x[[LITBASE]], {{#?}}:lo12:[[CURLIT]]]
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},

; CHECK-TINY: adr x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
; CHECK-TINY: ldr [[LIT128:s[0-9]+]], [x[[LITBASE]]]
; CHECK-NOFP-TINY-NOT: ldr {{s[0-9]+}},

; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g0_nc:[[CURLIT:.LCPI[0-9]+_[0-9]+]]
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
Expand All @@ -33,6 +39,11 @@ define void @floating_lits() {
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
; CHECK-NOFP-NOT: fadd

; CHECK-TINY: adr x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
; CHECK-TINY: ldr [[LIT129:d[0-9]+]], [x[[LITBASE]]]
; CHECK-NOFP-TINY-NOT: ldr {{d[0-9]+}},
; CHECK-NOFP-TINY-NOT: fadd

; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g0_nc:[[CURLIT:.LCPI[0-9]+_[0-9]+]]
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
Expand Down
421 changes: 421 additions & 0 deletions llvm/test/CodeGen/AArch64/tiny_model.ll

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions llvm/test/CodeGen/AArch64/tiny_supported.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -code-model=tiny < %s 2>&1 | FileCheck %s
; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-eabi -code-model=tiny < %s 2>&1 | FileCheck %s
; RUN: not llc -verify-machineinstrs -o - -mtriple=arm64-apple-darwin -code-model=tiny < %s 2>&1 | FileCheck %s --check-prefix=NOTINY
; RUN: not llc -verify-machineinstrs -o - -mtriple=arm64-apple-ios -code-model=tiny < %s 2>&1 | FileCheck %s --check-prefix=NOTINY
; RUN: not llc -verify-machineinstrs -o - -mtriple=aarch64-unknown-windows-msvc -code-model=tiny < %s 2>&1 | FileCheck %s --check-prefix=NOTINY

; CHECK-NOT: tiny code model is only supported on ELF
; CHECK-LABEL: foo
; NOTINY: tiny code model is only supported on ELF

define void @foo() {
ret void
}
8 changes: 8 additions & 0 deletions llvm/test/MC/AArch64/basic-a64-diagnostics.s
Original file line number Diff line number Diff line change
Expand Up @@ -3315,17 +3315,25 @@
//------------------------------------------------------------------------------

adr sp, loc // expects xzr
adr x0, :got:loc // bad relocation type
adrp x3, #20 // Immediate unaligned
adrp w2, loc // 64-bit register needed
adrp x5, :got_lo12:loc // bad relocation type
// CHECK-ERROR: error: invalid operand for instruction
// CHECK-ERROR-NEXT: adr sp, loc
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: unexpected adr label
// CHECK-ERROR-NEXT: adr x0, :got:loc
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: expected label or encodable integer pc offset
// CHECK-ERROR-NEXT: adrp x3, #20
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: invalid operand for instruction
// CHECK-ERROR-NEXT: adrp w2, loc
// CHECK-ERROR-NEXT: ^
// CHECK-ERROR-NEXT: error: page or gotpage label reference expected
// CHECK-ERROR-NEXT: adrp x5, :got_lo12:loc
// CHECK-ERROR-NEXT: ^

adr x9, #1048576
adr x2, #-1048577
Expand Down