mirror of
https://github.com/corda/corda.git
synced 2025-03-22 12:05:59 +00:00
sketch vmNativeCall implementation for powerpc
This commit is contained in:
parent
ca6215c720
commit
4b67adaa0a
122
src/powerpc.S
122
src/powerpc.S
@ -12,6 +12,7 @@
|
||||
|
||||
.text
|
||||
|
||||
BytesPerWord = 4
|
||||
LinkageArea = 24
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -24,35 +25,118 @@ vmNativeCall:
|
||||
// save return address
|
||||
mflr r0
|
||||
stw r0,8(r1)
|
||||
|
||||
// r3 aka 24(r1): function
|
||||
// r4 aka 28(r1): stack
|
||||
// r5 aka 32(r1): stackSize
|
||||
// r6 aka 36(r1): gprTable
|
||||
// r7 aka 40(r1): fprTable
|
||||
// r8 aka 48(r1): returnType
|
||||
|
||||
// r3 aka r13: function
|
||||
// r4 : stackTotal
|
||||
// r5 : memoryTable
|
||||
// r6 : memoryCount
|
||||
// r7 : gprTable
|
||||
// r8 : fprTable
|
||||
// r9 aka r14: returnType
|
||||
|
||||
// r15 : stack frame size
|
||||
// r16 : temporary
|
||||
// r17 : temporary
|
||||
|
||||
// save registers used for local variables
|
||||
stw r13,24(r1)
|
||||
stw r14,28(r1)
|
||||
stw r15,32(r1)
|
||||
stw r16,36(r1)
|
||||
stw r17,40(r1)
|
||||
|
||||
// calculate aligned stack frame size
|
||||
add r13,r5,LinkageArea + 15
|
||||
and r13,r13,-16
|
||||
add r15,r4,LinkageArea + LocalArea + 15
|
||||
and r15,r15,-16
|
||||
|
||||
// save and update stack pointer
|
||||
sub r14,r1,r9
|
||||
stwu r1,r14
|
||||
sub r16,r1,r15
|
||||
stwu r16,(r1)
|
||||
|
||||
// save our argument registers so we can clobber them
|
||||
stw r3,24(r1)
|
||||
stw r4,28(r1)
|
||||
stw r5,32(r1)
|
||||
stw r6,36(r1)
|
||||
stw r7,40(r1)
|
||||
stw r8,48(r1)
|
||||
|
||||
// todo
|
||||
mr r13,r3
|
||||
mr r14,r9
|
||||
|
||||
li r16,0
|
||||
b test
|
||||
|
||||
loop:
|
||||
lwzx r17,r16,r5
|
||||
stwx r17,r16,r1
|
||||
add r16,r16,BytesPerWord
|
||||
|
||||
test:
|
||||
cmp r16,r6
|
||||
blt loop
|
||||
|
||||
// do we need to load the floating point registers?
|
||||
cmp r8,0
|
||||
be gpr
|
||||
|
||||
// yes, we do
|
||||
lfd fr1,0(r8)
|
||||
lfd fr2,8(r8)
|
||||
lfd fr3,16(r8)
|
||||
lfd fr4,24(r8)
|
||||
lfd fr5,32(r8)
|
||||
lfd fr6,40(r8)
|
||||
lfd fr7,48(r8)
|
||||
lfd fr8,56(r8)
|
||||
lfd fr9,64(r8)
|
||||
lfd fr10,72(r8)
|
||||
lfd fr11,80(r8)
|
||||
lfd fr12,88(r8)
|
||||
lfd fr13,96(r8)
|
||||
|
||||
gpr:
|
||||
// do we need to load the general-purpose registers?
|
||||
cmp r7,0
|
||||
be call
|
||||
|
||||
// yes, we do
|
||||
mr r16,r7
|
||||
lwz r3,0(r16)
|
||||
lwz r4,4(r16)
|
||||
lwz r5,8(r16)
|
||||
lwz r6,12(r16)
|
||||
lwz r7,16(r16)
|
||||
lwz r8,20(r16)
|
||||
lwz r9,24(r16)
|
||||
lwz r10,28(r16)
|
||||
|
||||
call:
|
||||
// load and call function address
|
||||
mtctr r13
|
||||
bcctrl
|
||||
|
||||
// handle return value based on expected type
|
||||
cmp r14,VOID_TYPE
|
||||
bne float
|
||||
b exit
|
||||
|
||||
float:
|
||||
cmp r14,FLOAT_TYPE
|
||||
be copy
|
||||
cmp r14,DOUBLE_TYPE
|
||||
bne exit
|
||||
|
||||
copy:
|
||||
// move floating point return value to GPRs via memory
|
||||
sfd fr1,8(r1)
|
||||
lwz r3,8(r1)
|
||||
lwz r4,12(r1)
|
||||
|
||||
exit:
|
||||
// restore stack pointer
|
||||
addi r1,r1,r13
|
||||
|
||||
// restore registers used for local variables
|
||||
lwz r13,24(r1)
|
||||
lwz r14,28(r1)
|
||||
lwz r15,32(r1)
|
||||
lwz r16,36(r1)
|
||||
lwz r17,40(r1)
|
||||
|
||||
// load return address
|
||||
lwz r0,8(r1)
|
||||
mtlr r0
|
||||
|
@ -34,8 +34,9 @@
|
||||
#endif
|
||||
|
||||
extern "C" uint64_t
|
||||
vmNativeCall(void* function, void* stack, unsigned stackSize,
|
||||
void* gprTable, void* fprTable, unsigned returnType);
|
||||
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
|
||||
unsigned memoryCount, void* gprTable, void* fprTable,
|
||||
unsigned returnType);
|
||||
|
||||
namespace vm {
|
||||
|
||||
@ -52,6 +53,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
unsigned fprIndex = 0;
|
||||
|
||||
uint64_t stack[argumentsSize];
|
||||
unsigned stackSkip = 0;
|
||||
unsigned stackIndex = 0;
|
||||
|
||||
for (unsigned i = 0; i < argumentsSize; ++i) {
|
||||
@ -59,7 +61,8 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
case FLOAT_TYPE: {
|
||||
if (fprIndex < FprCount) {
|
||||
fprTable[fprIndex++] = arguments[i];
|
||||
gprIndex += 1;
|
||||
++ gprIndex;
|
||||
++ stackSkip;
|
||||
} else {
|
||||
stack[stackIndex++] = arguments[i];
|
||||
}
|
||||
@ -68,8 +71,9 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
case DOUBLE_TYPE: {
|
||||
if (fprIndex < FprCount) {
|
||||
memcpy(fprTable + fprIndex, arguments + i, 8);
|
||||
fprIndex += BytesPerWord / 4;
|
||||
++ fprIndex;
|
||||
gprIndex += BytesPerWord / 4;
|
||||
stackSkip += BytesPerWord / 4;
|
||||
i += (BytesPerWord / 4) - 1;
|
||||
} else {
|
||||
memcpy(stack + stackIndex, arguments + i, 8);
|
||||
@ -82,6 +86,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
if (gprIndex < GprCount) {
|
||||
memcpy(gprTable + gprIndex, arguments + i, 8);
|
||||
gprIndex += BytesPerWord / 4;
|
||||
stackSkip += BytesPerWord / 4;
|
||||
i += (BytesPerWord / 4) - 1;
|
||||
} else {
|
||||
memcpy(stack + stackIndex, arguments + i, 8);
|
||||
@ -93,6 +98,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
default: {
|
||||
if (gprIndex < GprCount) {
|
||||
gprTable[gprIndex++] = arguments[i];
|
||||
++ stackSkip;
|
||||
} else {
|
||||
stack[stackIndex++] = arguments[i];
|
||||
}
|
||||
@ -100,7 +106,8 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
}
|
||||
}
|
||||
|
||||
return vmNativeCall(function, stack, stackIndex * BytesPerWord,
|
||||
return vmNativeCall(function, (stackSkip + stackIndex) * BytesPerWord,
|
||||
stack, stackIndex,
|
||||
(gprIndex ? gprTable : 0),
|
||||
(fprIndex ? fprTable : 0), returnType);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user