| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,368 @@ | ||
| ; RUN: llc -emulated-tls -mtriple=arm-linux-android \ | ||
| ; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s | ||
| ; RUN: llc -emulated-tls -mtriple=aarch64-linux-android \ | ||
| ; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM64 %s | ||
|
|
||
| ; Copied from X86/emutls.ll | ||
|
|
||
| ; Use my_emutls_get_address like __emutls_get_address. | ||
| @my_emutls_v_xyz = external global i8*, align 4 | ||
| declare i8* @my_emutls_get_address(i8*) | ||
|
|
||
| define i32 @my_get_xyz() { | ||
| ; ARM32-LABEL: my_get_xyz: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl my_emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldr r0, [r0] | ||
| ; ARM64-LABEL: my_get_xyz: | ||
| ; ARM64: adrp x0, :got:my_emutls_v_xyz | ||
| ; ARM64-NEXT: ldr x0, [x0, :got_lo12:my_emutls_v_xyz] | ||
| ; ARM64-NEXT: bl my_emutls_get_address | ||
| ; ARM64-NEXT: ldr w0, [x0] | ||
| ; ARM64-NEXT: ldp x29, x30, [sp] | ||
|
|
||
| entry: | ||
| %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) | ||
| %0 = bitcast i8* %call to i32* | ||
| %1 = load i32, i32* %0, align 4 | ||
| ret i32 %1 | ||
| } | ||
|
|
||
| @i1 = thread_local global i32 15 | ||
| @i2 = external thread_local global i32 | ||
| @i3 = internal thread_local global i32 15 | ||
| @i4 = hidden thread_local global i32 15 | ||
| @i5 = external hidden thread_local global i32 | ||
| @s1 = thread_local global i16 15 | ||
| @b1 = thread_local global i8 0 | ||
|
|
||
| define i32 @f1() { | ||
| ; ARM32-LABEL: f1: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldr r0, [r0] | ||
| ; ARM64-LABEL: f1: | ||
| ; ARM64: adrp x0, :got:__emutls_v.i1 | ||
| ; ARM64-NEXT: ldr x0, [x0, :got_lo12:__emutls_v.i1] | ||
| ; ARM64-NEXT: bl __emutls_get_address | ||
| ; ARM64-NEXT: ldr w0, [x0] | ||
| ; ARM64-NEXT: ldp x29, x30, [sp] | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i1 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f2() { | ||
| ; ARM32-LABEL: f2: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: pop | ||
| ; ARM64-LABEL: f2: | ||
| ; ARM64: adrp x0, :got:__emutls_v.i1 | ||
| ; ARM64-NEXT: ldr x0, [x0, :got_lo12:__emutls_v.i1] | ||
| ; ARM64-NEXT: bl __emutls_get_address | ||
| ; ARM64-NEXT: ldp x29, x30, [sp] | ||
|
|
||
| entry: | ||
| ret i32* @i1 | ||
| } | ||
|
|
||
| define i32 @f3() nounwind { | ||
| ; ARM32-LABEL: f3: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldr r0, [r0] | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i2 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f4() { | ||
| ; ARM32-LABEL: f4: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: pop | ||
|
|
||
| entry: | ||
| ret i32* @i2 | ||
| } | ||
|
|
||
| define i32 @f5() nounwind { | ||
| ; ARM32-LABEL: f5: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldr r0, [r0] | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i3 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f6() { | ||
| ; ARM32-LABEL: f6: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: pop | ||
|
|
||
| entry: | ||
| ret i32* @i3 | ||
| } | ||
|
|
||
| define i32 @f7() { | ||
| ; ARM32-LABEL: f7: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldr r0, [r0] | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i4 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f8() { | ||
| ; ARM32-LABEL: f8: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: pop | ||
|
|
||
| entry: | ||
| ret i32* @i4 | ||
| } | ||
|
|
||
| define i32 @f9() { | ||
| ; ARM32-LABEL: f9: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldr r0, [r0] | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i5 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f10() { | ||
| ; ARM32-LABEL: f10: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: pop | ||
|
|
||
| entry: | ||
| ret i32* @i5 | ||
| } | ||
|
|
||
| define i16 @f11() { | ||
| ; ARM32-LABEL: f11: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldrh r0, [r0] | ||
|
|
||
| entry: | ||
| %tmp1 = load i16, i16* @s1 | ||
| ret i16 %tmp1 | ||
| } | ||
|
|
||
| define i32 @f12() { | ||
| ; ARM32-LABEL: f12: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldrsh r0, [r0] | ||
|
|
||
| entry: | ||
| %tmp1 = load i16, i16* @s1 | ||
| %tmp2 = sext i16 %tmp1 to i32 | ||
| ret i32 %tmp2 | ||
| } | ||
|
|
||
| define i8 @f13() { | ||
| ; ARM32-LABEL: f13: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldrb r0, [r0] | ||
| ; ARM32-NEXT: pop | ||
|
|
||
| entry: | ||
| %tmp1 = load i8, i8* @b1 | ||
| ret i8 %tmp1 | ||
| } | ||
|
|
||
| define i32 @f14() { | ||
| ; ARM32-LABEL: f14: | ||
| ; ARM32: ldr r0, | ||
| ; ARM32-NEXT: ldr r1, | ||
| ; ARM32: add r0, pc, r0 | ||
| ; ARM32-NEXT: ldr r0, [r1, r0] | ||
| ; ARM32-NEXT: bl __emutls_get_address(PLT) | ||
| ; ARM32-NEXT: ldrsb r0, [r0] | ||
| ; ARM32-NEXT: pop | ||
|
|
||
| entry: | ||
| %tmp1 = load i8, i8* @b1 | ||
| %tmp2 = sext i8 %tmp1 to i32 | ||
| ret i32 %tmp2 | ||
| } | ||
|
|
||
| ;;;;;;;;;;;;;; 32-bit __emutls_v. and __emutls_t. | ||
|
|
||
| ; ARM32 .section .data.rel.local, | ||
| ; ARM32-LABEL: __emutls_v.i1: | ||
| ; ARM32-NEXT: .long 4 | ||
| ; ARM32-NEXT: .long 4 | ||
| ; ARM32-NEXT: .long 0 | ||
| ; ARM32-NEXT: .long __emutls_t.i1 | ||
|
|
||
| ; ARM32 .section .rodata, | ||
| ; ARM32-LABEL: __emutls_t.i1: | ||
| ; ARM32-NEXT: .long 15 | ||
|
|
||
| ; ARM32-NOT: __emutls_v.i2 | ||
|
|
||
| ; ARM32 .section .data.rel.local, | ||
| ; ARM32-LABEL: __emutls_v.i3: | ||
| ; ARM32-NEXT: .long 4 | ||
| ; ARM32-NEXT: .long 4 | ||
| ; ARM32-NEXT: .long 0 | ||
| ; ARM32-NEXT: .long __emutls_t.i3 | ||
|
|
||
| ; ARM32 .section .rodata, | ||
| ; ARM32-LABEL: __emutls_t.i3: | ||
| ; ARM32-NEXT: .long 15 | ||
|
|
||
| ; ARM32 .section .data.rel.local, | ||
| ; ARM32-LABEL: __emutls_v.i4: | ||
| ; ARM32-NEXT: .long 4 | ||
| ; ARM32-NEXT: .long 4 | ||
| ; ARM32-NEXT: .long 0 | ||
| ; ARM32-NEXT: .long __emutls_t.i4 | ||
|
|
||
| ; ARM32 .section .rodata, | ||
| ; ARM32-LABEL: __emutls_t.i4: | ||
| ; ARM32-NEXT: .long 15 | ||
|
|
||
| ; ARM32-NOT: __emutls_v.i5: | ||
| ; ARM32 .hidden __emutls_v.i5 | ||
| ; ARM32-NOT: __emutls_v.i5: | ||
|
|
||
| ; ARM32 .section .data.rel.local, | ||
| ; ARM32-LABEL: __emutls_v.s1: | ||
| ; ARM32-NEXT: .long 2 | ||
| ; ARM32-NEXT: .long 2 | ||
| ; ARM32-NEXT: .long 0 | ||
| ; ARM32-NEXT: .long __emutls_t.s1 | ||
|
|
||
| ; ARM32 .section .rodata, | ||
| ; ARM32-LABEL: __emutls_t.s1: | ||
| ; ARM32-NEXT: .short 15 | ||
|
|
||
| ; ARM32 .section .data.rel.local, | ||
| ; ARM32-LABEL: __emutls_v.b1: | ||
| ; ARM32-NEXT: .long 1 | ||
| ; ARM32-NEXT: .long 1 | ||
| ; ARM32-NEXT: .long 0 | ||
| ; ARM32-NEXT: .long 0 | ||
|
|
||
| ; ARM32-NOT: __emutls_t.b1 | ||
|
|
||
| ;;;;;;;;;;;;;; 64-bit __emutls_v. and __emutls_t. | ||
|
|
||
| ; ARM64 .section .data.rel.local, | ||
| ; ARM64-LABEL: __emutls_v.i1: | ||
| ; ARM64-NEXT: .xword 4 | ||
| ; ARM64-NEXT: .xword 4 | ||
| ; ARM64-NEXT: .xword 0 | ||
| ; ARM64-NEXT: .xword __emutls_t.i1 | ||
|
|
||
| ; ARM64 .section .rodata, | ||
| ; ARM64-LABEL: __emutls_t.i1: | ||
| ; ARM64-NEXT: .word 15 | ||
|
|
||
| ; ARM64-NOT: __emutls_v.i2 | ||
|
|
||
| ; ARM64 .section .data.rel.local, | ||
| ; ARM64-LABEL: __emutls_v.i3: | ||
| ; ARM64-NEXT: .xword 4 | ||
| ; ARM64-NEXT: .xword 4 | ||
| ; ARM64-NEXT: .xword 0 | ||
| ; ARM64-NEXT: .xword __emutls_t.i3 | ||
|
|
||
| ; ARM64 .section .rodata, | ||
| ; ARM64-LABEL: __emutls_t.i3: | ||
| ; ARM64-NEXT: .word 15 | ||
|
|
||
| ; ARM64 .section .data.rel.local, | ||
| ; ARM64-LABEL: __emutls_v.i4: | ||
| ; ARM64-NEXT: .xword 4 | ||
| ; ARM64-NEXT: .xword 4 | ||
| ; ARM64-NEXT: .xword 0 | ||
| ; ARM64-NEXT: .xword __emutls_t.i4 | ||
|
|
||
| ; ARM64 .section .rodata, | ||
| ; ARM64-LABEL: __emutls_t.i4: | ||
| ; ARM64-NEXT: .word 15 | ||
|
|
||
| ; ARM64-NOT: __emutls_v.i5: | ||
| ; ARM64 .hidden __emutls_v.i5 | ||
| ; ARM64-NOT: __emutls_v.i5: | ||
|
|
||
| ; ARM64 .section .data.rel.local, | ||
| ; ARM64-LABEL: __emutls_v.s1: | ||
| ; ARM64-NEXT: .xword 2 | ||
| ; ARM64-NEXT: .xword 2 | ||
| ; ARM64-NEXT: .xword 0 | ||
| ; ARM64-NEXT: .xword __emutls_t.s1 | ||
|
|
||
| ; ARM64 .section .rodata, | ||
| ; ARM64-LABEL: __emutls_t.s1: | ||
| ; ARM64-NEXT: .hword 15 | ||
|
|
||
| ; ARM64 .section .data.rel.local, | ||
| ; ARM64-LABEL: __emutls_v.b1: | ||
| ; ARM64-NEXT: .xword 1 | ||
| ; ARM64-NEXT: .xword 1 | ||
| ; ARM64-NEXT: .xword 0 | ||
| ; ARM64-NEXT: .xword 0 | ||
|
|
||
| ; ARM64-NOT: __emutls_t.b1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| ; RUN: llc < %s -emulated-tls -march=arm -mtriple=arm-linux-androideabi \ | ||
| ; RUN: | FileCheck %s | ||
| ; RUN: llc < %s -emulated-tls -march=arm -mtriple=arm-linux-androideabi \ | ||
| ; RUN: -relocation-model=pic | FileCheck %s --check-prefix=PIC | ||
|
|
||
| ; Compared with tls1.ll, emulated mode should not use __aeabi_read_tp or __tls_get_addr. | ||
|
|
||
| ; CHECK-NOT: _aeabi_read_tp | ||
| ; CHECK-NOT: _tls_get_addr | ||
| ; CHECK: __emutls_get_addr | ||
| ; CHECK-NOT: __aeabi_read_tp | ||
| ; CHECK-NOT: _tls_get_addr | ||
|
|
||
| ; PIC-NOT: _aeabi_read_tp | ||
| ; PIC-NOT: _tls_get_addr | ||
| ; PIC: __emutls_get_addr | ||
| ; PIC-NOT: _aeabi_read_tp | ||
| ; PIC-NOT: _tls_get_addr | ||
|
|
||
| @i = thread_local global i32 15 ; <i32*> [#uses=2] | ||
|
|
||
| define i32 @f() { | ||
| entry: | ||
| %tmp1 = load i32, i32* @i ; <i32> [#uses=1] | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @g() { | ||
| entry: | ||
| ret i32* @i | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,34 @@ | ||
| ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \ | ||
| ; RUN: grep "tbss" | ||
| ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \ | ||
| ; RUN: FileCheck %s -check-prefix=CHECK -check-prefix=NOEMU | ||
| ; RUN: llc < %s -emulated-tls -march=arm -mtriple=arm-linux-gnueabi | \ | ||
| ; RUN: FileCheck %s -check-prefix=CHECK -check-prefix=EMU | ||
|
|
||
| %struct.anon = type { i32, i32 } | ||
| @teste = internal thread_local global %struct.anon zeroinitializer ; <%struct.anon*> [#uses=1] | ||
|
|
||
| define i32 @main() { | ||
| entry: | ||
| %tmp2 = load i32, i32* getelementptr (%struct.anon, %struct.anon* @teste, i32 0, i32 0), align 8 ; <i32> [#uses=1] | ||
| ret i32 %tmp2 | ||
| } | ||
|
|
||
| ; CHECK-LABEL: main: | ||
| ; NOEMU-NOT: __emutls_get_address | ||
|
|
||
| ; NOEMU: .section .tbss | ||
| ; NOEMU-LABEL: teste: | ||
| ; NOEMU-NEXT: .zero 8 | ||
|
|
||
| ; CHECK-NOT: __emutls_t.teste | ||
|
|
||
| ; EMU: .align 2 | ||
| ; EMU-LABEL: __emutls_v.teste: | ||
| ; EMU-NEXT: .long 8 | ||
| ; EMU-NEXT: .long 4 | ||
| ; EMU-NEXT: .long 0 | ||
| ; EMU-NEXT: .long 0 | ||
|
|
||
| ; CHECK-NOT: teste: | ||
| ; CHECK-NOT: __emutls_t.teste |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,298 @@ | ||
| ; RUN: llc < %s -emulated-tls -mtriple=arm-linux-android -relocation-model=pic \ | ||
| ; RUN: | FileCheck -check-prefix=ARM_32 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=arm-linux-androidabi -relocation-model=pic \ | ||
| ; RUN: | FileCheck -check-prefix=ARM_32 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-android -relocation-model=pic \ | ||
| ; RUN: | FileCheck -check-prefix=ARM_64 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=arm-linux-androidabi -relocation-model=pic -O3 \ | ||
| ; RUN: | FileCheck -check-prefix=ARM_32 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-android -relocation-model=pic -O3 \ | ||
| ; RUN: | FileCheck -check-prefix=ARM_64 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=arm-linux-androidabi -O3 \ | ||
| ; RUN: | FileCheck -check-prefix=ARM_32 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=aarch64-linux-android -O3 \ | ||
| ; RUN: | FileCheck -check-prefix=ARM_64 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=i686-linux-android -relocation-model=pic \ | ||
| ; RUN: | FileCheck -check-prefix=X86_32 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -march=x86 -relocation-model=pic \ | ||
| ; RUN: | FileCheck -check-prefix=X86_32 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -relocation-model=pic \ | ||
| ; RUN: | FileCheck -check-prefix=X86_64 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=mipsel-linux-android -relocation-model=pic \ | ||
| ; RUN: | FileCheck -check-prefix=MIPS_32 %s | ||
| ; RUN: llc < %s -emulated-tls -mtriple=mips64el-linux-android -relocation-model=pic \ | ||
| ; RUN: | FileCheck -check-prefix=MIPS_64 %s | ||
| ; RUN: llc < %s -emulated-tls -march=ppc64 -relocation-model=pic \ | ||
| ; RUN: | FileCheck %s | ||
| ; RUN: llc < %s -emulated-tls -march=ppc32 -relocation-model=pic \ | ||
| ; RUN: | FileCheck %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-gnu -relocation-model=pic \ | ||
| ; RUN: | FileCheck %s | ||
|
|
||
| ; Make sure that TLS symbols are emitted in expected order. | ||
|
|
||
| @external_x = external thread_local global i32, align 8 | ||
| @external_y = thread_local global i8 7, align 2 | ||
| @internal_y = internal thread_local global i64 9, align 16 | ||
|
|
||
| define i32* @get_external_x() { | ||
| entry: | ||
| ret i32* @external_x | ||
| } | ||
|
|
||
| define i8* @get_external_y() { | ||
| entry: | ||
| ret i8* @external_y | ||
| } | ||
|
|
||
| define i64* @get_internal_y() { | ||
| entry: | ||
| ret i64* @internal_y | ||
| } | ||
|
|
||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; targets independent mode | ||
| ; CHECK-LABEL: get_external_x: | ||
| ; CHECK-NOT: _tls_get_address | ||
| ; CHECK: __emutls_get_address | ||
| ; CHECK-LABEL: get_external_y: | ||
| ; CHECK: __emutls_get_address | ||
| ; CHECK-NOT: _tls_get_address | ||
| ; CHECK-LABEL: get_internal_y: | ||
|
|
||
| ; CHECK-NOT: __emutls_t.external_x: | ||
| ; CHECK-NOT: __emutls_v.external_x: | ||
|
|
||
| ; CHECK-LABEL: __emutls_v.external_y: | ||
| ; CHECK-LABEL: __emutls_t.external_y: | ||
| ; CHECK: __emutls_t.external_y | ||
|
|
||
| ; CHECK-LABEL: __emutls_v.internal_y: | ||
| ; CHECK-LABEL: __emutls_t.internal_y: | ||
| ; CHECK: __emutls_t.internal_y | ||
|
|
||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 32-bit mode | ||
| ; ARM_32-LABEL: get_external_x: | ||
| ; X86_32-LABEL: get_external_x: | ||
| ; MIPS-LABEL: get_external_x: | ||
|
|
||
| ; ARM_32: bl __emutls_get_address | ||
| ; ARM_32: .long __emutls_v.external_x | ||
|
|
||
| ; X86_32: movl __emutls_v.external_x | ||
| ; X86_32: calll __emutls_get_address | ||
|
|
||
| ; ARM_32-LABEL: get_external_y: | ||
| ; X86_32-LABEL: get_external_y: | ||
| ; MIPS_32-LABEL: get_external_y: | ||
|
|
||
| ; ARM_32: bl __emutls_get_address | ||
| ; ARM_32: .long __emutls_v.external_y | ||
|
|
||
| ; X86_32: movl __emutls_v.external_y | ||
| ; X86_32: calll __emutls_get_address | ||
|
|
||
| ; ARM_32-LABEL: get_internal_y: | ||
| ; X86_32-LABEL: get_internal_y: | ||
| ; MIPS_32-LABEL: get_internal_y: | ||
|
|
||
| ; ARM_32: bl __emutls_get_address | ||
| ; ARM_32: .long __emutls_v.internal_y | ||
|
|
||
| ; X86_32: movl __emutls_v.internal_y | ||
| ; X86_32: calll __emutls_get_address | ||
|
|
||
| ; MIPS_32: lw {{.+}}(__emutls_v.internal_y | ||
| ; MIPS_32: lw {{.+}}call16(__emutls_get_address | ||
|
|
||
| ; ARM_32-NOT: __emutls_t.external_x | ||
| ; X86_32-NOT: __emutls_t.external_x | ||
| ; MIPS_32-NOT: __emutls_t.external_x | ||
|
|
||
| ; ARM_32-NOT: __emutls_v.external_x: | ||
| ; X86_32-NOT: __emutls_v.external_x: | ||
| ; MIPS_32-NOT: __emutls_v.external_x: | ||
|
|
||
| ; ARM_32: .section .data.rel.local | ||
| ; X86_32: .section .data.rel.local | ||
| ; MIPS_32: .section .data.rel.local | ||
|
|
||
| ; ARM_32: .align 2 | ||
| ; X86_32: .align 4 | ||
| ; MIPS_32: .align 2 | ||
|
|
||
| ; ARM_32-LABEL: __emutls_v.external_y: | ||
| ; X86_32-LABEL: __emutls_v.external_y: | ||
| ; MIPS_32-LABEL: __emutls_v.external_y: | ||
|
|
||
| ; ARM_32-NEXT: .long 1 | ||
| ; ARM_32-NEXT: .long 2 | ||
| ; ARM_32-NEXT: .long 0 | ||
| ; ARM_32-NEXT: .long __emutls_t.external_y | ||
|
|
||
| ; X86_32-NEXT: .long 1 | ||
| ; X86_32-NEXT: .long 2 | ||
| ; X86_32-NEXT: .long 0 | ||
| ; X86_32-NEXT: .long __emutls_t.external_y | ||
|
|
||
| ; ARM_32: .section .rodata, | ||
| ; X86_32: .section .rodata, | ||
| ; MIPS_32: .section .rodata, | ||
|
|
||
| ; ARM_32-LABEL: __emutls_t.external_y: | ||
| ; X86_32-LABEL: __emutls_t.external_y: | ||
| ; MIPS_32-LABEL: __emutls_t.external_y: | ||
|
|
||
| ; ARM_32-NEXT: .byte 7 | ||
| ; X86_32-NEXT: .byte 7 | ||
| ; MIPS_32-NEXT: .byte 7 | ||
|
|
||
| ; ARM_32: .section .data.rel.local | ||
| ; X86_32: .section .data.rel.local | ||
| ; MIPS_32: .section .data.rel.local | ||
|
|
||
| ; ARM_32: .align 2 | ||
| ; X86_32: .align 4 | ||
| ; MIPS_32: .align 2 | ||
|
|
||
| ; ARM_32-LABEL: __emutls_v.internal_y: | ||
| ; X86_32-LABEL: __emutls_v.internal_y: | ||
| ; MIPS_32-LABEL: __emutls_v.internal_y: | ||
|
|
||
| ; ARM_32-NEXT: .long 8 | ||
| ; ARM_32-NEXT: .long 16 | ||
| ; ARM_32-NEXT: .long 0 | ||
| ; ARM_32-NEXT: .long __emutls_t.internal_y | ||
|
|
||
| ; X86_32-NEXT: .long 8 | ||
| ; X86_32-NEXT: .long 16 | ||
| ; X86_32-NEXT: .long 0 | ||
| ; X86_32-NEXT: .long __emutls_t.internal_y | ||
|
|
||
| ; MIPS_32-NEXT: .4byte 8 | ||
| ; MIPS_32-NEXT: .4byte 16 | ||
| ; MIPS_32-NEXT: .4byte 0 | ||
| ; MIPS_32-NEXT: .4byte __emutls_t.internal_y | ||
|
|
||
| ; ARM_32-LABEL: __emutls_t.internal_y: | ||
| ; X86_32-LABEL: __emutls_t.internal_y: | ||
| ; MIPS_32-LABEL: __emutls_t.internal_y: | ||
|
|
||
| ; ARM_32-NEXT: .long 9 | ||
| ; ARM_32-NEXT: .long 0 | ||
| ; X86_32-NEXT: .quad 9 | ||
| ; MIPS_32-NEXT: .8byte 9 | ||
|
|
||
|
|
||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64-bit mode | ||
| ; X86_64-LABEL: get_external_x: | ||
| ; ARM_64-LABEL: get_external_x: | ||
| ; MIPS_64-LABEL: get_external_x: | ||
|
|
||
| ; X86_64: __emutls_v.external_x | ||
| ; X86_64: __emutls_get_address | ||
|
|
||
| ; ARM_64: __emutls_v.external_x | ||
| ; ARM_64: __emutls_get_address | ||
|
|
||
| ; X86_64-LABEL: get_external_y: | ||
| ; ARM_64-LABEL: get_external_y: | ||
| ; MIPS_64-LABEL: get_external_y: | ||
|
|
||
| ; X86_64: __emutls_v.external_y | ||
| ; X86_64: __emutls_get_address | ||
|
|
||
| ; ARM_64: __emutls_v.external_y | ||
| ; ARM_64: __emutls_get_address | ||
|
|
||
| ; X86_64-LABEL: get_internal_y: | ||
| ; ARM_64-LABEL: get_internal_y: | ||
| ; MIPS_64-LABEL: get_internal_y: | ||
|
|
||
| ; X86_64: __emutls_v.internal_y | ||
| ; X86_64: __emutls_get_address | ||
|
|
||
| ; ARM_64: __emutls_v.internal_y | ||
| ; ARM_64: __emutls_get_address | ||
|
|
||
| ; MIPS_64: ld {{.+}}(__emutls_v.internal_y | ||
| ; MIPS_64: ld {{.+}}call16(__emutls_get_address | ||
|
|
||
| ; ARM_64-NOT: __emutls_t.external_x | ||
| ; X86_64-NOT: __emutls_t.external_x | ||
| ; MIPS_64-NOT: __emutls_t.external_x | ||
|
|
||
| ; X86_64-NOT: __emutls_v.external_x: | ||
| ; ARM_64-NOT: __emutls_v.external_x: | ||
| ; MIPS_64-NOT: __emutls_v.external_x: | ||
|
|
||
| ; X86_64: .align 8 | ||
| ; ARM_64: .align 3 | ||
|
|
||
| ; X86_64-LABEL: __emutls_v.external_y: | ||
| ; ARM_64-LABEL: __emutls_v.external_y: | ||
| ; MIPS_64-LABEL: __emutls_v.external_y: | ||
|
|
||
| ; X86_64-NEXT: .quad 1 | ||
| ; X86_64-NEXT: .quad 2 | ||
| ; X86_64-NEXT: .quad 0 | ||
| ; X86_64-NEXT: .quad __emutls_t.external_y | ||
|
|
||
| ; ARM_64-NEXT: .xword 1 | ||
| ; ARM_64-NEXT: .xword 2 | ||
| ; ARM_64-NEXT: .xword 0 | ||
| ; ARM_64-NEXT: .xword __emutls_t.external_y | ||
|
|
||
| ; X86_64-NOT: __emutls_v.external_x: | ||
| ; ARM_64-NOT: __emutls_v.external_x: | ||
| ; MIPS_64-NOT: __emutls_v.external_x: | ||
|
|
||
| ; ARM_64: .section .rodata, | ||
| ; X86_64: .section .rodata, | ||
| ; MIPS_64: .section .rodata, | ||
|
|
||
| ; X86_64-LABEL: __emutls_t.external_y: | ||
| ; ARM_64-LABEL: __emutls_t.external_y: | ||
| ; MIPS_64-LABEL: __emutls_t.external_y: | ||
|
|
||
| ; X86_64-NEXT: .byte 7 | ||
| ; ARM_64-NEXT: .byte 7 | ||
| ; MIPS_64-NEXT: .byte 7 | ||
|
|
||
| ; ARM_64: .section .data.rel.local | ||
| ; X86_64: .section .data.rel.local | ||
| ; MIPS_64: .section .data.rel.local | ||
|
|
||
| ; X86_64: .align 8 | ||
| ; ARM_64: .align 3 | ||
| ; MIPS_64: .align 3 | ||
|
|
||
| ; X86_64-LABEL: __emutls_v.internal_y: | ||
| ; ARM_64-LABEL: __emutls_v.internal_y: | ||
| ; MIPS_64-LABEL: __emutls_v.internal_y: | ||
|
|
||
| ; X86_64-NEXT: .quad 8 | ||
| ; X86_64-NEXT: .quad 16 | ||
| ; X86_64-NEXT: .quad 0 | ||
| ; X86_64-NEXT: .quad __emutls_t.internal_y | ||
|
|
||
| ; ARM_64-NEXT: .xword 8 | ||
| ; ARM_64-NEXT: .xword 16 | ||
| ; ARM_64-NEXT: .xword 0 | ||
| ; ARM_64-NEXT: .xword __emutls_t.internal_y | ||
|
|
||
| ; MIPS_64-NEXT: .8byte 8 | ||
| ; MIPS_64-NEXT: .8byte 16 | ||
| ; MIPS_64-NEXT: .8byte 0 | ||
| ; MIPS_64-NEXT: .8byte __emutls_t.internal_y | ||
|
|
||
| ; ARM_64: .section .rodata, | ||
| ; X86_64: .section .rodata, | ||
| ; MIPS_64: .section .rodata, | ||
|
|
||
| ; X86_64-LABEL: __emutls_t.internal_y: | ||
| ; ARM_64-LABEL: __emutls_t.internal_y: | ||
| ; MIPS_64-LABEL: __emutls_t.internal_y: | ||
|
|
||
| ; X86_64-NEXT: .quad 9 | ||
| ; ARM_64-NEXT: .xword 9 | ||
| ; MIPS_64-NEXT: .8byte 9 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X32 %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X64 %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X32 %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s | ||
|
|
||
| ; Use my_emutls_get_address like __emutls_get_address. | ||
| @my_emutls_v_xyz = external global i8*, align 4 | ||
| declare i8* @my_emutls_get_address(i8*) | ||
|
|
||
| define i32 @my_get_xyz() { | ||
| ; X32-LABEL: my_get_xyz: | ||
| ; X32: movl my_emutls_v_xyz@GOT(%ebx), %eax | ||
| ; X32-NEXT: movl %eax, (%esp) | ||
| ; X32-NEXT: calll my_emutls_get_address@PLT | ||
| ; X64-LABEL: my_get_xyz: | ||
| ; X64: movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi | ||
| ; X64-NEXT: callq my_emutls_get_address@PLT | ||
| ; X64-NEXT: movl (%rax), %eax | ||
|
|
||
| entry: | ||
| %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) | ||
| %0 = bitcast i8* %call to i32* | ||
| %1 = load i32, i32* %0, align 4 | ||
| ret i32 %1 | ||
| } | ||
|
|
||
| @i = thread_local global i32 15 | ||
| @j = internal thread_local global i32 42 | ||
| @k = internal thread_local global i32 0, align 8 | ||
|
|
||
| define i32 @f1() { | ||
| entry: | ||
| %tmp1 = load i32, i32* @i | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| ; X32-LABEL: f1: | ||
| ; X32: movl __emutls_v.i@GOT(%ebx), %eax | ||
| ; X32-NEXT: movl %eax, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address@PLT | ||
| ; X64-LABEL: f1: | ||
| ; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi | ||
| ; X64-NEXT: callq __emutls_get_address@PLT | ||
| ; X64-NEXT: movl (%rax), %eax | ||
|
|
||
| @i2 = external thread_local global i32 | ||
|
|
||
| define i32* @f2() { | ||
| entry: | ||
| ret i32* @i | ||
| } | ||
|
|
||
| ; X32-LABEL: f2: | ||
| ; X64-LABEL: f2: | ||
|
|
||
|
|
||
| define i32 @f3() { | ||
| entry: | ||
| %tmp1 = load i32, i32* @i ; <i32> [#uses=1] | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| ; X32-LABEL: f3: | ||
| ; X64-LABEL: f3: | ||
|
|
||
|
|
||
| define i32* @f4() nounwind { | ||
| entry: | ||
| ret i32* @i | ||
| } | ||
|
|
||
| ; X32-LABEL: f4: | ||
| ; X64-LABEL: f4: | ||
|
|
||
|
|
||
| define i32 @f5() nounwind { | ||
| entry: | ||
| %0 = load i32, i32* @j, align 4 | ||
| %1 = load i32, i32* @k, align 4 | ||
| %add = add nsw i32 %0, %1 | ||
| ret i32 %add | ||
| } | ||
|
|
||
| ; X32-LABEL: f5: | ||
| ; X32: movl __emutls_v.j@GOT(%ebx), %eax | ||
| ; X32-NEXT: movl %eax, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address@PLT | ||
| ; X32-NEXT: movl (%eax), %esi | ||
| ; X32-NEXT: movl __emutls_v.k@GOT(%ebx), %eax | ||
| ; X32-NEXT: movl %eax, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address@PLT | ||
| ; X32-NEXT: addl (%eax), %esi | ||
| ; X32-NEXT: movl %esi, %eax | ||
|
|
||
| ; X64-LABEL: f5: | ||
| ; X64: movq __emutls_v.j@GOTPCREL(%rip), %rdi | ||
| ; X64-NEXT: callq __emutls_get_address@PLT | ||
| ; X64-NEXT: movl (%rax), %ebx | ||
| ; X64-NEXT: movq __emutls_v.k@GOTPCREL(%rip), %rdi | ||
| ; X64-NEXT: callq __emutls_get_address@PLT | ||
| ; X64-NEXT: addl (%rax), %ebx | ||
| ; X64-NEXT: movl %ebx, %eax | ||
|
|
||
| ;;;;; 32-bit targets | ||
|
|
||
| ; X32: .section .data.rel.local, | ||
| ; X32-LABEL: __emutls_v.i: | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 0 | ||
| ; X32-NEXT: .long __emutls_t.i | ||
|
|
||
| ; X32: .section .rodata, | ||
| ; X32-LABEL: __emutls_t.i: | ||
| ; X32-NEXT: .long 15 | ||
|
|
||
| ; X32: .section .data.rel.local, | ||
| ; X32-LABEL: __emutls_v.j: | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 0 | ||
| ; X32-NEXT: .long __emutls_t.j | ||
|
|
||
| ; X32: .section .rodata, | ||
| ; X32-LABEL: __emutls_t.j: | ||
| ; X32-NEXT: .long 42 | ||
|
|
||
| ; X32: .data | ||
| ; X32-LABEL: __emutls_v.k: | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 8 | ||
| ; X32-NEXT: .long 0 | ||
| ; X32-NEXT: .long 0 | ||
|
|
||
| ; X32-NOT: __emutls_t.k: | ||
|
|
||
| ;;;;; 64-bit targets | ||
|
|
||
| ; X64: .section .data.rel.local, | ||
| ; X64-LABEL: __emutls_v.i: | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad __emutls_t.i | ||
|
|
||
| ; X64: .section .rodata, | ||
| ; X64-LABEL: __emutls_t.i: | ||
| ; X64-NEXT: .long 15 | ||
|
|
||
| ; X64: .section .data.rel.local, | ||
| ; X64-LABEL: __emutls_v.j: | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad __emutls_t.j | ||
|
|
||
| ; X64: .section .rodata, | ||
| ; X64-LABEL: __emutls_t.j: | ||
| ; X64-NEXT: .long 42 | ||
|
|
||
| ; X64: .data | ||
| ; X64-LABEL: __emutls_v.k: | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 8 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad 0 | ||
|
|
||
| ; X64-NOT: __emutls_t.k: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic -enable-pie \ | ||
| ; RUN: | FileCheck -check-prefix=X32 %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86-64 -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic -enable-pie \ | ||
| ; RUN: | FileCheck -check-prefix=X64 %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -mcpu=generic -mtriple=i386-linux-android -relocation-model=pic -enable-pie \ | ||
| ; RUN: | FileCheck -check-prefix=X32 %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86-64 -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic -enable-pie \ | ||
| ; RUN: | FileCheck -check-prefix=X64 %s | ||
|
|
||
| ; Use my_emutls_get_address like __emutls_get_address. | ||
| @my_emutls_v_xyz = external global i8*, align 4 | ||
| declare i8* @my_emutls_get_address(i8*) | ||
|
|
||
| define i32 @my_get_xyz() { | ||
| ; X32-LABEL: my_get_xyz: | ||
| ; X32: movl my_emutls_v_xyz@GOT(%ebx), %eax | ||
| ; X32-NEXT: movl %eax, (%esp) | ||
| ; X32-NEXT: calll my_emutls_get_address@PLT | ||
| ; X32-NEXT: movl (%eax), %eax | ||
| ; X32-NEXT: addl $8, %esp | ||
| ; X32-NEXT: popl %ebx | ||
| ; X32-NEXT: retl | ||
| ; X64-LABEL: my_get_xyz: | ||
| ; X64: movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi | ||
| ; X64-NEXT: callq my_emutls_get_address@PLT | ||
| ; X64-NEXT: movl (%rax), %eax | ||
| ; X64-NEXT: popq %rdx | ||
| ; X64-NEXT: retq | ||
|
|
||
| entry: | ||
| %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) | ||
| %0 = bitcast i8* %call to i32* | ||
| %1 = load i32, i32* %0, align 4 | ||
| ret i32 %1 | ||
| } | ||
|
|
||
| @i = thread_local global i32 15 | ||
| @i2 = external thread_local global i32 | ||
|
|
||
| define i32 @f1() { | ||
| ; X32-LABEL: f1: | ||
| ; X32: movl __emutls_v.i@GOT(%ebx), %eax | ||
| ; X32-NEXT: movl %eax, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address@PLT | ||
| ; X32-NEXT: movl (%eax), %eax | ||
| ; X32-NEXT: addl $8, %esp | ||
| ; X32-NEXT: popl %ebx | ||
| ; X32-NEXT: retl | ||
| ; X64-LABEL: f1: | ||
| ; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi | ||
| ; X64-NEXT: callq __emutls_get_address@PLT | ||
| ; X64-NEXT: movl (%rax), %eax | ||
| ; X64-NEXT: popq %rdx | ||
| ; X64-NEXT: retq | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f2() { | ||
| ; X32-LABEL: f2: | ||
| ; X32: movl __emutls_v.i@GOT(%ebx), %eax | ||
| ; X32-NEXT: movl %eax, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address@PLT | ||
| ; X64-LABEL: f2: | ||
| ; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi | ||
| ; X64-NEXT: callq __emutls_get_address@PLT | ||
|
|
||
| entry: | ||
| ret i32* @i | ||
| } | ||
|
|
||
| define i32 @f3() { | ||
| ; X32-LABEL: f3: | ||
| ; X32: movl __emutls_v.i2@GOT(%ebx), %eax | ||
| ; X32-NEXT: movl %eax, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address@PLT | ||
| ; X64-LABEL: f3: | ||
| ; X64: movq __emutls_v.i2@GOTPCREL(%rip), %rdi | ||
| ; X64-NEXT: callq __emutls_get_address@PLT | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i2 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f4() { | ||
| ; X32-LABEL: f4: | ||
| ; X32: movl __emutls_v.i2@GOT(%ebx), %eax | ||
| ; X32-NEXT: movl %eax, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address@PLT | ||
| ; X64-LABEL: f4: | ||
| ; X64: movq __emutls_v.i2@GOTPCREL(%rip), %rdi | ||
| ; X64-NEXT: callq __emutls_get_address@PLT | ||
|
|
||
| entry: | ||
| ret i32* @i2 | ||
| } | ||
|
|
||
| ;;;;; 32-bit targets | ||
|
|
||
| ; X32: .section .data.rel.local, | ||
| ; X32-LABEL: __emutls_v.i: | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 0 | ||
| ; X32-NEXT: .long __emutls_t.i | ||
|
|
||
| ; X32: .section .rodata, | ||
| ; X32-LABEL: __emutls_t.i: | ||
| ; X32-NEXT: .long 15 | ||
|
|
||
| ; X32-NOT: __emutls_v.i2 | ||
| ; X32-NOT: __emutls_t.i2 | ||
|
|
||
| ;;;;; 64-bit targets | ||
|
|
||
| ; X64: .section .data.rel.local, | ||
| ; X64-LABEL: __emutls_v.i: | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad __emutls_t.i | ||
|
|
||
| ; X64: .section .rodata, | ||
| ; X64-LABEL: __emutls_t.i: | ||
| ; X64-NEXT: .long 15 | ||
|
|
||
| ; X64-NOT: __emutls_v.i2 | ||
| ; X64-NOT: __emutls_t.i2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,347 @@ | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-gnu | FileCheck -check-prefix=X32 %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=X64 %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=x86-linux-android | FileCheck -check-prefix=X32 %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android | FileCheck -check-prefix=X64 %s | ||
|
|
||
| ; Copied from tls.ll; emulated TLS model is not implemented | ||
| ; for *-pc-win32 and *-pc-winows targets yet. | ||
|
|
||
| ; Use my_emutls_get_address like __emutls_get_address. | ||
| @my_emutls_v_xyz = external global i8*, align 4 | ||
| declare i8* @my_emutls_get_address(i8*) | ||
|
|
||
| define i32 @my_get_xyz() { | ||
| ; X32-LABEL: my_get_xyz: | ||
| ; X32: movl $my_emutls_v_xyz, (%esp) | ||
| ; X32-NEXT: calll my_emutls_get_address | ||
| ; X32-NEXT: movl (%eax), %eax | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
| ; X64-LABEL: my_get_xyz: | ||
| ; X64: movl $my_emutls_v_xyz, %edi | ||
| ; X64-NEXT: callq my_emutls_get_address | ||
| ; X64-NEXT: movl (%rax), %eax | ||
| ; X64-NEXT: popq %rdx | ||
| ; X64-NEXT: retq | ||
|
|
||
| entry: | ||
| %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) | ||
| %0 = bitcast i8* %call to i32* | ||
| %1 = load i32, i32* %0, align 4 | ||
| ret i32 %1 | ||
| } | ||
|
|
||
| @i1 = thread_local global i32 15 | ||
| @i2 = external thread_local global i32 | ||
| @i3 = internal thread_local global i32 15 | ||
| @i4 = hidden thread_local global i32 15 | ||
| @i5 = external hidden thread_local global i32 | ||
| @s1 = thread_local global i16 15 | ||
| @b1 = thread_local global i8 0 | ||
|
|
||
| define i32 @f1() { | ||
| ; X32-LABEL: f1: | ||
| ; X32: movl $__emutls_v.i1, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: movl (%eax), %eax | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
| ; X64-LABEL: f1: | ||
| ; X64: movl $__emutls_v.i1, %edi | ||
| ; X64-NEXT: callq __emutls_get_address | ||
| ; X64-NEXT: movl (%rax), %eax | ||
| ; X64-NEXT: popq %rdx | ||
| ; X64-NEXT: retq | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i1 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f2() { | ||
| ; X32-LABEL: f2: | ||
| ; X32: movl $__emutls_v.i1, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
| ; X64-LABEL: f2: | ||
| ; X64: movl $__emutls_v.i1, %edi | ||
| ; X64-NEXT: callq __emutls_get_address | ||
| ; X64-NEXT: popq %rdx | ||
| ; X64-NEXT: retq | ||
|
|
||
| entry: | ||
| ret i32* @i1 | ||
| } | ||
|
|
||
| define i32 @f3() nounwind { | ||
| ; X32-LABEL: f3: | ||
| ; X32: movl $__emutls_v.i2, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: movl (%eax), %eax | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i2 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f4() { | ||
| ; X32-LABEL: f4: | ||
| ; X32: movl $__emutls_v.i2, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| ret i32* @i2 | ||
| } | ||
|
|
||
| define i32 @f5() nounwind { | ||
| ; X32-LABEL: f5: | ||
| ; X32: movl $__emutls_v.i3, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: movl (%eax), %eax | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i3 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f6() { | ||
| ; X32-LABEL: f6: | ||
| ; X32: movl $__emutls_v.i3, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| ret i32* @i3 | ||
| } | ||
|
|
||
| define i32 @f7() { | ||
| ; X32-LABEL: f7: | ||
| ; X32: movl $__emutls_v.i4, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: movl (%eax), %eax | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i4 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f8() { | ||
| ; X32-LABEL: f8: | ||
| ; X32: movl $__emutls_v.i4, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| ret i32* @i4 | ||
| } | ||
|
|
||
| define i32 @f9() { | ||
| ; X32-LABEL: f9: | ||
| ; X32: movl $__emutls_v.i5, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: movl (%eax), %eax | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| %tmp1 = load i32, i32* @i5 | ||
| ret i32 %tmp1 | ||
| } | ||
|
|
||
| define i32* @f10() { | ||
| ; X32-LABEL: f10: | ||
| ; X32: movl $__emutls_v.i5, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| ret i32* @i5 | ||
| } | ||
|
|
||
| define i16 @f11() { | ||
| ; X32-LABEL: f11: | ||
| ; X32: movl $__emutls_v.s1, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: movzwl (%eax), %eax | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| %tmp1 = load i16, i16* @s1 | ||
| ret i16 %tmp1 | ||
| } | ||
|
|
||
| define i32 @f12() { | ||
| ; X32-LABEL: f12: | ||
| ; X32: movl $__emutls_v.s1, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: movswl (%eax), %eax | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| %tmp1 = load i16, i16* @s1 | ||
| %tmp2 = sext i16 %tmp1 to i32 | ||
| ret i32 %tmp2 | ||
| } | ||
|
|
||
| define i8 @f13() { | ||
| ; X32-LABEL: f13: | ||
| ; X32: movl $__emutls_v.b1, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: movb (%eax), %al | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| %tmp1 = load i8, i8* @b1 | ||
| ret i8 %tmp1 | ||
| } | ||
|
|
||
| define i32 @f14() { | ||
| ; X32-LABEL: f14: | ||
| ; X32: movl $__emutls_v.b1, (%esp) | ||
| ; X32-NEXT: calll __emutls_get_address | ||
| ; X32-NEXT: movsbl (%eax), %eax | ||
| ; X32-NEXT: addl $12, %esp | ||
| ; X32-NEXT: retl | ||
|
|
||
| entry: | ||
| %tmp1 = load i8, i8* @b1 | ||
| %tmp2 = sext i8 %tmp1 to i32 | ||
| ret i32 %tmp2 | ||
| } | ||
|
|
||
| ;;;;;;;;;;;;;; 32-bit __emutls_v. and __emutls_t. | ||
|
|
||
| ; X32 .section .data.rel.local, | ||
| ; X32-LABEL: __emutls_v.i1: | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 0 | ||
| ; X32-NEXT: .long __emutls_t.i1 | ||
|
|
||
| ; X32 .section .rodata, | ||
| ; X32-LABEL: __emutls_t.i1: | ||
| ; X32-NEXT: .long 15 | ||
|
|
||
| ; X32-NOT: __emutls_v.i2 | ||
|
|
||
| ; X32 .section .data.rel.local, | ||
| ; X32-LABEL: __emutls_v.i3: | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 0 | ||
| ; X32-NEXT: .long __emutls_t.i3 | ||
|
|
||
| ; X32 .section .rodata, | ||
| ; X32-LABEL: __emutls_t.i3: | ||
| ; X32-NEXT: .long 15 | ||
|
|
||
| ; X32 .section .data.rel.local, | ||
| ; X32-LABEL: __emutls_v.i4: | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 4 | ||
| ; X32-NEXT: .long 0 | ||
| ; X32-NEXT: .long __emutls_t.i4 | ||
|
|
||
| ; X32 .section .rodata, | ||
| ; X32-LABEL: __emutls_t.i4: | ||
| ; X32-NEXT: .long 15 | ||
|
|
||
| ; X32-NOT: __emutls_v.i5: | ||
| ; X32 .hidden __emutls_v.i5 | ||
| ; X32-NOT: __emutls_v.i5: | ||
|
|
||
| ; X32 .section .data.rel.local, | ||
| ; X32-LABEL: __emutls_v.s1: | ||
| ; X32-NEXT: .long 2 | ||
| ; X32-NEXT: .long 2 | ||
| ; X32-NEXT: .long 0 | ||
| ; X32-NEXT: .long __emutls_t.s1 | ||
|
|
||
| ; X32 .section .rodata, | ||
| ; X32-LABEL: __emutls_t.s1: | ||
| ; X32-NEXT: .short 15 | ||
|
|
||
| ; X32 .section .data.rel.local, | ||
| ; X32-LABEL: __emutls_v.b1: | ||
| ; X32-NEXT: .long 1 | ||
| ; X32-NEXT: .long 1 | ||
| ; X32-NEXT: .long 0 | ||
| ; X32-NEXT: .long 0 | ||
|
|
||
| ; X32-NOT: __emutls_t.b1 | ||
|
|
||
| ;;;;;;;;;;;;;; 64-bit __emutls_v. and __emutls_t. | ||
|
|
||
| ; X64 .section .data.rel.local, | ||
| ; X64-LABEL: __emutls_v.i1: | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad __emutls_t.i1 | ||
|
|
||
| ; X64 .section .rodata, | ||
| ; X64-LABEL: __emutls_t.i1: | ||
| ; X64-NEXT: .long 15 | ||
|
|
||
| ; X64-NOT: __emutls_v.i2 | ||
|
|
||
| ; X64 .section .data.rel.local, | ||
| ; X64-LABEL: __emutls_v.i3: | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad __emutls_t.i3 | ||
|
|
||
| ; X64 .section .rodata, | ||
| ; X64-LABEL: __emutls_t.i3: | ||
| ; X64-NEXT: .long 15 | ||
|
|
||
| ; X64 .section .data.rel.local, | ||
| ; X64-LABEL: __emutls_v.i4: | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad __emutls_t.i4 | ||
|
|
||
| ; X64 .section .rodata, | ||
| ; X64-LABEL: __emutls_t.i4: | ||
| ; X64-NEXT: .long 15 | ||
|
|
||
| ; X64-NOT: __emutls_v.i5: | ||
| ; X64 .hidden __emutls_v.i5 | ||
| ; X64-NOT: __emutls_v.i5: | ||
|
|
||
| ; X64 .section .data.rel.local, | ||
| ; X64-LABEL: __emutls_v.s1: | ||
| ; X64-NEXT: .quad 2 | ||
| ; X64-NEXT: .quad 2 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad __emutls_t.s1 | ||
|
|
||
| ; X64 .section .rodata, | ||
| ; X64-LABEL: __emutls_t.s1: | ||
| ; X64-NEXT: .short 15 | ||
|
|
||
| ; X64 .section .data.rel.local, | ||
| ; X64-LABEL: __emutls_v.b1: | ||
| ; X64-NEXT: .quad 1 | ||
| ; X64-NEXT: .quad 1 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad 0 | ||
|
|
||
| ; X64-NOT: __emutls_t.b1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -relocation-model=pic -mtriple=i686-unknown-linux-gnu -fast-isel | FileCheck %s | ||
| ; PR3654 | ||
|
|
||
| @v = thread_local global i32 0 | ||
| define i32 @f() nounwind { | ||
| entry: | ||
| %t = load i32, i32* @v | ||
| %s = add i32 %t, 1 | ||
| ret i32 %s | ||
| } | ||
|
|
||
| ; CHECK-LABEL: f: | ||
| ; CHECK: movl __emutls_v.v@GOT(%ebx), %eax | ||
| ; CHECK-NEXT: movl %eax, (%esp) | ||
| ; CHECK-NEXT: calll __emutls_get_address@PLT | ||
| ; CHECK-NEXT: movl (%eax), %eax | ||
|
|
||
| @alias = internal alias i32* @v | ||
| define i32 @f_alias() nounwind { | ||
| entry: | ||
| %t = load i32, i32* @v | ||
| %s = add i32 %t, 1 | ||
| ret i32 %s | ||
| } | ||
|
|
||
| ; CHECK-LABEL: f_alias: | ||
| ; CHECK: movl __emutls_v.v@GOT(%ebx), %eax | ||
| ; CHECK-NEXT: movl %eax, (%esp) | ||
| ; CHECK-NEXT: calll __emutls_get_address@PLT | ||
| ; CHECK-NEXT: movl (%eax), %eax | ||
|
|
||
| ; Use my_emutls_get_address like __emutls_get_address. | ||
| @my_emutls_v_xyz = external global i8*, align 4 | ||
| declare i8* @my_emutls_get_address(i8*) | ||
|
|
||
| define i32 @my_get_xyz() { | ||
| entry: | ||
| %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) | ||
| %0 = bitcast i8* %call to i32* | ||
| %1 = load i32, i32* %0, align 4 | ||
| ret i32 %1 | ||
| } | ||
|
|
||
| ; CHECK-LABEL: my_get_xyz: | ||
| ; CHECK: movl my_emutls_v_xyz@GOT(%ebx), %eax | ||
| ; CHECK-NEXT: movl %eax, (%esp) | ||
| ; CHECK-NEXT: calll my_emutls_get_address@PLT | ||
| ; CHECK-NEXT: movl (%eax), %eax |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck %s | ||
|
|
||
| ; Make sure that some symboles are not emitted in emulated TLS model. | ||
|
|
||
| @external_x = external thread_local global i32 | ||
| @external_y = thread_local global i32 7 | ||
| @internal_y = internal thread_local global i32 9 | ||
| @internal_y0 = internal thread_local global i32 0 | ||
|
|
||
| define i32* @get_external_x() { | ||
| entry: | ||
| ret i32* @external_x | ||
| } | ||
|
|
||
| define i32* @get_external_y() { | ||
| entry: | ||
| ret i32* @external_y | ||
| } | ||
|
|
||
| define i32* @get_internal_y() { | ||
| entry: | ||
| ret i32* @internal_y | ||
| } | ||
|
|
||
| define i32* @get_internal_y0() { | ||
| entry: | ||
| ret i32* @internal_y0 | ||
| } | ||
|
|
||
| ; no direct access to emulated TLS variables. | ||
| ; no definition of emulated TLS variables. | ||
| ; no initializer for external TLS variables, __emutls_t.external_x | ||
| ; no initializer for 0-initialized TLS variables, __emutls_t.internal_y0 | ||
| ; not global linkage for __emutls_t.external_y | ||
|
|
||
| ; CHECK-NOT: external_x@TLS | ||
| ; CHECK-NOT: external_y@TLS | ||
| ; CHECK-NOT: internal_y@TLS | ||
| ; CHECK-NOT: .size external_x | ||
| ; CHECK-NOT: .size external_y | ||
| ; CHECK-NOT: .size internal_y | ||
| ; CHECK-NOT: .size internal_y0 | ||
| ; CHECK-NOT: __emutls_v.external_x: | ||
| ; CHECK-NOT: __emutls_t.external_x: | ||
| ; CHECK-NOT: __emutls_t.internal_y0: | ||
| ; CHECK-NOT: global __emutls_t.external_y | ||
| ; CHECK-NOT: global __emutls_v.internal_y | ||
| ; CHECK-NOT: global __emutls_v.internal_y0 | ||
|
|
||
| ; CHECK: __emutls_t.external_y | ||
|
|
||
| ; CHECK-NOT: external_x@TLS | ||
| ; CHECK-NOT: external_y@TLS | ||
| ; CHECK-NOT: internal_y@TLS | ||
| ; CHECK-NOT: .size external_x | ||
| ; CHECK-NOT: .size external_y | ||
| ; CHECK-NOT: .size internal_y | ||
| ; CHECK-NOT: .size internal_y0 | ||
| ; CHECK-NOT: __emutls_v.external_x: | ||
| ; CHECK-NOT: __emutls_t.external_x: | ||
| ; CHECK-NOT: __emutls_t.internal_y0: | ||
| ; CHECK-NOT: global __emutls_t.external_y | ||
| ; CHECK-NOT: global __emutls_v.internal_y | ||
| ; CHECK-NOT: global __emutls_v.internal_y0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck %s | ||
| ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s | ||
|
|
||
| ; Make sure that TLS symboles are emitted in expected order. | ||
|
|
||
| @external_x = external thread_local global i32 | ||
| @external_y = thread_local global i32 7 | ||
| @internal_y = internal thread_local global i32 9 | ||
|
|
||
| define i32* @get_external_x() { | ||
| entry: | ||
| ret i32* @external_x | ||
| } | ||
|
|
||
| define i32* @get_external_y() { | ||
| entry: | ||
| ret i32* @external_y | ||
| } | ||
|
|
||
| define i32* @get_internal_y() { | ||
| entry: | ||
| ret i32* @internal_y | ||
| } | ||
|
|
||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 32-bit mode | ||
| ; CHECK-LABEL: get_external_x: | ||
| ; CHECK: __emutls_v.external_x | ||
| ; CHECK: __emutls_get_address | ||
|
|
||
| ; CHECK-LABEL: get_external_y: | ||
| ; CHECK: __emutls_v.external_y | ||
| ; CHECK: __emutls_get_address | ||
|
|
||
| ; CHECK-LABEL: get_internal_y: | ||
| ; CHECK: __emutls_v.internal_y | ||
| ; CHECK: __emutls_get_address | ||
|
|
||
| ; CHECK-NOT: __emutls_v.external_x: | ||
|
|
||
| ; CHECK: .align 4 | ||
| ; CHECK-LABEL: __emutls_v.external_y: | ||
| ; CHECK-NEXT: .long 4 | ||
| ; CHECK-NEXT: .long 4 | ||
| ; CHECK-NEXT: .long 0 | ||
| ; CHECK-NEXT: .long __emutls_t.external_y | ||
| ; CHECK-LABEL: __emutls_t.external_y: | ||
| ; CHECK-NEXT: .long 7 | ||
|
|
||
| ; CHECK: .align 4 | ||
| ; CHECK-LABEL: __emutls_v.internal_y: | ||
| ; CHECK-NEXT: .long 4 | ||
| ; CHECK-NEXT: .long 4 | ||
| ; CHECK-NEXT: .long 0 | ||
| ; CHECK-NEXT: .long __emutls_t.internal_y | ||
| ; CHECK-LABEL: __emutls_t.internal_y: | ||
| ; CHECK-NEXT: .long 9 | ||
|
|
||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64-bit mode | ||
| ; X64-LABEL: get_external_x: | ||
| ; X64: __emutls_v.external_x | ||
| ; X64: __emutls_get_address | ||
|
|
||
| ; X64-LABEL: get_external_y: | ||
| ; X64: __emutls_v.external_y | ||
| ; X64: __emutls_get_address | ||
|
|
||
| ; X64-LABEL: get_internal_y: | ||
| ; X64: __emutls_v.internal_y | ||
| ; X64: __emutls_get_address | ||
|
|
||
| ; X64-NOT: __emutls_v.external_x: | ||
|
|
||
| ; X64: .align 8 | ||
| ; X64-LABEL: __emutls_v.external_y: | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad __emutls_t.external_y | ||
| ; X64-LABEL: __emutls_t.external_y: | ||
| ; X64-NEXT: .long 7 | ||
|
|
||
| ; X64: .align 8 | ||
| ; X64-LABEL: __emutls_v.internal_y: | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 4 | ||
| ; X64-NEXT: .quad 0 | ||
| ; X64-NEXT: .quad __emutls_t.internal_y | ||
| ; X64-LABEL: __emutls_t.internal_y: | ||
| ; X64-NEXT: .long 9 |