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