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