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