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 Sambucint 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 Sambucint 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 Sambucint 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 Sambucvoid __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