| /* Copyright (c) 2020 Kalray |
| |
| Permission is hereby granted, free of charge, to any person obtaining |
| a copy of this software and associated documentation files (the |
| ``Software''), to deal in the Software without restriction, including |
| without limitation the rights to use, copy, modify, merge, publish, |
| distribute, sublicense, and/or sell copies of the Software, and to |
| permit persons to whom the Software is furnished to do so, subject to |
| the following conditions: |
| |
| The above copyright notice and this permission notice shall be |
| included in all copies or substantial portions of the Software. |
| |
| THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, |
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
| |
| #if defined(__kvx__) |
| #define LIBFFI_ASM |
| #include <fficonfig.h> |
| #include <ffi.h> |
| #include <ffi_cfi.h> |
| #include <kvx/asm.h> |
| |
| .text |
| .global ffi_call_SYSV |
| .type ffi_call_SYSV, @function |
| .type ffi_prep_args, @function |
| .align 8 |
| |
| /* ffi_call_SYSV |
| |
| r0: total size to allocate on stack |
| r1: size of arg slots |
| r2: extended cif structure, DO NOT REMOVE: it is used by ffi_prep_args() |
| r3: return value address |
| r4: function to call |
| r5: integer sign extension method to be used |
| */ |
| ffi_call_SYSV: |
| addd $r12 = $r12, -64 |
| so (-32)[$r12] = $r20r21r22r23 |
| ;; |
| sd (0)[$r12] = $r24 |
| ;; |
| get $r23 = $ra |
| copyd $r20 = $r12 |
| sbfd $r12 = $r0, $r12 |
| ;; |
| copyd $r0 = $r12 |
| copyd $r21 = $r3 |
| copyd $r22 = $r4 |
| copyd $r24 = $r5 |
| call ffi_prep_args |
| ;; |
| lo $r8r9r10r11 = (64)[$r12] |
| ;; |
| lo $r4r5r6r7 = (32)[$r12] |
| ;; |
| lo $r0r1r2r3 = (0)[$r12] |
| copyd $r12 = $r0 |
| /* $r15 is the register used by the ABI to return big (>32 bytes) |
| * structs by value. |
| * It is also referred to as the "struct register" in the ABI. |
| */ |
| copyd $r15 = $r21 |
| icall $r22 |
| ;; |
| pcrel $r4 = @pcrel(.Ltable) |
| cb.deqz $r24 ? .Lend |
| ;; |
| addx8d $r24 = $r24, $r4 |
| ;; |
| igoto $r24 |
| ;; |
| .Ltable: |
| 0: /* we should never arrive here */ |
| goto .Lerror |
| nop |
| ;; |
| 1: /* Sign extend byte to double */ |
| sxbd $r0 = $r0 |
| goto .Lend |
| ;; |
| 2: /* Sign extend half to double */ |
| sxhd $r0 = $r0 |
| goto .Lend |
| ;; |
| 3: /* Sign extend word to double */ |
| sxwd $r0 = $r0 |
| goto .Lend |
| ;; |
| 4: /* Zero extend byte to double */ |
| zxbd $r0 = $r0 |
| goto .Lend |
| ;; |
| 5: /* Zero extend half to double */ |
| zxhd $r0 = $r0 |
| goto .Lend |
| ;; |
| 6: /* Zero extend word to double */ |
| zxwd $r0 = $r0 |
| /* Fallthrough to .Lend */ |
| ;; |
| .Lend: |
| ld $r24 = (0)[$r12] |
| ;; |
| set $ra = $r23 |
| lo $r20r21r22r23 = (32)[$r20] |
| addd $r12 = $r20, 64 |
| ;; |
| ret |
| ;; |
| .Lerror: |
| errop |
| ;; |
| |
| #endif /* __kvx__ */ |
| |
| #if defined __ELF__ && defined __linux__ |
| .section .note.GNU-stack,"",%progbits |
| #endif |
| |