OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libffi/] [src/] [x86/] [win64.S] - Rev 759

Go to most recent revision | Compare with Previous | Blame | View Log

#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
        
/* Constants for ffi_call_win64 */      
#define STACK 0
#define PREP_ARGS_FN 32
#define ECIF 40
#define CIF_BYTES 48
#define CIF_FLAGS 56
#define RVALUE 64
#define FN 72

/* ffi_call_win64 (void (*prep_args_fn)(char *, extended_cif *),
                   extended_cif *ecif, unsigned bytes, unsigned flags,
                   unsigned *rvalue, void (*fn)());
 */

#ifdef _MSC_VER
PUBLIC  ffi_call_win64

EXTRN   __chkstk:NEAR
EXTRN   ffi_closure_win64_inner:NEAR

_TEXT   SEGMENT

;;; ffi_closure_win64 will be called with these registers set:
;;;    rax points to 'closure'
;;;    r11 contains a bit mask that specifies which of the
;;;    first four parameters are float or double
;;;
;;; It must move the parameters passed in registers to their stack location,
;;; call ffi_closure_win64_inner for the actual work, then return the result.
;;; 
ffi_closure_win64 PROC FRAME
        ;; copy register arguments onto stack
        test    r11, 1
        jne     first_is_float  
        mov     QWORD PTR [rsp+8], rcx
        jmp     second
first_is_float:
        movlpd  QWORD PTR [rsp+8], xmm0

second:
        test    r11, 2
        jne     second_is_float 
        mov     QWORD PTR [rsp+16], rdx
        jmp     third
second_is_float:
        movlpd  QWORD PTR [rsp+16], xmm1

third:
        test    r11, 4
        jne     third_is_float  
        mov     QWORD PTR [rsp+24], r8
        jmp     fourth
third_is_float:
        movlpd  QWORD PTR [rsp+24], xmm2

fourth:
        test    r11, 8
        jne     fourth_is_float 
        mov     QWORD PTR [rsp+32], r9
        jmp     done
fourth_is_float:
        movlpd  QWORD PTR [rsp+32], xmm3

done:
        .ALLOCSTACK 40
        sub     rsp, 40
        .ENDPROLOG
        mov     rcx, rax        ; context is first parameter
        mov     rdx, rsp        ; stack is second parameter
        add     rdx, 48         ; point to start of arguments
        mov     rax, ffi_closure_win64_inner
        call    rax             ; call the real closure function
        add     rsp, 40
        movd    xmm0, rax       ; If the closure returned a float,
                                ; ffi_closure_win64_inner wrote it to rax
        ret     0
ffi_closure_win64 ENDP

ffi_call_win64 PROC FRAME
        ;; copy registers onto stack
        mov     QWORD PTR [rsp+32], r9
        mov     QWORD PTR [rsp+24], r8
        mov     QWORD PTR [rsp+16], rdx
        mov     QWORD PTR [rsp+8], rcx
        .PUSHREG rbp
        push    rbp
        .ALLOCSTACK 48
        sub     rsp, 48                                 ; 00000030H
        .SETFRAME rbp, 32
        lea     rbp, QWORD PTR [rsp+32]
        .ENDPROLOG

        mov     eax, DWORD PTR CIF_BYTES[rbp]
        add     rax, 15
        and     rax, -16
        call    __chkstk
        sub     rsp, rax
        lea     rax, QWORD PTR [rsp+32]
        mov     QWORD PTR STACK[rbp], rax

        mov     rdx, QWORD PTR ECIF[rbp]
        mov     rcx, QWORD PTR STACK[rbp]
        call    QWORD PTR PREP_ARGS_FN[rbp]

        mov     rsp, QWORD PTR STACK[rbp]

        movlpd  xmm3, QWORD PTR [rsp+24]
        movd    r9, xmm3

        movlpd  xmm2, QWORD PTR [rsp+16]
        movd    r8, xmm2

        movlpd  xmm1, QWORD PTR [rsp+8]
        movd    rdx, xmm1

        movlpd  xmm0, QWORD PTR [rsp]
        movd    rcx, xmm0

        call    QWORD PTR FN[rbp]
ret_struct4b$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_4B
        jne     ret_struct2b$

        mov     rcx, QWORD PTR RVALUE[rbp]
        mov     DWORD PTR [rcx], eax
        jmp     ret_void$

ret_struct2b$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_2B
        jne     ret_struct1b$

        mov     rcx, QWORD PTR RVALUE[rbp]
        mov     WORD PTR [rcx], ax
        jmp     ret_void$

ret_struct1b$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_1B
        jne     ret_uint8$

        mov     rcx, QWORD PTR RVALUE[rbp]
        mov     BYTE PTR [rcx], al
        jmp     ret_void$

ret_uint8$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT8
        jne     ret_sint8$

        mov     rcx, QWORD PTR RVALUE[rbp]
        movzx   rax, al
        mov     QWORD PTR [rcx], rax
        jmp     ret_void$

ret_sint8$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT8
        jne     ret_uint16$

        mov     rcx, QWORD PTR RVALUE[rbp]
        movsx   rax, al
        mov     QWORD PTR [rcx], rax
        jmp     ret_void$

ret_uint16$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT16
        jne     ret_sint16$

        mov     rcx, QWORD PTR RVALUE[rbp]
        movzx   rax, ax
        mov     QWORD PTR [rcx], rax
        jmp     SHORT ret_void$

ret_sint16$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT16
        jne     ret_uint32$

        mov     rcx, QWORD PTR RVALUE[rbp]
        movsx   rax, ax
        mov     QWORD PTR [rcx], rax
        jmp     SHORT ret_void$

ret_uint32$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT32
        jne     ret_sint32$

        mov     rcx, QWORD PTR RVALUE[rbp]
        mov     eax, eax
        mov     QWORD PTR [rcx], rax
        jmp     SHORT ret_void$

ret_sint32$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT32
        jne     ret_float$

        mov     rcx, QWORD PTR RVALUE[rbp]
        cdqe
        mov     QWORD PTR [rcx], rax
        jmp     SHORT ret_void$

ret_float$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_FLOAT
        jne     SHORT ret_double$

        mov     rax, QWORD PTR RVALUE[rbp]
        movss   DWORD PTR [rax], xmm0
        jmp     SHORT ret_void$

ret_double$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_DOUBLE
        jne     SHORT ret_sint64$

        mov     rax, QWORD PTR RVALUE[rbp]
        movlpd  QWORD PTR [rax], xmm0
        jmp     SHORT ret_void$

ret_sint64$:
        cmp     DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT64
        jne     ret_void$

        mov     rcx, QWORD PTR RVALUE[rbp]
        mov     QWORD PTR [rcx], rax
        jmp     SHORT ret_void$
        
ret_void$:
        xor     rax, rax

        lea     rsp, QWORD PTR [rbp+16]
        pop     rbp
        ret     0
ffi_call_win64 ENDP
_TEXT   ENDS
END
#else        
.text

.extern _ffi_closure_win64_inner

# ffi_closure_win64 will be called with these registers set:
#    rax points to 'closure'
#    r11 contains a bit mask that specifies which of the
#    first four parameters are float or double
#
# It must move the parameters passed in registers to their stack location,
# call ffi_closure_win64_inner for the actual work, then return the result.
# 
        .balign 16
        .globl _ffi_closure_win64       
_ffi_closure_win64:     
        # copy register arguments onto stack
        test    $1,%r11
        jne     .Lfirst_is_float        
        mov     %rcx, 8(%rsp)
        jmp     .Lsecond
.Lfirst_is_float:
        movlpd  %xmm0, 8(%rsp)

.Lsecond:
        test    $2, %r11
        jne     .Lsecond_is_float       
        mov     %rdx, 16(%rsp)
        jmp     .Lthird
.Lsecond_is_float:
        movlpd  %xmm1, 16(%rsp)

.Lthird:
        test    $4, %r11
        jne     .Lthird_is_float        
        mov     %r8,24(%rsp)
        jmp     .Lfourth
.Lthird_is_float:
        movlpd  %xmm2, 24(%rsp)

.Lfourth:
        test    $8, %r11
        jne     .Lfourth_is_float       
        mov     %r9, 32(%rsp)
        jmp     .Ldone
.Lfourth_is_float:
        movlpd  %xmm3, 32(%rsp)

.Ldone:
#.ALLOCSTACK 40
        sub     $40, %rsp
#.ENDPROLOG
        mov     %rax, %rcx      # context is first parameter
        mov     %rsp, %rdx      # stack is second parameter
        add     $48, %rdx       # point to start of arguments
        mov     $_ffi_closure_win64_inner, %rax
        callq   *%rax           # call the real closure function
        add     $40, %rsp
        movq    %rax, %xmm0     # If the closure returned a float,
                                # ffi_closure_win64_inner wrote it to rax
        retq
.ffi_closure_win64_end:

        .balign 16
        .globl  _ffi_call_win64
_ffi_call_win64:        
        # copy registers onto stack
        mov     %r9,32(%rsp)
        mov     %r8,24(%rsp)
        mov     %rdx,16(%rsp)
        mov     %rcx,8(%rsp)
        #.PUSHREG rbp
        push    %rbp
        #.ALLOCSTACK 48
        sub     $48,%rsp
        #.SETFRAME rbp, 32
        lea     32(%rsp),%rbp
        #.ENDPROLOG

        mov     CIF_BYTES(%rbp),%eax
        add     $15, %rax
        and     $-16, %rax
        cmpq    $0x1000, %rax
        jb      Lch_done
Lch_probe:
        subq    $0x1000,%rsp
        orl     $0x0, (%rsp)
        subq    $0x1000,%rax
        cmpq    $0x1000,%rax
        ja      Lch_probe
Lch_done:
        subq    %rax, %rsp
        orl     $0x0, (%rsp)
        lea     32(%rsp), %rax
        mov     %rax, STACK(%rbp)

        mov     ECIF(%rbp), %rdx
        mov     STACK(%rbp), %rcx
        callq   *PREP_ARGS_FN(%rbp)

        mov     STACK(%rbp), %rsp

        movlpd  24(%rsp), %xmm3
        movd    %xmm3, %r9

        movlpd  16(%rsp), %xmm2
        movd    %xmm2, %r8

        movlpd  8(%rsp), %xmm1
        movd    %xmm1, %rdx

        movlpd  (%rsp), %xmm0
        movd    %xmm0, %rcx

        callq   *FN(%rbp)
.Lret_struct4b:
        cmpl    $FFI_TYPE_SMALL_STRUCT_4B, CIF_FLAGS(%rbp)
        jne .Lret_struct2b

        mov     RVALUE(%rbp), %rcx
        mov     %eax, (%rcx)
        jmp     .Lret_void

.Lret_struct2b:
        cmpl    $FFI_TYPE_SMALL_STRUCT_2B, CIF_FLAGS(%rbp)
        jne .Lret_struct1b
        
        mov     RVALUE(%rbp), %rcx
        mov     %ax, (%rcx)
        jmp .Lret_void
        
.Lret_struct1b:
        cmpl    $FFI_TYPE_SMALL_STRUCT_1B, CIF_FLAGS(%rbp)
        jne .Lret_uint8
        
        mov     RVALUE(%rbp), %rcx
        mov     %al, (%rcx)
        jmp .Lret_void

.Lret_uint8:
        cmpl    $FFI_TYPE_UINT8, CIF_FLAGS(%rbp)
        jne .Lret_sint8
        
        mov     RVALUE(%rbp), %rcx
        movzbq  %al, %rax
        movq    %rax, (%rcx)
        jmp .Lret_void

.Lret_sint8:
        cmpl    $FFI_TYPE_SINT8, CIF_FLAGS(%rbp)
        jne .Lret_uint16
        
        mov     RVALUE(%rbp), %rcx
        movsbq  %al, %rax
        movq    %rax, (%rcx)
        jmp .Lret_void

.Lret_uint16:
        cmpl    $FFI_TYPE_UINT16, CIF_FLAGS(%rbp)
        jne .Lret_sint16
        
        mov     RVALUE(%rbp), %rcx
        movzwq  %ax, %rax
        movq    %rax, (%rcx)
        jmp .Lret_void

.Lret_sint16:
        cmpl    $FFI_TYPE_SINT16, CIF_FLAGS(%rbp)
        jne .Lret_uint32
        
        mov     RVALUE(%rbp), %rcx
        movswq  %ax, %rax
        movq    %rax, (%rcx)
        jmp .Lret_void

.Lret_uint32:
        cmpl    $FFI_TYPE_UINT32, CIF_FLAGS(%rbp)
        jne .Lret_sint32
        
        mov     RVALUE(%rbp), %rcx
        movl    %eax, %eax
        movq    %rax, (%rcx)
        jmp .Lret_void

.Lret_sint32:
        cmpl    $FFI_TYPE_SINT32, CIF_FLAGS(%rbp)
        jne     .Lret_float

        mov     RVALUE(%rbp), %rcx
        cltq
        movq    %rax, (%rcx)
        jmp     .Lret_void

.Lret_float:
        cmpl    $FFI_TYPE_FLOAT, CIF_FLAGS(%rbp)
        jne     .Lret_double

        mov     RVALUE(%rbp), %rax
        movss   %xmm0, (%rax)
        jmp     .Lret_void

.Lret_double:
        cmpl    $FFI_TYPE_DOUBLE, CIF_FLAGS(%rbp)
        jne     .Lret_sint64

        mov     RVALUE(%rbp), %rax
        movlpd  %xmm0, (%rax)
        jmp     .Lret_void

.Lret_sint64:
        cmpl    $FFI_TYPE_SINT64, CIF_FLAGS(%rbp)
        jne     .Lret_void

        mov     RVALUE(%rbp), %rcx
        mov     %rax, (%rcx)
        jmp     .Lret_void
        
.Lret_void:
        xor     %rax, %rax

        lea     16(%rbp), %rsp
        pop     %rbp
        retq
.ffi_call_win64_end:
#endif /* !_MSC_VER */

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.