mirror of
https://github.com/corda/corda.git
synced 2025-03-24 13:05:49 +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
|
.text
|
||||||
|
|
||||||
|
BytesPerWord = 4
|
||||||
LinkageArea = 24
|
LinkageArea = 24
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@ -24,35 +25,118 @@ vmNativeCall:
|
|||||||
// save return address
|
// save return address
|
||||||
mflr r0
|
mflr r0
|
||||||
stw r0,8(r1)
|
stw r0,8(r1)
|
||||||
|
|
||||||
// r3 aka 24(r1): function
|
// r3 aka r13: function
|
||||||
// r4 aka 28(r1): stack
|
// r4 : stackTotal
|
||||||
// r5 aka 32(r1): stackSize
|
// r5 : memoryTable
|
||||||
// r6 aka 36(r1): gprTable
|
// r6 : memoryCount
|
||||||
// r7 aka 40(r1): fprTable
|
// r7 : gprTable
|
||||||
// r8 aka 48(r1): returnType
|
// 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
|
// calculate aligned stack frame size
|
||||||
add r13,r5,LinkageArea + 15
|
add r15,r4,LinkageArea + LocalArea + 15
|
||||||
and r13,r13,-16
|
and r15,r15,-16
|
||||||
|
|
||||||
// save and update stack pointer
|
// save and update stack pointer
|
||||||
sub r14,r1,r9
|
sub r16,r1,r15
|
||||||
stwu r1,r14
|
stwu r16,(r1)
|
||||||
|
|
||||||
// save our argument registers so we can clobber them
|
// save our argument registers so we can clobber them
|
||||||
stw r3,24(r1)
|
mr r13,r3
|
||||||
stw r4,28(r1)
|
mr r14,r9
|
||||||
stw r5,32(r1)
|
|
||||||
stw r6,36(r1)
|
|
||||||
stw r7,40(r1)
|
|
||||||
stw r8,48(r1)
|
|
||||||
|
|
||||||
// todo
|
|
||||||
|
|
||||||
|
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
|
// restore stack pointer
|
||||||
addi r1,r1,r13
|
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
|
// load return address
|
||||||
lwz r0,8(r1)
|
lwz r0,8(r1)
|
||||||
mtlr r0
|
mtlr r0
|
||||||
|
@ -34,8 +34,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" uint64_t
|
extern "C" uint64_t
|
||||||
vmNativeCall(void* function, void* stack, unsigned stackSize,
|
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
|
||||||
void* gprTable, void* fprTable, unsigned returnType);
|
unsigned memoryCount, void* gprTable, void* fprTable,
|
||||||
|
unsigned returnType);
|
||||||
|
|
||||||
namespace vm {
|
namespace vm {
|
||||||
|
|
||||||
@ -52,6 +53,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
|||||||
unsigned fprIndex = 0;
|
unsigned fprIndex = 0;
|
||||||
|
|
||||||
uint64_t stack[argumentsSize];
|
uint64_t stack[argumentsSize];
|
||||||
|
unsigned stackSkip = 0;
|
||||||
unsigned stackIndex = 0;
|
unsigned stackIndex = 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < argumentsSize; ++i) {
|
for (unsigned i = 0; i < argumentsSize; ++i) {
|
||||||
@ -59,7 +61,8 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
|||||||
case FLOAT_TYPE: {
|
case FLOAT_TYPE: {
|
||||||
if (fprIndex < FprCount) {
|
if (fprIndex < FprCount) {
|
||||||
fprTable[fprIndex++] = arguments[i];
|
fprTable[fprIndex++] = arguments[i];
|
||||||
gprIndex += 1;
|
++ gprIndex;
|
||||||
|
++ stackSkip;
|
||||||
} else {
|
} else {
|
||||||
stack[stackIndex++] = arguments[i];
|
stack[stackIndex++] = arguments[i];
|
||||||
}
|
}
|
||||||
@ -68,8 +71,9 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
|||||||
case DOUBLE_TYPE: {
|
case DOUBLE_TYPE: {
|
||||||
if (fprIndex < FprCount) {
|
if (fprIndex < FprCount) {
|
||||||
memcpy(fprTable + fprIndex, arguments + i, 8);
|
memcpy(fprTable + fprIndex, arguments + i, 8);
|
||||||
fprIndex += BytesPerWord / 4;
|
++ fprIndex;
|
||||||
gprIndex += BytesPerWord / 4;
|
gprIndex += BytesPerWord / 4;
|
||||||
|
stackSkip += BytesPerWord / 4;
|
||||||
i += (BytesPerWord / 4) - 1;
|
i += (BytesPerWord / 4) - 1;
|
||||||
} else {
|
} else {
|
||||||
memcpy(stack + stackIndex, arguments + i, 8);
|
memcpy(stack + stackIndex, arguments + i, 8);
|
||||||
@ -82,6 +86,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
|||||||
if (gprIndex < GprCount) {
|
if (gprIndex < GprCount) {
|
||||||
memcpy(gprTable + gprIndex, arguments + i, 8);
|
memcpy(gprTable + gprIndex, arguments + i, 8);
|
||||||
gprIndex += BytesPerWord / 4;
|
gprIndex += BytesPerWord / 4;
|
||||||
|
stackSkip += BytesPerWord / 4;
|
||||||
i += (BytesPerWord / 4) - 1;
|
i += (BytesPerWord / 4) - 1;
|
||||||
} else {
|
} else {
|
||||||
memcpy(stack + stackIndex, arguments + i, 8);
|
memcpy(stack + stackIndex, arguments + i, 8);
|
||||||
@ -93,6 +98,7 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
|||||||
default: {
|
default: {
|
||||||
if (gprIndex < GprCount) {
|
if (gprIndex < GprCount) {
|
||||||
gprTable[gprIndex++] = arguments[i];
|
gprTable[gprIndex++] = arguments[i];
|
||||||
|
++ stackSkip;
|
||||||
} else {
|
} else {
|
||||||
stack[stackIndex++] = arguments[i];
|
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),
|
(gprIndex ? gprTable : 0),
|
||||||
(fprIndex ? fprTable : 0), returnType);
|
(fprIndex ? fprTable : 0), returnType);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user