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