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