Merge tag 'v3.14.25' into backport/v3.14.24-ltsi-rc1+v3.14.25/snapshot-merge.wip
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / staging / ktap / runtime / ffi / call_x86_64.S
1 /*
2  * call_x86_64.S - assembly code to call C function and handle return value
3  *
4  * This file is part of ktap by Jovi Zhangwei
5  *
6  * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
7  *
8  * ktap is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * ktap is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22
23 #ifdef __x86_64
24
25         .file "call_x86_64.S"
26         .text
27
28 /*      ffi_call_assem_x86_64(void *stack, void *temp_stack,
29  *              void *rvalue, void *func_addr, ffi_type rftype)
30  *      @stack: base address of register values and new stack
31  *      @temp_stack: stack to store temporary values
32  *      @func_addr: Function address
33  *      @rvalue: where to put return value
34  *      @rftype: FFI type of return value
35  */
36         .align 2
37         .globl  ffi_call_assem_x86_64
38         .type   ffi_call_assem_x86_64,@function
39
40 ffi_call_assem_x86_64:
41         movq    (%rsp), %rax    /* save return address */
42         /* move stuffs to temp memory region(void *temp_stack) */
43         movq    %rcx, (%rsi)    /* save pointer to return value */
44         movq    %r8, 8(%rsi)    /* save return_ffi_type */
45         movq    %rbp, 16(%rsi)  /* save %rbp */
46         movq    %rax, 24(%rsi)  /* save return address */
47         movq    %rsp, 32(%rsi)  /* save %rsp */
48         movq    %rsi, %rbp      /* point %rbp to temp memory region */
49
50         movq    %rdx, %r11      /* move function address to %r11 */
51
52         movq    %rdi, %r10      /* set %r10 point to register region */
53         movq    (%r10), %rdi    /* load registers */
54         movq    8(%r10), %rsi
55         movq    16(%r10), %rdx
56         movq    24(%r10), %rcx
57         movq    32(%r10), %r8
58         movq    40(%r10), %r9
59         xorq    %rax, %rax
60
61         leaq    48(%r10), %rsp
62
63         callq   *%r11
64
65         movq    32(%rbp), %rsp  /* restore %rsp */
66         movq    24(%rbp), %rcx  /* restore return address */
67         movq    %rcx, (%rsp)
68
69         movq    (%rbp), %rcx    /* get pointer to return value */
70         movq    8(%rbp), %r8    /* get return_ffi_type */
71         movq    16(%rbp), %rbp  /* restore rbp */
72
73         leaq    .Lreturn_table(%rip), %r11      /* start address of return_table */
74         movslq  (%r11, %r8, 8), %r11    /* fetch target address from table */
75         jmpq    *%r11                   /* jump according to value in table */
76
77         .align 8
78 .Lreturn_table:
79         .quad   .Lreturn_void           /* FFI_VOID */
80         .quad   .Lreturn_uint8          /* FFI_UINT8 */
81         .quad   .Lreturn_int8           /* FFI_INT8 */
82         .quad   .Lreturn_uint16         /* FFI_UINT16 */
83         .quad   .Lreturn_int16          /* FFI_INT16 */
84         .quad   .Lreturn_uint32         /* FFI_UINT32 */
85         .quad   .Lreturn_int32          /* FFI_INT32 */
86         .quad   .Lreturn_uint64         /* FFI_UINT64 */
87         .quad   .Lreturn_int64          /* FFI_INT64 */
88         .quad   .Lreturn_ptr            /* FFI_PTR */
89         .quad   .Lreturn_func           /* FFI_FUNC */
90         .quad   .Lreturn_struct         /* FFI_STRUCT */
91         .quad   .Lreturn_unknown        /* FFI_UNKNOWN */
92
93         .align 8
94 .Lreturn_void:
95 .Lreturn_func:
96 .Lreturn_unknown:
97         retq
98         .align 8
99 .Lreturn_uint8:
100         movzbq  %al, %rax
101         movq    %rax, (%rcx)
102         retq
103         .align 8
104 .Lreturn_int8:
105         movsbq  %al, %rax
106         movq    %rax, (%rcx)
107         retq
108         .align 8
109 .Lreturn_uint16:
110         movzwq  %ax, %rax
111         movq    %rax, (%rcx)
112         retq
113         .align 8
114 .Lreturn_int16:
115         movswq  %ax, %rax
116         movq    %rax, (%rcx)
117         retq
118         .align 8
119 .Lreturn_uint32:
120         movl    %eax, %eax
121         movq    %rax, (%rcx)
122         retq
123         .align 8
124 .Lreturn_int32:
125         movslq  %eax, %rax
126         movq    %rax, (%rcx)
127         retq
128         .align 8
129 .Lreturn_uint64:
130 .Lreturn_int64:
131 .Lreturn_ptr:
132         movq    %rax, (%rcx)
133         retq
134 /* Struct type indicates that struct is put into at most two registers,
135  * and 16 bytes space is always available
136  */
137         .align 8
138 .Lreturn_struct:
139         movq    %rax, (%rcx)
140         movq    %rdx, 8(%rcx)
141         retq
142
143 #endif /* end for __x86_64 */