diff options
Diffstat (limited to 'test/CodeGen/ms-inline-asm-functions.c')
-rw-r--r-- | test/CodeGen/ms-inline-asm-functions.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/test/CodeGen/ms-inline-asm-functions.c b/test/CodeGen/ms-inline-asm-functions.c new file mode 100644 index 0000000..1a6ead9 --- /dev/null +++ b/test/CodeGen/ms-inline-asm-functions.c @@ -0,0 +1,60 @@ +// REQUIRES: x86-registered-target +// RUN: %clang_cc1 %s -triple i386-pc-windows-msvc -fms-extensions -S -o - | FileCheck %s + +// Yes, this is an assembly test from Clang, because we need to make it all the +// way through code generation to know if our call became a direct, pc-relative +// call or an indirect call through memory. + +int k(int); +__declspec(dllimport) int kimport(int); +int (*kptr)(int); +int (*gptr())(int); + +int foo() { + // CHECK-LABEL: _foo: + int (*r)(int) = gptr(); + + // Simple case: direct call. + __asm call k; + // CHECK: calll _k + + // Marginally harder: indirect calls, via dllimport or function pointer. + __asm call r; + // CHECK: calll *({{.*}}) + __asm call kimport; + // CHECK: calll *({{.*}}) + + // Broken case: Call through a global function pointer. + __asm call kptr; + // CHECK: calll _kptr + // CHECK-FIXME: calll *_kptr +} + +int bar() { + // CHECK-LABEL: _bar: + __asm jmp k; + // CHECK: jmp _k +} + +int baz() { + // CHECK-LABEL: _baz: + __asm mov eax, k; + // CHECK: movl _k, %eax + __asm mov eax, kptr; + // CHECK: movl _kptr, %eax +} + +// Test that this asm blob doesn't require more registers than available. This +// has to be an LLVM code generation test. + +void __declspec(naked) naked() { + __asm pusha + __asm call k + __asm popa + __asm ret + // CHECK-LABEL: _naked: + // CHECK: pushal + // CHECK-NEXT: calll _k + // CHECK-NEXT: popal + // CHECK-NEXT: retl +} |