blob: 1a6ead9286dff2efb04e79a4958a4aa3194ca152 [file] [log] [blame]
// 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
}