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 8int k(int); 9__declspec(dllimport) int kimport(int); 10int (*kptr)(int); 11int (*gptr())(int); 12 13int 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 33int bar() { 34 // CHECK-LABEL: _bar: 35 __asm jmp k; 36 // CHECK: jmp _k 37} 38 39int 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 50void __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