| /* 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 | |