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,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(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,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(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* elementtype(i8) %{{.*}}i, i16* elementtype(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* elementtype(i8) %{{.*}}i, i16* elementtype(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* elementtype(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 __asm mov eax, offset gvar+1 ; eax = 1 + address of gvar 194 // CHECK: mov eax, $3 + $$1 195 __asm mov eax, 1+offset gvar ; eax = 1 + address of gvar 196 // CHECK: mov eax, $4 + $$1 197 __asm mov eax, 1+offset gvar+1 ; eax = 2 + address of gvar 198 // CHECK: mov eax, $5 + $$2 199 // CHECK: "*m,r,i,i,i,i,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* %{{.*}}, i32* @{{.*}}, i32* @{{.*}}, i32* @{{.*}}, i32* @{{.*}}) 200 } 201 202 void t16() { 203 int var = 10; 204 __asm mov dword ptr [eax], offset var 205 // CHECK: t16 206 // CHECK: call void asm sideeffect inteldialect "mov dword ptr [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) 207 } 208 209 void t17() { 210 // CHECK: t17 211 __asm _emit 0x4A 212 // CHECK: .byte 0x4A 213 __asm _emit 0x43L 214 // CHECK: .byte 0x43L 215 __asm _emit 0x4B 216 // CHECK: .byte 0x4B 217 __asm _EMIT 0x4B 218 // CHECK: .byte 0x4B 219 // CHECK: "~{dirflag},~{fpsr},~{flags}"() 220 } 221 222 void t20() { 223 // CHECK: t20 224 char bar; 225 int foo; 226 char _bar[2]; 227 int _foo[4]; 228 229 __asm mov eax, LENGTH foo 230 // CHECK: mov eax, $$1 231 __asm mov eax, LENGTH bar 232 // CHECK: mov eax, $$1 233 __asm mov eax, LENGTH _foo 234 // CHECK: mov eax, $$4 235 __asm mov eax, LENGTH _bar 236 // CHECK: mov eax, $$2 237 __asm mov eax, [eax + LENGTH foo * 4] 238 // CHECK: mov eax, [eax + $$4] 239 240 __asm mov eax, TYPE foo 241 // CHECK: mov eax, $$4 242 __asm mov eax, TYPE bar 243 // CHECK: mov eax, $$1 244 __asm mov eax, TYPE _foo 245 // CHECK: mov eax, $$4 246 __asm mov eax, TYPE _bar 247 // CHECK: mov eax, $$1 248 __asm mov eax, [eax + TYPE foo * 4] 249 // CHECK: mov eax, [eax + $$16] 250 251 __asm mov eax, SIZE foo 252 // CHECK: mov eax, $$4 253 __asm mov eax, SIZE bar 254 // CHECK: mov eax, $$1 255 __asm mov eax, SIZE _foo 256 // CHECK: mov eax, $$16 257 __asm mov eax, [eax + SIZE _foo * 4] 258 // CHECK: mov eax, [eax + $$64] 259 __asm mov eax, SIZE _bar 260 // CHECK: mov eax, $$2 261 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 262 263 } 264 265 void t21() { 266 __asm { 267 __asm push ebx 268 __asm mov ebx, 07H 269 __asm pop ebx 270 } 271 // CHECK: t21 272 // CHECK: call void asm sideeffect inteldialect 273 // CHECK-SAME: push ebx 274 // CHECK-SAME: mov ebx, $$7 275 // CHECK-SAME: pop ebx 276 // CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() 277 } 278 279 extern void t22_helper(int x); 280 void t22() { 281 int x = 0; 282 __asm { 283 __asm push ebx 284 __asm mov ebx, esp 285 } 286 t22_helper(x); 287 __asm { 288 __asm mov esp, ebx 289 __asm pop ebx 290 } 291 // CHECK: t22 292 // CHECK: call void asm sideeffect inteldialect 293 // CHECK-SAME: push ebx 294 // CHECK-SAME: mov ebx, esp 295 // CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() 296 // CHECK: call void @t22_helper 297 // CHECK: call void asm sideeffect inteldialect 298 // CHECK-SAME: mov esp, ebx 299 // CHECK-SAME: pop ebx 300 // CHECK-SAME: "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() 301 } 302 303 void t23() { 304 __asm { 305 the_label: 306 } 307 // CHECK: t23 308 // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__the_label:", "~{dirflag},~{fpsr},~{flags}"() 309 } 310 311 void t24_helper(void) {} 312 void t24() { 313 __asm call t24_helper 314 // CHECK: t24 315 // CHECK: call void asm sideeffect inteldialect "call dword ptr ${0:P}", "*m,~{dirflag},~{fpsr},~{flags}"(void ()* elementtype(void ()) @t24_helper) 316 } 317 318 void t25() { 319 // CHECK: t25 320 __asm mov eax, 0ffffffffh 321 // CHECK: mov eax, $$4294967295 322 __asm mov eax, 0fhU 323 // CHECK: mov eax, $$15 324 __asm mov eax, 0a2h 325 // CHECK: mov eax, $$162 326 __asm mov eax, 10100010b 327 // CHECK: mov eax, $$162 328 __asm mov eax, 10100010BU 329 // CHECK: mov eax, $$162 330 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 331 } 332 333 void t26() { 334 // CHECK: t26 335 __asm pushad 336 // CHECK: pushad 337 __asm mov eax, 0 338 // CHECK: mov eax, $$0 339 __asm __emit 0fh 340 // CHECK: .byte 0fh 341 __asm __emit 0a2h 342 // CHECK: .byte 0a2h 343 __asm __EMIT 0a2h 344 // CHECK: .byte 0a2h 345 __asm popad 346 // CHECK: popad 347 // CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"() 348 } 349 350 void t27() { 351 __asm mov eax, fs:[0h] 352 // CHECK: t27 353 // CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0]", "~{eax},~{dirflag},~{fpsr},~{flags}"() 354 } 355 356 void t28() { 357 // CHECK: t28 358 __asm align 8 359 // CHECK: .align 3 360 __asm align 16; 361 // CHECK: .align 4 362 __asm align 128; 363 // CHECK: .align 7 364 __asm ALIGN 256; 365 // CHECK: .align 8 366 // CHECK: "~{dirflag},~{fpsr},~{flags}"() 367 } 368 369 void t29() { 370 // CHECK: t29 371 int arr[2] = {0, 0}; 372 int olen = 0, osize = 0, otype = 0; 373 __asm mov olen, LENGTH arr 374 // CHECK: mov dword ptr $0, $$2 375 __asm mov osize, SIZE arr 376 // CHECK: mov dword ptr $1, $$8 377 __asm mov otype, TYPE arr 378 // CHECK: mov dword ptr $2, $$4 379 // CHECK: "=*m,=*m,=*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}) 380 } 381 382 int results[2] = {13, 37}; 383 int *t30() 384 // CHECK: t30 385 { 386 int *res; 387 __asm lea edi, results 388 // CHECK: lea edi, $2 389 __asm mov res, edi 390 // CHECK: mov $0, edi 391 return res; 392 // CHECK: "=*m,={eax},*m,~{edi},~{dirflag},~{fpsr},~{flags}"(i32** elementtype(i32*) %{{.*}}, [2 x i32]* elementtype([2 x i32]) @{{.*}}) 393 } 394 395 void t31() { 396 // CHECK: t31 397 __asm pushad 398 // CHECK: pushad 399 __asm popad 400 // CHECK: popad 401 // CHECK: "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"() 402 } 403 404 void t32() { 405 // CHECK: t32 406 int i; 407 __asm mov eax, i 408 // CHECK: mov eax, $0 409 __asm mov eax, dword ptr i 410 // CHECK: mov eax, dword ptr $1 411 __asm mov ax, word ptr i 412 // CHECK: mov ax, word ptr $2 413 __asm mov al, byte ptr i 414 // CHECK: mov al, byte ptr $3 415 // CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}) 416 } 417 418 void t33() { 419 // CHECK: t33 420 int i; 421 __asm mov eax, [i] 422 // CHECK: mov eax, $0 423 __asm mov eax, dword ptr [i] 424 // CHECK: mov eax, dword ptr $1 425 __asm mov ax, word ptr [i] 426 // CHECK: mov ax, word ptr $2 427 __asm mov al, byte ptr [i] 428 // CHECK: mov al, byte ptr $3 429 // CHECK: "*m,*m,*m,*m,~{al},~{ax},~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}, i32* elementtype(i32) %{{.*}}) 430 } 431 432 void t34() { 433 // CHECK: t34 434 __asm prefetchnta 64[eax] 435 // CHECK: prefetchnta [eax + $$64] 436 __asm mov eax, dword ptr 4[eax] 437 // CHECK: mov eax, dword ptr [eax + $$4] 438 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 439 } 440 441 void t35() { 442 // CHECK: t35 443 __asm prefetchnta [eax + (200*64)] 444 // CHECK: prefetchnta [eax + $$12800] 445 __asm mov eax, dword ptr [eax + (200*64)] 446 // CHECK: mov eax, dword ptr [eax + $$12800] 447 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 448 } 449 450 void t36() { 451 // CHECK: t36 452 int arr[4]; 453 // Work around PR20368: These should be single line blocks 454 __asm { mov eax, 4[arr] } 455 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 456 __asm { mov eax, 4[arr + 4] } 457 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 458 __asm { mov eax, 8[arr + 4 + 32*2 - 4] } 459 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 460 __asm { mov eax, 12[4 + arr] } 461 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 462 __asm { mov eax, 4[4 + arr + 4] } 463 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 464 __asm { mov eax, 4[64 + arr + (2*32)] } 465 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 466 __asm { mov eax, 4[64 + arr - 2*32] } 467 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 468 __asm { mov eax, [arr + 4] } 469 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 470 __asm { mov eax, [arr + 4 + 32*2 - 4] } 471 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 472 __asm { mov eax, [4 + arr] } 473 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 474 __asm { mov eax, [4 + arr + 4] } 475 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 476 __asm { mov eax, [64 + arr + (2*32)] } 477 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 478 __asm { mov eax, [64 + arr - 2*32] } 479 // CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 480 } 481 482 void t37() { 483 // CHECK: t37 484 __asm mov eax, 4 + 8 485 // CHECK: mov eax, $$12 486 __asm mov eax, 4 + 8 * 16 487 // CHECK: mov eax, $$132 488 __asm mov eax, -4 + 8 * 16 489 // CHECK: mov eax, $$124 490 __asm mov eax, (4 + 4) * 16 491 // CHECK: mov eax, $$128 492 __asm mov eax, 4 + 8 * -16 493 // CHECK: mov eax, $$-124 494 __asm mov eax, 4 + 16 / -8 495 // CHECK: mov eax, $$2 496 __asm mov eax, (16 + 16) / -8 497 // CHECK: mov eax, $$-4 498 __asm mov eax, ~15 499 // CHECK: mov eax, $$-16 500 __asm mov eax, 6 ^ 3 501 // CHECK: mov eax, $$5 502 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 503 } 504 505 void t38() { 506 // CHECK: t38 507 int arr[4]; 508 // Work around PR20368: These should be single line blocks 509 __asm { mov eax, 4+4[arr] } 510 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 511 __asm { mov eax, (4+4)[arr + 4] } 512 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 513 __asm { mov eax, 8*2[arr + 4 + 32*2 - 4] } 514 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$80]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 515 __asm { mov eax, 12+20[4 + arr] } 516 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$36]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 517 __asm { mov eax, 4*16+4[4 + arr + 4] } 518 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$76]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 519 __asm { mov eax, 4*4[64 + arr + (2*32)] } 520 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$144]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 521 __asm { mov eax, 4*(4-2)[64 + arr - 2*32] } 522 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 523 __asm { mov eax, 32*(4-2)[arr - 2*32] } 524 // CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* elementtype([4 x i32]) %{{.*}}) 525 } 526 527 void cpuid() { 528 __asm cpuid 529 // CHECK-LABEL: define{{.*}} void @cpuid 530 // CHECK: call void asm sideeffect inteldialect "cpuid", "~{eax},~{ebx},~{ecx},~{edx},~{dirflag},~{fpsr},~{flags}"() 531 } 532 533 typedef struct { 534 int a; 535 int b; 536 } A, *pA; 537 538 typedef struct { 539 int b1; 540 A b2; 541 } B; 542 543 typedef struct { 544 int c1; 545 A c2; 546 int c3; 547 B c4; 548 } C, *pC; 549 550 void t39() { 551 // CHECK-LABEL: define{{.*}} void @t39 552 __asm mov eax, [eax].A.b 553 // CHECK: mov eax, [eax + $$4] 554 __asm mov eax, [eax] A.b 555 // CHECK: mov eax, [eax + $$4] 556 __asm mov eax, [eax] pA.b 557 // CHECK: mov eax, [eax + $$4] 558 __asm mov eax, fs:[0] A.b 559 // CHECK: mov eax, fs:[$$4] 560 __asm mov eax, [eax].B.b2.a 561 // CHECK: mov eax, [eax + $$4] 562 __asm mov eax, [eax] B.b2.b 563 // CHECK: mov eax, [eax + $$8] 564 __asm mov eax, fs:[0] C.c2.b 565 // CHECK: mov eax, fs:[$$8] 566 __asm mov eax, [eax]C.c4.b2.b 567 // CHECK: mov eax, [eax + $$24] 568 __asm mov eax, [eax]pC.c4.b2.b 569 // CHECK: mov eax, [eax + $$24] 570 // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() 571 } 572 573 void t40(float a) { 574 // CHECK-LABEL: define{{.*}} void @t40 575 int i; 576 __asm fld a 577 // CHECK: fld dword ptr $1 578 __asm fistp i 579 // CHECK: fistp dword ptr $0 580 // CHECK: "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}, float* elementtype(float) %{{.*}}) 581 } 582 583 void t41(unsigned short a) { 584 // CHECK-LABEL: define{{.*}} void @t41(i16 noundef zeroext %a) 585 __asm mov cs, a; 586 // CHECK: mov cs, $0 587 __asm mov ds, a; 588 // CHECK: mov ds, $1 589 __asm mov es, a; 590 // CHECK: mov es, $2 591 __asm mov fs, a; 592 // CHECK: mov fs, $3 593 __asm mov gs, a; 594 // CHECK: mov gs, $4 595 __asm mov ss, a; 596 // CHECK: mov ss, $5 597 // CHECK: "*m,*m,*m,*m,*m,*m,~{dirflag},~{fpsr},~{flags}"(i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}, i16* {{.*}}) 598 } 599 600 void t42() { 601 // CHECK-LABEL: define{{.*}} void @t42( 602 int flags; 603 __asm mov flags, eax 604 // CHECK: mov $0, eax 605 // CHECK: "=*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %flags) 606 } 607 608 void t42b() { 609 // CHECK-LABEL: define{{.*}} void @t42b( 610 int mxcsr; 611 __asm mov mxcsr, eax 612 // CHECK: mov $0, eax 613 // CHECK: "=*m,~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %mxcsr) 614 } 615 616 void t43() { 617 // CHECK-LABEL: define{{.*}} void @t43 618 C strct; 619 // Work around PR20368: These should be single line blocks 620 __asm { mov eax, 4[strct.c1] } 621 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 622 __asm { mov eax, 4[strct.c3 + 4] } 623 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 624 __asm { mov eax, 8[strct.c2.a + 4 + 32*2 - 4] } 625 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$72]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 626 __asm { mov eax, 12[4 + strct.c2.b] } 627 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$16]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 628 __asm { mov eax, 4[4 + strct.c4.b2.b + 4] } 629 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$12]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 630 __asm { mov eax, 4[64 + strct.c1 + (2*32)] } 631 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$132]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 632 __asm { mov eax, 4[64 + strct.c2.a - 2*32] } 633 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 634 __asm { mov eax, [strct.c4.b1 + 4] } 635 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 636 __asm { mov eax, [strct.c4.b2.a + 4 + 32*2 - 4] } 637 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$64]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 638 __asm { mov eax, [4 + strct.c1] } 639 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$4]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 640 __asm { mov eax, [4 + strct.c2.b + 4] } 641 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$8]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 642 __asm { mov eax, [64 + strct.c3 + (2*32)] } 643 // CHECK: call void asm sideeffect inteldialect "mov eax, $0[$$128]", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 644 __asm { mov eax, [64 + strct.c4.b2.b - 2*32] } 645 // CHECK: call void asm sideeffect inteldialect "mov eax, $0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* elementtype(i32) %{{.*}}) 646 } 647 648 void t44() { 649 // CHECK-LABEL: define{{.*}} void @t44 650 __asm { 651 mov cr0, eax 652 mov cr2, ebx 653 mov cr3, ecx 654 mov cr4, edx 655 } 656 // 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}"() 657 } 658 659 void t45() { 660 // CHECK-LABEL: define{{.*}} void @t45 661 __asm { 662 mov dr0, eax 663 mov dr1, ebx 664 mov dr2, ebx 665 mov dr3, ecx 666 mov dr6, edx 667 mov dr7, ecx 668 } 669 // 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}"() 670 } 671 672 void t46() { 673 // CHECK-LABEL: define{{.*}} void @t46 674 __asm add eax, -128[eax] 675 // CHECK: call void asm sideeffect inteldialect "add eax, [eax + $$-128]", "~{eax},~{flags},~{dirflag},~{fpsr},~{flags}"() 676 } 677 678 void dot_operator(){ 679 // CHECK-LABEL: define{{.*}} void @dot_operator 680 __asm { mov eax, 3[ebx]A.b} 681 // CHECK: call void asm sideeffect inteldialect "mov eax, [ebx + $$7]", "~{eax},~{dirflag},~{fpsr},~{flags}" 682 } 683 684 void call_clobber() { 685 __asm call t41 686 // CHECK-LABEL: define{{.*}} void @call_clobber 687 // CHECK: call void asm sideeffect inteldialect "call dword ptr ${0:P}", "*m,~{dirflag},~{fpsr},~{flags}"(void (i16)* elementtype(void (i16)) @t41) 688 } 689 690 void xgetbv() { 691 __asm xgetbv 692 } 693 // CHECK-LABEL: define{{.*}} void @xgetbv() 694 // CHECK: call void asm sideeffect inteldialect "xgetbv", "~{eax},~{edx},~{dirflag},~{fpsr},~{flags}"() 695 696 void label1() { 697 __asm { 698 label: 699 jmp label 700 } 701 // CHECK-LABEL: define{{.*}} void @label1() 702 // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__label:\0A\09jmp {{.*}}__MSASMLABEL_.${:uid}__label", "~{dirflag},~{fpsr},~{flags}"() [[ATTR1:#[0-9]+]] 703 } 704 705 void label2() { 706 __asm { 707 jmp label 708 label: 709 } 710 // CHECK-LABEL: define{{.*}} void @label2 711 // CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:", "~{dirflag},~{fpsr},~{flags}"() 712 } 713 714 void label3() { 715 __asm { 716 label: 717 mov eax, label 718 } 719 // CHECK-LABEL: define{{.*}} void @label3 720 // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__label:\0A\09mov eax, {{.*}}__MSASMLABEL_.${:uid}__label", "~{eax},~{dirflag},~{fpsr},~{flags}"() 721 } 722 723 void label4() { 724 __asm { 725 label: 726 mov eax, [label] 727 } 728 // CHECK-LABEL: define{{.*}} void @label4 729 // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.${:uid}__label:\0A\09mov eax, {{.*}}__MSASMLABEL_.${:uid}__label", "~{eax},~{dirflag},~{fpsr},~{flags}"() 730 } 731 732 void label5() { 733 __asm { 734 jmp dollar_label$ 735 dollar_label$: 736 } 737 // CHECK-LABEL: define{{.*}} void @label5 738 // CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.${:uid}__dollar_label$$\0A\09{{.*}}__MSASMLABEL_.${:uid}__dollar_label$$:", "~{dirflag},~{fpsr},~{flags}"() 739 } 740 741 void label6(){ 742 __asm { 743 jmp short label 744 jc short label 745 jz short label 746 label: 747 } 748 // CHECK-LABEL: define{{.*}} void @label6 749 // CHECK: jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09jc {{.*}}__MSASMLABEL_.${:uid}__label\0A\09jz {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:" 750 } 751 752 // Don't include mxcsr in the clobber list. 753 void mxcsr() { 754 char buf[4096]; 755 __asm fxrstor buf 756 } 757 // CHECK-LABEL: define{{.*}} void @mxcsr 758 // CHECK: call void asm sideeffect inteldialect "fxrstor $0", "=*m,~{fpcr},~{dirflag},~{fpsr},~{flags}" 759 760 // Make sure we can find the register for the dirflag for popfd 761 void dirflag() { 762 __asm popfd 763 } 764 // CHECK-LABEL: define{{.*}} void @dirflag 765 // CHECK: call void asm sideeffect inteldialect "popfd", "~{dirflag},~{flags},~{esp},~{dirflag},~{fpsr},~{flags}" 766 767 typedef union _LARGE_INTEGER { 768 struct { 769 unsigned int LowPart; 770 unsigned int HighPart; 771 }; 772 struct { 773 unsigned int LowPart; 774 unsigned int HighPart; 775 } u; 776 unsigned long long QuadPart; 777 } LARGE_INTEGER, *PLARGE_INTEGER; 778 779 int test_indirect_field(LARGE_INTEGER LargeInteger) { 780 __asm mov eax, LargeInteger.LowPart 781 } 782 // CHECK-LABEL: define{{.*}} i32 @test_indirect_field( 783 // CHECK: call i32 asm sideeffect inteldialect "mov eax, $1", 784 785 // MS ASM containing labels must not be duplicated (PR23715). 786 // CHECK: attributes [[ATTR1]] = { 787 // CHECK-NOT: noduplicate 788 // CHECK-SAME: }{{$}} 789