1 // REQUIRES: x86-registered-target 2 // RUN: %clang_cc1 %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - | FileCheck %s 3 4 void t1() { 5 // CHECK: @t1 6 // CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() 7 // CHECK: ret void 8 __asm {} 9 } 10 11 void t2() { 12 // CHECK: @t2 13 // CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"() 14 // CHECK: ret void 15 __asm nop 16 __asm nop 17 __asm nop 18 } 19 20 void t3() { 21 // CHECK: @t3 22 // CHECK: call void asm sideeffect inteldialect "nop\0A\09nop\0A\09nop", "~{dirflag},~{fpsr},~{flags}"() 23 // CHECK: ret void 24 __asm nop __asm nop __asm nop 25 } 26 27 void t4(void) { 28 // CHECK: @t4 29 // CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() 30 // CHECK: ret void 31 __asm mov ebx, eax 32 __asm mov ecx, ebx 33 } 34 35 void t5(void) { 36 // CHECK: @t5 37 // CHECK: call void asm sideeffect inteldialect "mov ebx, eax\0A\09mov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() 38 // CHECK: ret void 39 __asm mov ebx, eax __asm mov ecx, ebx 40 } 41 42 void t6(void) { 43 __asm int 0x2c 44 // CHECK: t6 45 // CHECK: call void asm sideeffect inteldialect "int $$44", "~{dirflag},~{fpsr},~{flags}"() 46 } 47 48 void t7() { 49 __asm { 50 int 0x2cU ; } asm comments are fun! }{ 51 } 52 __asm { 53 { 54 int 0x2c ; } asm comments are fun! }{ 55 } 56 } 57 __asm {} 58 __asm { 59 ; 60 ; label 61 mov eax, ebx 62 } 63 // CHECK: t7 64 // CHECK: call void asm sideeffect inteldialect "int $$44", "~{dirflag},~{fpsr},~{flags}"() 65 // CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() 66 // CHECK: call void asm sideeffect inteldialect "mov eax, ebx", "~{eax},~{dirflag},~{fpsr},~{flags}"() 67 } 68 69 int t8() { 70 __asm int 4 ; } comments for single-line asm 71 __asm {} 72 __asm { int 5} 73 __asm int 6 74 __asm int 7 75 __asm { 76 int 8 77 } 78 return 10; 79 // CHECK: t8 80 // CHECK: call i32 asm sideeffect inteldialect "int $$4", "={eax},~{dirflag},~{fpsr},~{flags}"() 81 // CHECK: call i32 asm sideeffect inteldialect "", "={eax},~{dirflag},~{fpsr},~{flags}"() 82 // CHECK: call i32 asm sideeffect inteldialect "int $$5", "={eax},~{dirflag},~{fpsr},~{flags}"() 83 // CHECK: call i32 asm sideeffect inteldialect "int $$6\0A\09int $$7", "={eax},~{dirflag},~{fpsr},~{flags}"() 84 // CHECK: call i32 asm sideeffect inteldialect "int $$8", "={eax},~{dirflag},~{fpsr},~{flags}"() 85 // CHECK: ret i32 10 86 } 87 88 void t9() { 89 __asm { 90 push ebx 91 { mov ebx, 0x07 } 92 __asm { pop ebx } 93 } 94 // CHECK: t9 95 // CHECK: call void asm sideeffect inteldialect 96 // CHECK-SAME: push ebx 97 // CHECK-SAME: mov ebx, $$7 98 // CHECK-SAME: pop ebx 99 // CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() 100 } 101 102 unsigned t10(void) { 103 unsigned i = 1, j; 104 __asm { 105 mov eax, i 106 mov j, eax 107 } 108 return j; 109 // CHECK: t10 110 // CHECK: [[r:%[a-zA-Z0-9]+]] = alloca i32, align 4 111 // CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4 112 // CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4 113 // CHECK: store i32 1, i32* [[I]], align 4 114 // CHECK: call i32 asm sideeffect inteldialect 115 // CHECK-SAME: mov eax, $2 116 // CHECK-SAME: mov $0, eax 117 // CHECK-SAME: "=*m,={eax},*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}) 118 // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32, i32* [[J]], align 4 119 // CHECK: ret i32 [[RET]] 120 } 121 122 void t11(void) { 123 __asm mov eax, 1 124 // CHECK: t11 125 // CHECK: call void asm sideeffect inteldialect "mov eax, $$1", "~{eax},~{dirflag},~{fpsr},~{flags}"() 126 } 127 128 unsigned t12(void) { 129 unsigned i = 1, j, l = 1, m; 130 __asm { 131 mov eax, i 132 mov j, eax 133 mov eax, l 134 mov m, eax 135 } 136 return j + m; 137 // CHECK: t12 138 // CHECK: call i32 asm sideeffect inteldialect 139 // CHECK-SAME: mov eax, $3 140 // CHECK-SAME: mov $0, eax 141 // CHECK-SAME: mov eax, $4 142 // CHECK-SAME: mov $1, eax 143 // CHECK-SAME: "=*m,=*m,={eax},*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) 144 } 145 146 void t13() { 147 char i = 1; 148 short j = 2; 149 __asm movzx eax, i 150 __asm movzx eax, j 151 // CHECK-LABEL: define void @t13() 152 // CHECK: call void asm sideeffect inteldialect 153 // CHECK-SAME: movzx eax, byte ptr $0 154 // CHECK-SAME: movzx eax, word ptr $1 155 // CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j) 156 } 157 158 void t13_brac() { 159 char i = 1; 160 short j = 2; 161 __asm movzx eax, [i] 162 __asm movzx eax, [j] 163 // CHECK-LABEL: define void @t13_brac() 164 // CHECK: call void asm sideeffect inteldialect 165 // CHECK-SAME: movzx eax, byte ptr $0 166 // CHECK-SAME: movzx eax, word ptr $1 167 // CHECK-SAME: "*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i8* %{{.*}}i, i16* %{{.*}}j) 168 } 169 170 void t14() { 171 unsigned i = 1, j = 2; 172 __asm { 173 .if 1 174 { mov eax, i } 175 .else 176 mov ebx, j 177 .endif 178 } 179 // CHECK: t14 180 // CHECK: call void asm sideeffect inteldialect ".if 1\0A\09mov eax, $0\0A\09.else\0A\09mov ebx, j\0A\09.endif", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 181 } 182 183 int gvar = 10; 184 void t15() { 185 // CHECK: t15 186 int lvar = 10; 187 __asm mov eax, lvar ; eax = 10 188 // CHECK: mov eax, $0 189 __asm mov eax, offset lvar ; eax = address of lvar 190 // CHECK: mov eax, $1 191 __asm mov eax, offset gvar ; eax = address of gvar 192 // CHECK: mov eax, $2 193 // CHECK: "*m,r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* @{{.*}}) 194 } 195 196 void t16() { 197 int var = 10; 198 __asm mov [eax], offset var 199 // CHECK: t16 200 // CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 201 } 202 203 void t17() { 204 // CHECK: t17 205 __asm _emit 0x4A 206 // CHECK: .byte 0x4A 207 __asm _emit 0x43L 208 // CHECK: .byte 0x43L 209 __asm _emit 0x4B 210 // CHECK: .byte 0x4B 211 __asm _EMIT 0x4B 212 // CHECK: .byte 0x4B 213 // CHECK: "~{dirflag},~{fpsr},~{flags}"() 214 } 215 216 void t20() { 217 // CHECK: t20 218 char bar; 219 int foo; 220 char _bar[2]; 221 int _foo[4]; 222 223 __asm mov eax, LENGTH foo 224 // CHECK: mov eax, $$1 225 __asm mov eax, LENGTH bar 226 // CHECK: mov eax, $$1 227 __asm mov eax, LENGTH _foo 228 // CHECK: mov eax, $$4 229 __asm mov eax, LENGTH _bar 230 // CHECK: mov eax, $$2 231 __asm mov eax, [eax + LENGTH foo * 4] 232 // CHECK: mov eax, [eax + $$4] 233 234 __asm mov eax, TYPE foo 235 // CHECK: mov eax, $$4 236 __asm mov eax, TYPE bar 237 // CHECK: mov eax, $$1 238 __asm mov eax, TYPE _foo 239 // CHECK: mov eax, $$4 240 __asm mov eax, TYPE _bar 241 // CHECK: mov eax, $$1 242 __asm mov eax, [eax + TYPE foo * 4] 243 // CHECK: mov eax, [eax + $$16] 244 245 __asm mov eax, SIZE foo 246 // CHECK: mov eax, $$4 247 __asm mov eax, SIZE bar 248 // CHECK: mov eax, $$1 249 __asm mov eax, SIZE _foo 250 // CHECK: mov eax, $$16 251 __asm mov eax, [eax + SIZE _foo * 4] 252 // CHECK: mov eax, [eax + $$64] 253 __asm mov eax, SIZE _bar 254 // CHECK: mov eax, $$2 255 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 256 257 } 258 259 void t21() { 260 __asm { 261 __asm push ebx 262 __asm mov ebx, 07H 263 __asm pop ebx 264 } 265 // CHECK: t21 266 // CHECK: call void asm sideeffect inteldialect 267 // CHECK-SAME: push ebx 268 // CHECK-SAME: mov ebx, $$7 269 // CHECK-SAME: pop ebx 270 // CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() 271 } 272 273 extern void t22_helper(int x); 274 void t22() { 275 int x = 0; 276 __asm { 277 __asm push ebx 278 __asm mov ebx, esp 279 } 280 t22_helper(x); 281 __asm { 282 __asm mov esp, ebx 283 __asm pop ebx 284 } 285 // CHECK: t22 286 // CHECK: call void asm sideeffect inteldialect 287 // CHECK-SAME: push ebx 288 // CHECK-SAME: mov ebx, esp 289 // CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() 290 // CHECK: call void @t22_helper 291 // CHECK: call void asm sideeffect inteldialect 292 // CHECK-SAME: mov esp, ebx 293 // CHECK-SAME: pop ebx 294 // CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() 295 } 296 297 void t23() { 298 __asm { 299 the_label: 300 } 301 // CHECK: t23 302 // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__the_label:", "~{dirflag},~{fpsr},~{flags}"() 303 } 304 305 void t24_helper(void) {} 306 void t24() { 307 __asm call t24_helper 308 // CHECK: t24 309 // CHECK: call void asm sideeffect inteldialect "call dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper) 310 } 311 312 void t25() { 313 // CHECK: t25 314 __asm mov eax, 0ffffffffh 315 // CHECK: mov eax, $$4294967295 316 __asm mov eax, 0fhU 317 // CHECK: mov eax, $$15 318 __asm mov eax, 0a2h 319 // CHECK: mov eax, $$162 320 __asm mov eax, 10100010b 321 // CHECK: mov eax, $$162 322 __asm mov eax, 10100010BU 323 // CHECK: mov eax, $$162 324 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 325 } 326 327 void t26() { 328 // CHECK: t26 329 __asm pushad 330 // CHECK: pushad 331 __asm mov eax, 0 332 // CHECK: mov eax, $$0 333 __asm __emit 0fh 334 // CHECK: .byte 0fh 335 __asm __emit 0a2h 336 // CHECK: .byte 0a2h 337 __asm __EMIT 0a2h 338 // CHECK: .byte 0a2h 339 __asm popad 340 // CHECK: popad 341 // CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"() 342 } 343 344 void t27() { 345 __asm mov eax, fs:[0h] 346 // CHECK: t27 347 // CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0]", "~{eax},~{dirflag},~{fpsr},~{flags}"() 348 } 349 350 void t28() { 351 // CHECK: t28 352 __asm align 8 353 // CHECK: .align 3 354 __asm align 16; 355 // CHECK: .align 4 356 __asm align 128; 357 // CHECK: .align 7 358 __asm ALIGN 256; 359 // CHECK: .align 8 360 // CHECK: "~{dirflag},~{fpsr},~{flags}"() 361 } 362 363 void t29() { 364 // CHECK: t29 365 int arr[2] = {0, 0}; 366 int olen = 0, osize = 0, otype = 0; 367 __asm mov olen, LENGTH arr 368 // CHECK: mov dword ptr $0, $$2 369 __asm mov osize, SIZE arr 370 // CHECK: mov dword ptr $1, $$8 371 __asm mov otype, TYPE arr 372 // CHECK: mov dword ptr $2, $$4 373 // CHECK: "=*m,=*m,=*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) 374 } 375 376 int results[2] = {13, 37}; 377 int *t30() 378 // CHECK: t30 379 { 380 int *res; 381 __asm lea edi, results 382 // CHECK: lea edi, $2 383 __asm mov res, edi 384 // CHECK: mov $0, edi 385 return res; 386 // CHECK: "=*m,={eax},*m,~{edi},~{dirflag},~{fpsr},~{flags}"(i32** %{{.*}}, [2 x i32]* @{{.*}}) 387 } 388 389 void t31() { 390 // CHECK: t31 391 __asm pushad 392 // CHECK: pushad 393 __asm popad 394 // CHECK: popad 395 // CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"() 396 } 397 398 void t32() { 399 // CHECK: t32 400 int i; 401 __asm mov eax, i 402 // CHECK: mov eax, $0 403 __asm mov eax, dword ptr i 404 // CHECK: mov eax, dword ptr $1 405 __asm mov ax, word ptr i 406 // CHECK: mov ax, word ptr $2 407 __asm mov al, byte ptr i 408 // CHECK: mov al, byte ptr $3 409 // CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) 410 } 411 412 void t33() { 413 // CHECK: t33 414 int i; 415 __asm mov eax, [i] 416 // CHECK: mov eax, $0 417 __asm mov eax, dword ptr [i] 418 // CHECK: mov eax, dword ptr $1 419 __asm mov ax, word ptr [i] 420 // CHECK: mov ax, word ptr $2 421 __asm mov al, byte ptr [i] 422 // CHECK: mov al, byte ptr $3 423 // CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) 424 } 425 426 void t34() { 427 // CHECK: t34 428 __asm prefetchnta 64[eax] 429 // CHECK: prefetchnta [eax + $$64] 430 __asm mov eax, dword ptr 4[eax] 431 // CHECK: mov eax, dword ptr [eax + $$4] 432 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 433 } 434 435 void t35() { 436 // CHECK: t35 437 __asm prefetchnta [eax + (200*64)] 438 // CHECK: prefetchnta [eax + $$12800] 439 __asm mov eax, dword ptr [eax + (200*64)] 440 // CHECK: mov eax, dword ptr [eax + $$12800] 441 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 442 } 443 444 void t36() { 445 // CHECK: t36 446 int arr[4]; 447 // Work around PR20368: These should be single line blocks 448 __asm { mov eax, 4[arr] } 449 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 450 __asm { mov eax, 4[arr + 4] } 451 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 452 __asm { mov eax, 8[arr + 4 + 32*2 - 4] } 453 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 454 __asm { mov eax, 12[4 + arr] } 455 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 456 __asm { mov eax, 4[4 + arr + 4] } 457 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 458 __asm { mov eax, 4[64 + arr + (2*32)] } 459 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 460 __asm { mov eax, 4[64 + arr - 2*32] } 461 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 462 __asm { mov eax, [arr + 4] } 463 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 464 __asm { mov eax, [arr + 4 + 32*2 - 4] } 465 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 466 __asm { mov eax, [4 + arr] } 467 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 468 __asm { mov eax, [4 + arr + 4] } 469 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 470 __asm { mov eax, [64 + arr + (2*32)] } 471 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 472 __asm { mov eax, [64 + arr - 2*32] } 473 // CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 474 } 475 476 void t37() { 477 // CHECK: t37 478 __asm mov eax, 4 + 8 479 // CHECK: mov eax, $$12 480 __asm mov eax, 4 + 8 * 16 481 // CHECK: mov eax, $$132 482 __asm mov eax, -4 + 8 * 16 483 // CHECK: mov eax, $$124 484 __asm mov eax, (4 + 4) * 16 485 // CHECK: mov eax, $$128 486 __asm mov eax, 4 + 8 * -16 487 // CHECK: mov eax, $$-124 488 __asm mov eax, 4 + 16 / -8 489 // CHECK: mov eax, $$2 490 __asm mov eax, (16 + 16) / -8 491 // CHECK: mov eax, $$-4 492 __asm mov eax, ~15 493 // CHECK: mov eax, $$-16 494 __asm mov eax, 6 ^ 3 495 // CHECK: mov eax, $$5 496 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 497 } 498 499 void t38() { 500 // CHECK: t38 501 int arr[4]; 502 // Work around PR20368: These should be single line blocks 503 __asm { mov eax, 4+4[arr] } 504 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 505 __asm { mov eax, (4+4)[arr + 4] } 506 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 507 __asm { mov eax, 8*2[arr + 4 + 32*2 - 4] } 508 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$80]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 509 __asm { mov eax, 12+20[4 + arr] } 510 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$36]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 511 __asm { mov eax, 4*16+4[4 + arr + 4] } 512 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$76]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 513 __asm { mov eax, 4*4[64 + arr + (2*32)] } 514 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$144]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 515 __asm { mov eax, 4*(4-2)[64 + arr - 2*32] } 516 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 517 __asm { mov eax, 32*(4-2)[arr - 2*32] } 518 // CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}}) 519 } 520 521 void cpuid() { 522 __asm cpuid 523 // CHECK-LABEL: define void @cpuid 524 // CHECK: call void asm sideeffect inteldialect "cpuid", "~{eax},~{ebx},~{ecx},~{edx},~{dirflag},~{fpsr},~{flags}"() 525 } 526 527 typedef struct { 528 int a; 529 int b; 530 } A, *pA; 531 532 typedef struct { 533 int b1; 534 A b2; 535 } B; 536 537 typedef struct { 538 int c1; 539 A c2; 540 int c3; 541 B c4; 542 } C, *pC; 543 544 void t39() { 545 // CHECK-LABEL: define void @t39 546 __asm mov eax, [eax].A.b 547 // CHECK: mov eax, [eax + $$4] 548 __asm mov eax, [eax] A.b 549 // CHECK: mov eax, [eax + $$4] 550 __asm mov eax, [eax] pA.b 551 // CHECK: mov eax, [eax + $$4] 552 __asm mov eax, fs:[0] A.b 553 // CHECK: mov eax, fs:[$$4] 554 __asm mov eax, [eax].B.b2.a 555 // CHECK: mov eax, [eax + $$4] 556 __asm mov eax, [eax] B.b2.b 557 // CHECK: mov eax, [eax + $$8] 558 __asm mov eax, fs:[0] C.c2.b 559 // CHECK: mov eax, fs:[$$8] 560 __asm mov eax, [eax]C.c4.b2.b 561 // CHECK: mov eax, [eax + $$24] 562 __asm mov eax, [eax]pC.c4.b2.b 563 // CHECK: mov eax, [eax + $$24] 564 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 565 } 566 567 void t40(float a) { 568 // CHECK-LABEL: define void @t40 569 int i; 570 __asm fld a 571 // CHECK: fld dword ptr $1 572 __asm fistp i 573 // CHECK: fistp dword ptr $0 574 // CHECK: "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, float* %{{.*}}) 575 } 576 577 void t41(unsigned short a) { 578 // CHECK-LABEL: define void @t41(i16 zeroext %a) 579 __asm mov cs, a; 580 // CHECK: mov cs, $0 581 __asm mov ds, a; 582 // CHECK: mov ds, $1 583 __asm mov es, a; 584 // CHECK: mov es, $2 585 __asm mov fs, a; 586 // CHECK: mov fs, $3 587 __asm mov gs, a; 588 // CHECK: mov gs, $4 589 __asm mov ss, a; 590 // CHECK: mov ss, $5 591 // CHECK: "*m,*m,*m,*m,*m,*m,~{dirflag},~{fpsr},~{flags}"(i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}) 592 } 593 594 void t42() { 595 // CHECK-LABEL: define void @t42 596 int flags; 597 __asm mov flags, eax 598 // CHECK: mov $0, eax 599 // CHECK: "=*m,~{dirflag},~{fpsr},~{flags}"(i32* %flags) 600 } 601 602 void t43() { 603 // CHECK-LABEL: define void @t43 604 C strct; 605 // Work around PR20368: These should be single line blocks 606 __asm { mov eax, 4[strct.c1] } 607 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 608 __asm { mov eax, 4[strct.c3 + 4] } 609 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 610 __asm { mov eax, 8[strct.c2.a + 4 + 32*2 - 4] } 611 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 612 __asm { mov eax, 12[4 + strct.c2.b] } 613 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 614 __asm { mov eax, 4[4 + strct.c4.b2.b + 4] } 615 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 616 __asm { mov eax, 4[64 + strct.c1 + (2*32)] } 617 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 618 __asm { mov eax, 4[64 + strct.c2.a - 2*32] } 619 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 620 __asm { mov eax, [strct.c4.b1 + 4] } 621 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 622 __asm { mov eax, [strct.c4.b2.a + 4 + 32*2 - 4] } 623 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 624 __asm { mov eax, [4 + strct.c1] } 625 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 626 __asm { mov eax, [4 + strct.c2.b + 4] } 627 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 628 __asm { mov eax, [64 + strct.c3 + (2*32)] } 629 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 630 __asm { mov eax, [64 + strct.c4.b2.b - 2*32] } 631 // CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 632 } 633 634 void t44() { 635 // CHECK-LABEL: define void @t44 636 __asm { 637 mov cr0, eax 638 mov cr2, ebx 639 mov cr3, ecx 640 mov cr4, edx 641 } 642 // CHECK: call void asm sideeffect inteldialect "mov cr0, eax\0A\09mov cr2, ebx\0A\09mov cr3, ecx\0A\09mov cr4, edx", "~{cr0},~{cr2},~{cr3},~{cr4},~{dirflag},~{fpsr},~{flags}"() 643 } 644 645 void t45() { 646 // CHECK-LABEL: define void @t45 647 __asm { 648 mov dr0, eax 649 mov dr1, ebx 650 mov dr2, ebx 651 mov dr3, ecx 652 mov dr6, edx 653 mov dr7, ecx 654 } 655 // CHECK: call void asm sideeffect inteldialect "mov dr0, eax\0A\09mov dr1, ebx\0A\09mov dr2, ebx\0A\09mov dr3, ecx\0A\09mov dr6, edx\0A\09mov dr7, ecx", "~{dr0},~{dr1},~{dr2},~{dr3},~{dr6},~{dr7},~{dirflag},~{fpsr},~{flags}"() 656 } 657 658 void t46() { 659 // CHECK-LABEL: define void @t46 660 __asm add eax, -128[eax] 661 // CHECK: call void asm sideeffect inteldialect "add eax, [eax + $$-128]", "~{eax},~{flags},~{dirflag},~{fpsr},~{flags}"() 662 } 663 664 void t47() { 665 // CHECK-LABEL: define void @t47 666 __asm { 667 bndmk bnd0, dword ptr [eax] 668 bndmk bnd1, dword ptr [ebx] 669 bndmk bnd2, dword ptr [ecx] 670 bndmk bnd3, dword ptr [edx] 671 } 672 // CHECK: call void asm sideeffect inteldialect "bndmk bnd0, dword ptr [eax]\0A\09bndmk bnd1, dword ptr [ebx]\0A\09bndmk bnd2, dword ptr [ecx]\0A\09bndmk bnd3, dword ptr [edx]", "~{bnd0},~{bnd1},~{bnd2},~{bnd3},~{dirflag},~{fpsr},~{flags}"() 673 } 674 675 void dot_operator(){ 676 // CHECK-LABEL: define void @dot_operator 677 __asm { mov eax, 3[ebx]A.b} 678 // CHECK: call void asm sideeffect inteldialect "mov eax, [ebx + $$7]", "~{eax},~{dirflag},~{fpsr},~{flags}" 679 } 680 681 void call_clobber() { 682 __asm call t41 683 // CHECK-LABEL: define void @call_clobber 684 // CHECK: call void asm sideeffect inteldialect "call dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(void (i16)* @t41) 685 } 686 687 void xgetbv() { 688 __asm xgetbv 689 } 690 // CHECK-LABEL: define void @xgetbv() 691 // CHECK: call void asm sideeffect inteldialect "xgetbv", "~{eax},~{edx},~{dirflag},~{fpsr},~{flags}"() 692 693 void label1() { 694 __asm { 695 label: 696 jmp label 697 } 698 // CHECK-LABEL: define void @label1() 699 // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__label:\0A\09jmp {{.*}}__MSASMLABEL_.${:uid}__label", "~{dirflag},~{fpsr},~{flags}"() [[ATTR1:#[0-9]+]] 700 } 701 702 void label2() { 703 __asm { 704 jmp label 705 label: 706 } 707 // CHECK-LABEL: define void @label2 708 // CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:", "~{dirflag},~{fpsr},~{flags}"() 709 } 710 711 void label3() { 712 __asm { 713 label: 714 mov eax, label 715 } 716 // CHECK-LABEL: define void @label3 717 // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__label:\0A\09mov eax, {{.*}}__MSASMLABEL_.${:uid}__label", "~{eax},~{dirflag},~{fpsr},~{flags}"() 718 } 719 720 void label4() { 721 __asm { 722 label: 723 mov eax, [label] 724 } 725 // CHECK-LABEL: define void @label4 726 // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__label:\0A\09mov eax, {{.*}}__MSASMLABEL_.${:uid}__label", "~{eax},~{dirflag},~{fpsr},~{flags}"() 727 } 728 729 void label5() { 730 __asm { 731 jmp dollar_label$ 732 dollar_label$: 733 } 734 // CHECK-LABEL: define void @label5 735 // CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.${:uid}__dollar_label$$\0A\09{{.*}}__MSASMLABEL_.${:uid}__dollar_label$$:", "~{dirflag},~{fpsr},~{flags}"() 736 } 737 738 void label6(){ 739 __asm { 740 jmp short label 741 jc short label 742 jz short label 743 label: 744 } 745 // CHECK-LABEL: define void @label6 746 // CHECK: jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09jc {{.*}}__MSASMLABEL_.${:uid}__label\0A\09jz {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:" 747 } 748 749 // Don't include mxcsr in the clobber list. 750 void mxcsr() { 751 char buf[4096]; 752 __asm fxrstor buf 753 } 754 // CHECK-LABEL: define void @mxcsr 755 // CHECK: call void asm sideeffect inteldialect "fxrstor $0", "=*m,~{dirflag},~{fpsr},~{flags}" 756 757 typedef union _LARGE_INTEGER { 758 struct { 759 unsigned int LowPart; 760 unsigned int HighPart; 761 }; 762 struct { 763 unsigned int LowPart; 764 unsigned int HighPart; 765 } u; 766 unsigned long long QuadPart; 767 } LARGE_INTEGER, *PLARGE_INTEGER; 768 769 int test_indirect_field(LARGE_INTEGER LargeInteger) { 770 __asm mov eax, LargeInteger.LowPart 771 } 772 // CHECK-LABEL: define i32 @test_indirect_field( 773 // CHECK: call i32 asm sideeffect inteldialect "mov eax, $1", 774 775 // MS ASM containing labels must not be duplicated (PR23715). 776 // CHECK: attributes [[ATTR1]] = { 777 // CHECK-NOT: noduplicate 778 // CHECK-SAME: }{{$}} 779