1 // REQUIRES: x86-registered-target 2 // RUN: %clang_cc1 %s -triple i386-pc-windows-msvc -fms-extensions -S -o - | FileCheck %s 3 4 // Yes, this is an assembly test from Clang, because we need to make it all the 5 // way through code generation to know if our call became a direct, pc-relative 6 // call or an indirect call through memory. 7 8 int k(int); 9 __declspec(dllimport) int kimport(int); 10 int (*kptr)(int); 11 int (*gptr())(int); 12 13 int foo() { 14 // CHECK-LABEL: _foo: 15 int (*r)(int) = gptr(); 16 17 // Simple case: direct call. 18 __asm call k; 19 // CHECK: calll _k 20 21 // Marginally harder: indirect calls, via dllimport or function pointer. 22 __asm call r; 23 // CHECK: calll *({{.*}}) 24 __asm call kimport; 25 // CHECK: calll *({{.*}}) 26 27 // Broken case: Call through a global function pointer. 28 __asm call kptr; 29 // CHECK: calll _kptr 30 // CHECK-FIXME: calll *_kptr 31 } 32 33 int bar() { 34 // CHECK-LABEL: _bar: 35 __asm jmp k; 36 // CHECK: jmp _k 37 } 38 39 int baz() { 40 // CHECK-LABEL: _baz: 41 __asm mov eax, k; 42 // CHECK: movl _k, %eax 43 __asm mov eax, kptr; 44 // CHECK: movl _kptr, %eax 45 } 46 47 // Test that this asm blob doesn't require more registers than available. This 48 // has to be an LLVM code generation test. 49 50 void __declspec(naked) naked() { 51 __asm pusha 52 __asm call k 53 __asm popa 54 __asm ret 55 // CHECK-LABEL: _naked: 56 // CHECK: pushal 57 // CHECK-NEXT: calll _k 58 // CHECK-NEXT: popal 59 // CHECK-NEXT: retl 60 } 61