1; RUN: llc -emulated-tls -mtriple=arm-linux-android \ 2; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s 3; RUN: llc -mtriple=arm-linux-android \ 4; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s 5 6; Copied from X86/emutls.ll 7 8; Use my_emutls_get_address like __emutls_get_address. 9@my_emutls_v_xyz = external global ptr, align 4 10declare ptr @my_emutls_get_address(ptr) 11 12define i32 @my_get_xyz() { 13; ARM32-LABEL: my_get_xyz: 14; ARM32: ldr r0, 15; ARM32: ldr r0, [pc, r0] 16; ARM32-NEXT: bl my_emutls_get_address 17; ARM32-NEXT: ldr r0, [r0] 18; ARM32: .long my_emutls_v_xyz(GOT_PREL) 19 20entry: 21 %call = call ptr @my_emutls_get_address(ptr @my_emutls_v_xyz) 22 %0 = load i32, ptr %call, align 4 23 ret i32 %0 24} 25 26@i1 = thread_local global i32 15 27@i2 = external thread_local global i32 28@i3 = internal thread_local global i32 15 29@i4 = hidden thread_local global i32 15 30@i5 = external hidden thread_local global i32 31@s1 = thread_local global i16 15 32@b1 = thread_local global i8 0 33 34define i32 @f1() { 35; ARM32-LABEL: f1: 36; ARM32: ldr r0, 37; ARM32: ldr r0, [pc, r0] 38; ARM32-NEXT: bl __emutls_get_address 39; ARM32-NEXT: ldr r0, [r0] 40; ARM32: .long __emutls_v.i1(GOT_PREL) 41 42entry: 43 %tmp1 = load i32, ptr @i1 44 ret i32 %tmp1 45} 46 47define ptr @f2() { 48; ARM32-LABEL: f2: 49; ARM32: ldr r0, 50; ARM32: ldr r0, [pc, r0] 51; ARM32-NEXT: bl __emutls_get_address 52; ARM32-NEXT: pop 53; ARM32: .long __emutls_v.i1(GOT_PREL) 54 55entry: 56 ret ptr @i1 57} 58 59define i32 @f3() nounwind { 60; ARM32-LABEL: f3: 61; ARM32: ldr r0, 62; ARM32: ldr r0, [pc, r0] 63; ARM32-NEXT: bl __emutls_get_address 64; ARM32-NEXT: ldr r0, [r0] 65; ARM32: .long __emutls_v.i2(GOT_PREL) 66 67entry: 68 %tmp1 = load i32, ptr @i2 69 ret i32 %tmp1 70} 71 72define ptr @f4() { 73; ARM32-LABEL: f4: 74; ARM32: ldr r0, 75; ARM32: ldr r0, [pc, r0] 76; ARM32-NEXT: bl __emutls_get_address 77; ARM32-NEXT: pop 78; ARM32: .long __emutls_v.i2(GOT_PREL) 79 80entry: 81 ret ptr @i2 82} 83 84define i32 @f5() nounwind { 85; ARM32-LABEL: f5: 86; ARM32: ldr r0, 87; ARM32: add r0, pc, r0 88; ARM32-NEXT: bl __emutls_get_address 89; ARM32-NEXT: ldr r0, [r0] 90; ARM32: .long __emutls_v.i3- 91 92entry: 93 %tmp1 = load i32, ptr @i3 94 ret i32 %tmp1 95} 96 97define ptr @f6() { 98; ARM32-LABEL: f6: 99; ARM32: ldr r0, 100; ARM32: add r0, pc, r0 101; ARM32-NEXT: bl __emutls_get_address 102; ARM32-NEXT: pop 103; ARM32: .long __emutls_v.i3- 104 105entry: 106 ret ptr @i3 107} 108 109define i32 @f7() { 110; ARM32-LABEL: f7: 111; ARM32: ldr r0, 112; ARM32: add r0, pc, r0 113; ARM32-NEXT: bl __emutls_get_address 114; ARM32-NEXT: ldr r0, [r0] 115; ARM32: .long __emutls_v.i4-(.LPC 116 117entry: 118 %tmp1 = load i32, ptr @i4 119 ret i32 %tmp1 120} 121 122define ptr @f8() { 123; ARM32-LABEL: f8: 124; ARM32: ldr r0, 125; ARM32: add r0, pc, r0 126; ARM32-NEXT: bl __emutls_get_address 127; ARM32-NEXT: pop 128; ARM32: .long __emutls_v.i4-(.LPC 129 130entry: 131 ret ptr @i4 132} 133 134define i32 @f9() { 135; ARM32-LABEL: f9: 136; ARM32: ldr r0, 137; ARM32: add r0, pc, r0 138; ARM32-NEXT: bl __emutls_get_address 139; ARM32-NEXT: ldr r0, [r0] 140 141entry: 142 %tmp1 = load i32, ptr @i5 143 ret i32 %tmp1 144} 145 146define ptr @f10() { 147; ARM32-LABEL: f10: 148; ARM32: ldr r0, 149; ARM32: add r0, pc, r0 150; ARM32-NEXT: bl __emutls_get_address 151; ARM32-NEXT: pop 152 153entry: 154 ret ptr @i5 155} 156 157define i16 @f11() { 158; ARM32-LABEL: f11: 159; ARM32: ldr r0, 160; ARM32: ldr r0, [pc, r0] 161; ARM32-NEXT: bl __emutls_get_address 162; ARM32-NEXT: ldrh r0, [r0] 163 164entry: 165 %tmp1 = load i16, ptr @s1 166 ret i16 %tmp1 167} 168 169define i32 @f12() { 170; ARM32-LABEL: f12: 171; ARM32: ldr r0, 172; ARM32: ldr r0, [pc, r0] 173; ARM32-NEXT: bl __emutls_get_address 174; ARM32-NEXT: ldrsh r0, [r0] 175 176entry: 177 %tmp1 = load i16, ptr @s1 178 %tmp2 = sext i16 %tmp1 to i32 179 ret i32 %tmp2 180} 181 182define i8 @f13() { 183; ARM32-LABEL: f13: 184; ARM32: ldr r0, 185; ARM32: ldr r0, [pc, r0] 186; ARM32-NEXT: bl __emutls_get_address 187; ARM32-NEXT: ldrb r0, [r0] 188; ARM32-NEXT: pop 189 190entry: 191 %tmp1 = load i8, ptr @b1 192 ret i8 %tmp1 193} 194 195define i32 @f14() { 196; ARM32-LABEL: f14: 197; ARM32: ldr r0, 198; ARM32: ldr r0, [pc, r0] 199; ARM32-NEXT: bl __emutls_get_address 200; ARM32-NEXT: ldrsb r0, [r0] 201; ARM32-NEXT: pop 202 203entry: 204 %tmp1 = load i8, ptr @b1 205 %tmp2 = sext i8 %tmp1 to i32 206 ret i32 %tmp2 207} 208 209;;;;;;;;;;;;;; 32-bit __emutls_v. and __emutls_t. 210 211; ARM32: .data{{$}} 212; ARM32: .globl __emutls_v.i1 213; ARM32-LABEL: __emutls_v.i1: 214; ARM32-NEXT: .long 4 215; ARM32-NEXT: .long 4 216; ARM32-NEXT: .long 0 217; ARM32-NEXT: .long __emutls_t.i1 218 219; ARM32: .section .rodata, 220; ARM32-LABEL: __emutls_t.i1: 221; ARM32-NEXT: .long 15 222 223; ARM32-NOT: __emutls_v.i2 224 225; ARM32: .data{{$}} 226; ARM32-NOT: .globl 227; ARM32-LABEL: __emutls_v.i3: 228; ARM32-NEXT: .long 4 229; ARM32-NEXT: .long 4 230; ARM32-NEXT: .long 0 231; ARM32-NEXT: .long __emutls_t.i3 232 233; ARM32: .section .rodata, 234; ARM32-LABEL: __emutls_t.i3: 235; ARM32-NEXT: .long 15 236 237; ARM32: .data{{$}} 238; ARM32: .globl __emutls_v.i4 239; ARM32-LABEL: __emutls_v.i4: 240; ARM32-NEXT: .long 4 241; ARM32-NEXT: .long 4 242; ARM32-NEXT: .long 0 243; ARM32-NEXT: .long __emutls_t.i4 244 245; ARM32: .section .rodata, 246; ARM32-LABEL: __emutls_t.i4: 247; ARM32-NEXT: .long 15 248 249; ARM32-NOT: __emutls_v.i5: 250; ARM32: .hidden __emutls_v.i5 251; ARM32-NOT: __emutls_v.i5: 252 253; ARM32: .data{{$}} 254; ARM32: .globl __emutls_v.s1 255; ARM32-LABEL: __emutls_v.s1: 256; ARM32-NEXT: .long 2 257; ARM32-NEXT: .long 2 258; ARM32-NEXT: .long 0 259; ARM32-NEXT: .long __emutls_t.s1 260 261; ARM32: .section .rodata, 262; ARM32-LABEL: __emutls_t.s1: 263; ARM32-NEXT: .short 15 264 265; ARM32: .data{{$}} 266; ARM32: .globl __emutls_v.b1 267; ARM32-LABEL: __emutls_v.b1: 268; ARM32-NEXT: .long 1 269; ARM32-NEXT: .long 1 270; ARM32-NEXT: .long 0 271; ARM32-NEXT: .long 0 272 273; ARM32-NOT: __emutls_t.b1 274