sketch vmNativeCall implementation for powerpc

This commit is contained in:
Joel Dice 2008-06-08 13:47:37 -06:00
parent ca6215c720
commit 4b67adaa0a
2 changed files with 115 additions and 24 deletions

View File

@ -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

View File

@ -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);
}