forked from OSchip/llvm-project
[X86] Properly implement the calling convention for f80 for mingw/x86_64
In these cases, both parameters and return values are passed as a pointer to a stack allocation. MSVC doesn't use the f80 data type at all, while it is used for long doubles on mingw. Normally, this part of the calling convention is handled within clang, but for intrinsics that are lowered to libcalls, it may need to be handled within llvm as well. Differential Revision: https://reviews.llvm.org/D44592 llvm-svn: 327957
This commit is contained in:
parent
2c83285716
commit
802b434156
|
@ -18,6 +18,12 @@ class CCIfSubtarget<string F, CCAction A>
|
|||
"(State.getMachineFunction().getSubtarget()).", F),
|
||||
A>;
|
||||
|
||||
/// CCIfNotSubtarget - Match if the current subtarget doesn't has a feature F.
|
||||
class CCIfNotSubtarget<string F, CCAction A>
|
||||
: CCIf<!strconcat("!static_cast<const X86Subtarget&>"
|
||||
"(State.getMachineFunction().getSubtarget()).", F),
|
||||
A>;
|
||||
|
||||
// Register classes for RegCall
|
||||
class RC_X86_RegCall {
|
||||
list<Register> GPR_8 = [];
|
||||
|
@ -246,8 +252,9 @@ def RetCC_X86Common : CallingConv<[
|
|||
// MM0, it doesn't support these vector types.
|
||||
CCIfType<[x86mmx], CCAssignToReg<[MM0]>>,
|
||||
|
||||
// Long double types are always returned in FP0 (even with SSE).
|
||||
CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>
|
||||
// Long double types are always returned in FP0 (even with SSE),
|
||||
// except on Win64.
|
||||
CCIfNotSubtarget<"isTargetWin64()", CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>
|
||||
]>;
|
||||
|
||||
// X86-32 C return-value convention.
|
||||
|
@ -605,6 +612,9 @@ def CC_X86_Win64_C : CallingConv<[
|
|||
// 512 bit vectors are passed by pointer
|
||||
CCIfType<[v16i32, v16f32, v8f64, v8i64], CCPassIndirect<i64>>,
|
||||
|
||||
// Long doubles are passed by pointer
|
||||
CCIfType<[f80], CCPassIndirect<i64>>,
|
||||
|
||||
// The first 4 MMX vector arguments are passed in GPRs.
|
||||
CCIfType<[x86mmx], CCBitConvertToType<i64>>,
|
||||
|
||||
|
@ -628,11 +638,7 @@ def CC_X86_Win64_C : CallingConv<[
|
|||
|
||||
// Integer/FP values get stored in stack slots that are 8 bytes in size and
|
||||
// 8-byte aligned if there are no more registers to hold them.
|
||||
CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>,
|
||||
|
||||
// Long doubles get stack slots whose size and alignment depends on the
|
||||
// subtarget.
|
||||
CCIfType<[f80], CCAssignToStack<0, 0>>
|
||||
CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>
|
||||
]>;
|
||||
|
||||
def CC_X86_Win64_VectorCall : CallingConv<[
|
||||
|
|
|
@ -50,11 +50,19 @@ define x86_fp80 @exp_f80(x86_fp80 %x) #0 {
|
|||
;
|
||||
; WIN-LABEL: exp_f80:
|
||||
; WIN: # %bb.0:
|
||||
; WIN-NEXT: subq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: pushq %rsi
|
||||
; WIN-NEXT: subq $64, %rsp
|
||||
; WIN-NEXT: movq %rcx, %rsi
|
||||
; WIN-NEXT: fldt (%rdx)
|
||||
; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rdx
|
||||
; WIN-NEXT: callq expl
|
||||
; WIN-NEXT: addq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: fstpt (%rsi)
|
||||
; WIN-NEXT: movq %rsi, %rax
|
||||
; WIN-NEXT: addq $64, %rsp
|
||||
; WIN-NEXT: popq %rsi
|
||||
; WIN-NEXT: retq
|
||||
;
|
||||
; MAC-LABEL: exp_f80:
|
||||
|
@ -113,11 +121,19 @@ define x86_fp80 @exp2_f80(x86_fp80 %x) #0 {
|
|||
;
|
||||
; WIN-LABEL: exp2_f80:
|
||||
; WIN: # %bb.0:
|
||||
; WIN-NEXT: subq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: pushq %rsi
|
||||
; WIN-NEXT: subq $64, %rsp
|
||||
; WIN-NEXT: movq %rcx, %rsi
|
||||
; WIN-NEXT: fldt (%rdx)
|
||||
; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rdx
|
||||
; WIN-NEXT: callq exp2l
|
||||
; WIN-NEXT: addq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: fstpt (%rsi)
|
||||
; WIN-NEXT: movq %rsi, %rax
|
||||
; WIN-NEXT: addq $64, %rsp
|
||||
; WIN-NEXT: popq %rsi
|
||||
; WIN-NEXT: retq
|
||||
;
|
||||
; MAC-LABEL: exp2_f80:
|
||||
|
@ -176,11 +192,19 @@ define x86_fp80 @log_f80(x86_fp80 %x) #0 {
|
|||
;
|
||||
; WIN-LABEL: log_f80:
|
||||
; WIN: # %bb.0:
|
||||
; WIN-NEXT: subq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: pushq %rsi
|
||||
; WIN-NEXT: subq $64, %rsp
|
||||
; WIN-NEXT: movq %rcx, %rsi
|
||||
; WIN-NEXT: fldt (%rdx)
|
||||
; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rdx
|
||||
; WIN-NEXT: callq logl
|
||||
; WIN-NEXT: addq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: fstpt (%rsi)
|
||||
; WIN-NEXT: movq %rsi, %rax
|
||||
; WIN-NEXT: addq $64, %rsp
|
||||
; WIN-NEXT: popq %rsi
|
||||
; WIN-NEXT: retq
|
||||
;
|
||||
; MAC-LABEL: log_f80:
|
||||
|
@ -239,11 +263,19 @@ define x86_fp80 @log2_f80(x86_fp80 %x) #0 {
|
|||
;
|
||||
; WIN-LABEL: log2_f80:
|
||||
; WIN: # %bb.0:
|
||||
; WIN-NEXT: subq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: pushq %rsi
|
||||
; WIN-NEXT: subq $64, %rsp
|
||||
; WIN-NEXT: movq %rcx, %rsi
|
||||
; WIN-NEXT: fldt (%rdx)
|
||||
; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rdx
|
||||
; WIN-NEXT: callq log2l
|
||||
; WIN-NEXT: addq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: fstpt (%rsi)
|
||||
; WIN-NEXT: movq %rsi, %rax
|
||||
; WIN-NEXT: addq $64, %rsp
|
||||
; WIN-NEXT: popq %rsi
|
||||
; WIN-NEXT: retq
|
||||
;
|
||||
; MAC-LABEL: log2_f80:
|
||||
|
@ -302,11 +334,19 @@ define x86_fp80 @log10_f80(x86_fp80 %x) #0 {
|
|||
;
|
||||
; WIN-LABEL: log10_f80:
|
||||
; WIN: # %bb.0:
|
||||
; WIN-NEXT: subq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: pushq %rsi
|
||||
; WIN-NEXT: subq $64, %rsp
|
||||
; WIN-NEXT: movq %rcx, %rsi
|
||||
; WIN-NEXT: fldt (%rdx)
|
||||
; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rdx
|
||||
; WIN-NEXT: callq log10l
|
||||
; WIN-NEXT: addq $56, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: fstpt (%rsi)
|
||||
; WIN-NEXT: movq %rsi, %rax
|
||||
; WIN-NEXT: addq $64, %rsp
|
||||
; WIN-NEXT: popq %rsi
|
||||
; WIN-NEXT: retq
|
||||
;
|
||||
; MAC-LABEL: log10_f80:
|
||||
|
@ -373,13 +413,22 @@ define x86_fp80 @pow_f80(x86_fp80 %x) #0 {
|
|||
;
|
||||
; WIN-LABEL: pow_f80:
|
||||
; WIN: # %bb.0:
|
||||
; WIN-NEXT: subq $72, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: pushq %rsi
|
||||
; WIN-NEXT: subq $80, %rsp
|
||||
; WIN-NEXT: movq %rcx, %rsi
|
||||
; WIN-NEXT: fldt (%rdx)
|
||||
; WIN-NEXT: fld %st(0)
|
||||
; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: fstpt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rcx
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %rdx
|
||||
; WIN-NEXT: leaq {{[0-9]+}}(%rsp), %r8
|
||||
; WIN-NEXT: callq powl
|
||||
; WIN-NEXT: addq $72, %rsp
|
||||
; WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; WIN-NEXT: fstpt (%rsi)
|
||||
; WIN-NEXT: movq %rsi, %rax
|
||||
; WIN-NEXT: addq $80, %rsp
|
||||
; WIN-NEXT: popq %rsi
|
||||
; WIN-NEXT: retq
|
||||
;
|
||||
; MAC-LABEL: pow_f80:
|
||||
|
|
|
@ -918,7 +918,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind {
|
|||
; AVX512_64_WIN-LABEL: x_to_u64:
|
||||
; AVX512_64_WIN: # %bb.0:
|
||||
; AVX512_64_WIN-NEXT: pushq %rax
|
||||
; AVX512_64_WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; AVX512_64_WIN-NEXT: fldt (%rcx)
|
||||
; AVX512_64_WIN-NEXT: flds __real@{{.*}}(%rip)
|
||||
; AVX512_64_WIN-NEXT: fld %st(1)
|
||||
; AVX512_64_WIN-NEXT: fsub %st(1)
|
||||
|
@ -1003,25 +1003,25 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind {
|
|||
;
|
||||
; SSE3_64_WIN-LABEL: x_to_u64:
|
||||
; SSE3_64_WIN: # %bb.0:
|
||||
; SSE3_64_WIN-NEXT: subq $24, %rsp
|
||||
; SSE3_64_WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; SSE3_64_WIN-NEXT: subq $16, %rsp
|
||||
; SSE3_64_WIN-NEXT: fldt (%rcx)
|
||||
; SSE3_64_WIN-NEXT: flds __real@{{.*}}(%rip)
|
||||
; SSE3_64_WIN-NEXT: fld %st(1)
|
||||
; SSE3_64_WIN-NEXT: fsub %st(1)
|
||||
; SSE3_64_WIN-NEXT: fisttpll {{[0-9]+}}(%rsp)
|
||||
; SSE3_64_WIN-NEXT: fld %st(1)
|
||||
; SSE3_64_WIN-NEXT: fisttpll {{[0-9]+}}(%rsp)
|
||||
; SSE3_64_WIN-NEXT: fisttpll (%rsp)
|
||||
; SSE3_64_WIN-NEXT: fucompi %st(1)
|
||||
; SSE3_64_WIN-NEXT: fstp %st(0)
|
||||
; SSE3_64_WIN-NEXT: jbe .LBB4_1
|
||||
; SSE3_64_WIN-NEXT: # %bb.2:
|
||||
; SSE3_64_WIN-NEXT: movq {{[0-9]+}}(%rsp), %rax
|
||||
; SSE3_64_WIN-NEXT: addq $24, %rsp
|
||||
; SSE3_64_WIN-NEXT: movq (%rsp), %rax
|
||||
; SSE3_64_WIN-NEXT: addq $16, %rsp
|
||||
; SSE3_64_WIN-NEXT: retq
|
||||
; SSE3_64_WIN-NEXT: .LBB4_1:
|
||||
; SSE3_64_WIN-NEXT: movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
|
||||
; SSE3_64_WIN-NEXT: xorq {{[0-9]+}}(%rsp), %rax
|
||||
; SSE3_64_WIN-NEXT: addq $24, %rsp
|
||||
; SSE3_64_WIN-NEXT: addq $16, %rsp
|
||||
; SSE3_64_WIN-NEXT: retq
|
||||
;
|
||||
; SSE3_64_LIN-LABEL: x_to_u64:
|
||||
|
@ -1103,7 +1103,7 @@ define i64 @x_to_u64(x86_fp80 %a) nounwind {
|
|||
; SSE2_64_WIN-LABEL: x_to_u64:
|
||||
; SSE2_64_WIN: # %bb.0:
|
||||
; SSE2_64_WIN-NEXT: subq $24, %rsp
|
||||
; SSE2_64_WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; SSE2_64_WIN-NEXT: fldt (%rcx)
|
||||
; SSE2_64_WIN-NEXT: flds __real@{{.*}}(%rip)
|
||||
; SSE2_64_WIN-NEXT: fld %st(1)
|
||||
; SSE2_64_WIN-NEXT: fsub %st(1)
|
||||
|
@ -1268,7 +1268,7 @@ define i64 @x_to_s64(x86_fp80 %a) nounwind {
|
|||
; AVX512_64_WIN-LABEL: x_to_s64:
|
||||
; AVX512_64_WIN: # %bb.0:
|
||||
; AVX512_64_WIN-NEXT: pushq %rax
|
||||
; AVX512_64_WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; AVX512_64_WIN-NEXT: fldt (%rcx)
|
||||
; AVX512_64_WIN-NEXT: fisttpll (%rsp)
|
||||
; AVX512_64_WIN-NEXT: movq (%rsp), %rax
|
||||
; AVX512_64_WIN-NEXT: popq %rcx
|
||||
|
@ -1308,7 +1308,7 @@ define i64 @x_to_s64(x86_fp80 %a) nounwind {
|
|||
; SSE3_64_WIN-LABEL: x_to_s64:
|
||||
; SSE3_64_WIN: # %bb.0:
|
||||
; SSE3_64_WIN-NEXT: pushq %rax
|
||||
; SSE3_64_WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; SSE3_64_WIN-NEXT: fldt (%rcx)
|
||||
; SSE3_64_WIN-NEXT: fisttpll (%rsp)
|
||||
; SSE3_64_WIN-NEXT: movq (%rsp), %rax
|
||||
; SSE3_64_WIN-NEXT: popq %rcx
|
||||
|
@ -1359,8 +1359,8 @@ define i64 @x_to_s64(x86_fp80 %a) nounwind {
|
|||
;
|
||||
; SSE2_64_WIN-LABEL: x_to_s64:
|
||||
; SSE2_64_WIN: # %bb.0:
|
||||
; SSE2_64_WIN-NEXT: subq $24, %rsp
|
||||
; SSE2_64_WIN-NEXT: fldt {{[0-9]+}}(%rsp)
|
||||
; SSE2_64_WIN-NEXT: subq $16, %rsp
|
||||
; SSE2_64_WIN-NEXT: fldt (%rcx)
|
||||
; SSE2_64_WIN-NEXT: fnstcw {{[0-9]+}}(%rsp)
|
||||
; SSE2_64_WIN-NEXT: movzwl {{[0-9]+}}(%rsp), %eax
|
||||
; SSE2_64_WIN-NEXT: movw $3199, {{[0-9]+}}(%rsp) # imm = 0xC7F
|
||||
|
@ -1369,7 +1369,7 @@ define i64 @x_to_s64(x86_fp80 %a) nounwind {
|
|||
; SSE2_64_WIN-NEXT: fistpll {{[0-9]+}}(%rsp)
|
||||
; SSE2_64_WIN-NEXT: fldcw {{[0-9]+}}(%rsp)
|
||||
; SSE2_64_WIN-NEXT: movq {{[0-9]+}}(%rsp), %rax
|
||||
; SSE2_64_WIN-NEXT: addq $24, %rsp
|
||||
; SSE2_64_WIN-NEXT: addq $16, %rsp
|
||||
; SSE2_64_WIN-NEXT: retq
|
||||
;
|
||||
; SSE2_64_LIN-LABEL: x_to_s64:
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
; RUN: llc -mtriple x86_64-w64-mingw32 %s -o - | FileCheck %s
|
||||
|
||||
@glob = common dso_local local_unnamed_addr global x86_fp80 0xK00000000000000000000, align 16
|
||||
|
||||
define dso_local void @call() {
|
||||
entry:
|
||||
%0 = load x86_fp80, x86_fp80* @glob, align 16
|
||||
%1 = tail call x86_fp80 @floorl(x86_fp80 %0)
|
||||
store x86_fp80 %1, x86_fp80* @glob, align 16
|
||||
ret void
|
||||
}
|
||||
|
||||
declare x86_fp80 @floorl(x86_fp80)
|
||||
|
||||
; CHECK-LABEL: call
|
||||
; CHECK: fldt glob(%rip)
|
||||
; CHECK: fstpt [[ARGOFF:[0-9]+]](%rsp)
|
||||
; CHECK: leaq [[RETOFF:[0-9]+]](%rsp), %rcx
|
||||
; CHECK: leaq [[ARGOFF]](%rsp), %rdx
|
||||
; CHECK: callq floorl
|
||||
; CHECK: fldt [[RETOFF]](%rsp)
|
||||
; CHECK: fstpt glob(%rip)
|
Loading…
Reference in New Issue