DeerEngine/Deer/vendor/angelScript/src/as_callfunc_riscv64_gcc.S

140 lines
5.4 KiB
ArmAsm
Executable File

//
// AngelCode Scripting Library
// Copyright (c) 2024 Andreas Jonsson
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any
// damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any
// purpose, including commercial applications, and to alter it and
// redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented// you
// must not claim that you wrote the original software. If you use
// this software in a product, an acknowledgment in the product
// documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and
// must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
// The original version of this library can be located at:
// http://www.angelcode.com/angelscript/
//
// Andreas Jonsson
// andreas@angelcode.com
//
// Assembly routines for the 64bit RISC-V call convention used for Linux
// Compile with GCC/GAS
#if !defined(AS_MAX_PORTABILITY)
#if defined(__riscv) && defined(__LP64__)
.file "as_callfunc_riscv64_gcc.S"
.option pic
.attribute unaligned_access, 0
.attribute stack_align, 16
.text
.align 1
.globl CallRiscVFunc
.type CallRiscVFunc, @function
CallRiscVFunc:
.cfi_startproc
// Setup call stack
addi sp,sp,-336 // reserve bytes on stack (aligned to 16bytes). 256 bytes (32*8) is reserved for values that will be pushed on the stack for the function call, the rest is for local backup of registers
.cfi_def_cfa_offset 336
sd ra,328(sp) // backup return address on stack, just below original stack frame pointer
sd s0,320(sp) // backup frame pointer on stack, below return address
.cfi_offset 1, -8
.cfi_offset 8, -16
addi s0,sp,336 // load new frame pointer with the reserved space
.cfi_def_cfa 8,0
// Backup arguments on stack
// TODO: skip the backup and move them into the temp registers directly
sd a0,-24(s0) // store func arg on stack, below backup of s0
sd a1,-32(s0) // store retfloat arg on stack
sd a2,-40(s0) // store argValues arg on stack
sd a3,-48(s0) // store numRegularValues arg on stack
sd a4,-56(s0) // store numFloatValues arg on stack
sd a5,-64(s0) // store numStackValues arg on stack
ld t1,-40(s0) // load argValues arg into t1
// Load regular values into regular registers
// TODO: skip ahead to the number of generic args
ld a7,56(t1) // a7 = argValues[7]
ld a6,48(t1) // a6 = argValues[6]
ld a5,40(t1) // a5 = argValues[5]
ld a4,32(t1) // a4 = argValues[4]
ld a3,24(t1) // a3 = argValues[3]
ld a2,16(t1) // a2 = argValues[2]
ld a1,8(t1) // a1 = argValues[1]
ld a0,0(t1) // a0 = argValues[0]
// Load float values into float registers
// TODO: skip ahead to the number of float args
fld fa7,120(t1) // fa7 = argValues[15]
fld fa6,112(t1) // fa6 = argValues[14]
fld fa5,104(t1) // fa5 = argValues[13]
fld fa4,96(t1) // fa4 = argValues[12]
fld fa3,88(t1) // fa3 = argValues[11]
fld fa2,80(t1) // fa2 = argValues[10]
fld fa1,72(t1) // fa1 = argValues[9]
fld fa0,64(t1) // fa0 = argValues[8]
// Push the remaining args on the stack
addi t1,t1,128 // t1 = &argValues[16]
mv t3,sp // t3 = sp
ld t2,-64(s0) // t2 = numStackValues
beq t2,x0,.L_nomore // jump if t2 == 0
.L_next:
addi t2,t2,-1 // t2--
ld t5,0(t1) // t5 value from argValues
sd t5,0(t3) // store the value on the stack
addi t3,t3,8 // move t3 to the next slot on the stack
addi t1,t1,8 // move to the next value in argValues
bne t2,x0,.L_next // reiterate if t2 is not zero
.L_nomore:
// Call the function
ld t1,-24(s0) // load func arg to t1
jalr t1 // call the function in func arg
nop
// If the function returns a float value, then retrieve that
ld a5,-32(s0) // restore retfloat
sext.w a4,a5 // load lower 32bit word of retfloat into a4
li a5,1 // set a5 = 1
bne a4,a5,.L_nofloat // jump if a4 != 1 TODO: rewrite to compare with x0 which is hardwired to 0 so there is no need to set a5
fsd fa0,-32(s0) // store the raw returned 64bit float/double value on the stack (where retfloat was)
ld a0,-32(s0) // load the raw 64bit value into a0 for return
fsd fa1,-32(s0) // store the raw returned 64bit float/double value on the stack (where retfloat was)
ld a1,-32(s0) // load the raw 64bit value into a1 for return
.L_nofloat:
// Clean up call stack
ld ra,328(sp) // restore return address from stack
.cfi_restore 1
ld s0,320(sp) // restore frame pointer from stack
.cfi_restore 8
.cfi_def_cfa 2, 336
addi sp,sp,336 // clear reserved space from stack
.cfi_def_cfa_offset 0
jr ra
.cfi_endproc
.size CallRiscVFunc, .-CallRiscVFunc
#endif /* __riscv && __LP64__ */
#endif /* !AS_MAX_PORTABILITY */