corda/src/x86.h

85 lines
1.8 KiB
C++

#ifndef X86_H
#define X86_H
#include "types.h"
#include "stdint.h"
#include "common.h"
extern "C" void NO_RETURN
vmJump(void* address, void* base, void* stack, void* thread);
#ifdef __i386__
extern "C" uint64_t
vmNativeCall(void* function, void* stack, unsigned stackSize,
unsigned returnType);
namespace vm {
inline uint64_t
dynamicCall(void* function, uintptr_t* arguments, uint8_t*,
unsigned, unsigned argumentsSize, unsigned returnType)
{
return vmNativeCall(function, arguments, argumentsSize, returnType);
}
} // namespace vm
#elif defined __x86_64__
extern "C" uint64_t
vmNativeCall(void* function, void* stack, unsigned stackSize,
void* gprTable, void* sseTable, unsigned returnType);
namespace vm {
inline uint64_t
dynamicCall(void* function, uint64_t* arguments, uint8_t* argumentTypes,
unsigned argumentCount, unsigned, unsigned returnType)
{
const unsigned GprCount = 6;
uint64_t gprTable[GprCount];
unsigned gprIndex = 0;
const unsigned SseCount = 8;
uint64_t sseTable[SseCount];
unsigned sseIndex = 0;
uint64_t stack[argumentCount];
unsigned stackIndex = 0;
for (unsigned i = 0; i < argumentCount; ++i) {
switch (argumentTypes[i]) {
case FLOAT_TYPE:
case DOUBLE_TYPE: {
if (sseIndex < SseCount) {
sseTable[sseIndex++] = arguments[i];
} else {
stack[stackIndex++] = arguments[i];
}
} break;
default: {
if (gprIndex < GprCount) {
gprTable[gprIndex++] = arguments[i];
} else {
stack[stackIndex++] = arguments[i];
}
} break;
}
}
return vmNativeCall(function, stack, stackIndex * 8,
(gprIndex ? gprTable : 0),
(sseIndex ? sseTable : 0), returnType);
}
} // namespace vm
#else
# error unsupported platform
#endif
#endif//X86_H