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