150
|
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 }
|