From 0ccf8d57eabad24cbf9e10469461cb992327dd90 Mon Sep 17 00:00:00 2001 From: dicej Date: Wed, 4 Jun 2008 16:21:27 -0600 Subject: [PATCH] rough sketch of powerpc support --- makefile | 11 ++++- src/arch.h | 27 ++++++++++++ src/common.h | 4 +- src/compile.cpp | 2 +- src/posix.cpp | 35 ++------------- src/powerpc.S | 31 ++++++++++++++ src/powerpc.cpp | 5 +++ src/powerpc.h | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ src/x86.h | 32 +++++++++++--- 9 files changed, 216 insertions(+), 41 deletions(-) create mode 100644 src/arch.h create mode 100644 src/powerpc.S create mode 100644 src/powerpc.cpp create mode 100644 src/powerpc.h diff --git a/makefile b/makefile index 63954a932f..7446b356e2 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,10 @@ MAKEFLAGS = -s name = avian version = 0.0.1 -build-arch = $(shell uname -m) +build-arch = "$(shell uname -m)" +ifeq ($(build-arch),"Power Macintosh") + build-arch = powerpc +endif ifeq ($(build-arch),i586) build-arch = i386 endif @@ -85,6 +88,12 @@ ifeq ($(arch),i386) object-format = elf32-i386 pointer-size = 4 endif +ifeq ($(arch),powerpc) + asm = powerpc + object-arch = powerpc + object-format = elf32-powerpc + pointer-size = 4 +endif ifeq ($(platform),darwin) build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \ diff --git a/src/arch.h b/src/arch.h new file mode 100644 index 0000000000..ae613297b6 --- /dev/null +++ b/src/arch.h @@ -0,0 +1,27 @@ +/* Copyright (c) 2008, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#ifndef ARCH_H +#define ARCH_H + +#include "common.h" + +extern "C" void NO_RETURN +vmJump(void* address, void* base, void* stack, void* thread); + +#if (defined __i386__) || (defined __x86_64__) +# include "x86.h" +#elif defined __POWERPC__ +# include "powerpc.h" +#else +# error unsupported architecture +#endif + +#endif//ARCH_H diff --git a/src/common.h b/src/common.h index a02627b5d8..2a2e548a07 100644 --- a/src/common.h +++ b/src/common.h @@ -27,7 +27,7 @@ # define JNIEXPORT __attribute__ ((visibility("default"))) #endif -#ifdef __i386__ +#if (defined __i386__) || (defined __POWERPC__) # define LD "d" # define LLD "lld" #ifdef __APPLE__ @@ -60,7 +60,7 @@ # define SO_SUFFIX ".so" #endif -#ifdef __APPLE__ +#if (defined __APPLE__) && (defined __i386__) # define FORCE_ALIGN __attribute__((force_align_arg_pointer)) #else # define FORCE_ALIGN diff --git a/src/compile.cpp b/src/compile.cpp index e6fb0bc22d..b012acb37c 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -14,7 +14,7 @@ #include "process.h" #include "assembler.h" #include "compiler.h" -#include "x86.h" +#include "arch.h" using namespace vm; diff --git a/src/posix.cpp b/src/posix.cpp index e705245bf1..38fb515d6b 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -9,9 +9,10 @@ details. */ #ifdef __APPLE__ -#include "CoreFoundation/CoreFoundation.h" -#undef assert +# include "CoreFoundation/CoreFoundation.h" +# undef assert #endif + #include "sys/mman.h" #include "sys/types.h" #include "sys/stat.h" @@ -26,7 +27,7 @@ #include "ucontext.h" #include "stdint.h" -#include "x86.h" +#include "arch.h" #include "system.h" #define ACQUIRE(x) MutexResource MAKE_NAME(mutexResource_) (x) @@ -66,34 +67,6 @@ MySystem* system; const int signals[] = { VisitSignal, SegFaultSignal, InterruptSignal }; -#ifdef __x86_64__ -# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP]) -# define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP]) -# define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_RSP]) -# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX]) -#elif defined __i386__ -# ifdef __APPLE__ -# if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32) -# define IP_REGISTER(context) (context->uc_mcontext->__ss.__eip) -# define BASE_REGISTER(context) (context->uc_mcontext->__ss.__ebp) -# define STACK_REGISTER(context) (context->uc_mcontext->__ss.__esp) -# define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__ebx) -# else -# define IP_REGISTER(context) (context->uc_mcontext->ss.eip) -# define BASE_REGISTER(context) (context->uc_mcontext->ss.ebp) -# define STACK_REGISTER(context) (context->uc_mcontext->ss.esp) -# define THREAD_REGISTER(context) (context->uc_mcontext->ss.ebx) -# endif -# else -# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_EIP]) -# define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_EBP]) -# define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_ESP]) -# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_EBX]) -# endif -#else -# error unsupported architecture -#endif - void handleSignal(int signal, siginfo_t* info, void* context); diff --git a/src/powerpc.S b/src/powerpc.S new file mode 100644 index 0000000000..367c352e0d --- /dev/null +++ b/src/powerpc.S @@ -0,0 +1,31 @@ +/* Copyright (c) 2008, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#include "types.h" + +.text + +#ifdef __APPLE__ +.globl _vmNativeCall +_vmNativeCall: +#else +.globl vmNativeCall +vmNativeCall: +#endif +;; mflr r0 ; extract return address +;; stw r0,8(r1) ; save the return address +;; stwu r1,-spaceToSaveAligned(r1) ; skip over caller save area + +;; ; todo + +;; lwz r0,spaceToSaveAligned + 8(r1) ; get the return address +;; mtlr r0 ; into the link register +;; addi r1,r1,spaceToSaveAligned ; restore stack pointer + blr ; and branch to the return address diff --git a/src/powerpc.cpp b/src/powerpc.cpp new file mode 100644 index 0000000000..0d1f38179a --- /dev/null +++ b/src/powerpc.cpp @@ -0,0 +1,5 @@ +#include "assembler.h" + +using namespace vm; + +// todo diff --git a/src/powerpc.h b/src/powerpc.h new file mode 100644 index 0000000000..544a914f9e --- /dev/null +++ b/src/powerpc.h @@ -0,0 +1,110 @@ +/* Copyright (c) 2008, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +#ifndef POWERPC_H +#define POWERPC_H + +#include "types.h" +#include "common.h" + +#ifdef __APPLE__ +# if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32) +# define IP_REGISTER(context) (context->uc_mcontext->__ss.__srr0) +# define BASE_REGISTER(context) (context->uc_mcontext->__ss.__r13) +# define STACK_REGISTER(context) (context->uc_mcontext->__ss.__r1) +# define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__r14) +# else +# define IP_REGISTER(context) (context->uc_mcontext->ss.srr0) +# define BASE_REGISTER(context) (context->uc_mcontext->ss.r13) +# define STACK_REGISTER(context) (context->uc_mcontext->ss.r1) +# define THREAD_REGISTER(context) (context->uc_mcontext->ss.r14) +# endif +#else +# define IP_REGISTER(context) (context->uc_mcontext.gregs[32]) +# define BASE_REGISTER(context) (context->uc_mcontext.gregs[13]) +# define STACK_REGISTER(context) (context->uc_mcontext.gregs[1]) +# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[14]) +#endif + +extern "C" uint64_t +vmNativeCall(void* function, void* stack, unsigned stackSize, + void* gprTable, void* fprTable, unsigned returnType); + +namespace vm { + +inline uint64_t +dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes, + unsigned, unsigned argumentsSize, unsigned returnType) +{ + const unsigned GprCount = 8; + uintptr_t gprTable[GprCount]; + unsigned gprIndex = 0; + + const unsigned FprCount = 13; + uint64_t fprTable[FprCount]; + unsigned fprIndex = 0; + + uint64_t stack[argumentsSize]; + unsigned stackIndex = 0; + + for (unsigned i = 0; i < argumentsSize; ++i) { + switch (argumentTypes[i]) { + case FLOAT_TYPE: { + if (fprIndex < FprCount) { + fprTable[fprIndex++] = arguments[i]; + gprIndex += 1; + } else { + stack[stackIndex++] = arguments[i]; + } + } break; + + case DOUBLE_TYPE: { + if (fprIndex < FprCount) { + memcpy(fprTable + fprIndex, arguments + i, 8); + fprIndex += BytesPerWord / 4; + gprIndex += BytesPerWord / 4; + i += (BytesPerWord / 4) - 1; + } else { + memcpy(stack + stackIndex, arguments + i, 8); + stackIndex += BytesPerWord / 4; + i += (BytesPerWord / 4) - 1; + } + } break; + + case INT64_TYPE: { + if (gprIndex < GprCount) { + memcpy(gprTable + gprIndex, arguments + i, 8); + gprIndex += BytesPerWord / 4; + i += (BytesPerWord / 4) - 1; + } else { + memcpy(stack + stackIndex, arguments + i, 8); + stackIndex += BytesPerWord / 4; + i += (BytesPerWord / 4) - 1; + } + } break; + + default: { + if (gprIndex < GprCount) { + gprTable[gprIndex++] = arguments[i]; + } else { + stack[stackIndex++] = arguments[i]; + } + } break; + } + } + + return vmNativeCall(function, stack, stackIndex * BytesPerWord, + (gprIndex ? gprTable : 0), + (fprIndex ? fprTable : 0), returnType); +} + +} // namespace vm + +#endif//POWERPC_H diff --git a/src/x86.h b/src/x86.h index 3174af4bd3..ae56473882 100644 --- a/src/x86.h +++ b/src/x86.h @@ -12,14 +12,29 @@ #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__ +# ifdef __APPLE__ +# if __DARWIN_UNIX03 && defined(_STRUCT_X86_EXCEPTION_STATE32) +# define IP_REGISTER(context) (context->uc_mcontext->__ss.__eip) +# define BASE_REGISTER(context) (context->uc_mcontext->__ss.__ebp) +# define STACK_REGISTER(context) (context->uc_mcontext->__ss.__esp) +# define THREAD_REGISTER(context) (context->uc_mcontext->__ss.__ebx) +# else +# define IP_REGISTER(context) (context->uc_mcontext->ss.eip) +# define BASE_REGISTER(context) (context->uc_mcontext->ss.ebp) +# define STACK_REGISTER(context) (context->uc_mcontext->ss.esp) +# define THREAD_REGISTER(context) (context->uc_mcontext->ss.ebx) +# endif +# else +# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_EIP]) +# define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_EBP]) +# define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_ESP]) +# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_EBX]) +# endif + extern "C" uint64_t vmNativeCall(void* function, void* stack, unsigned stackSize, unsigned returnType); @@ -37,6 +52,11 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t*, #elif defined __x86_64__ +# define IP_REGISTER(context) (context->uc_mcontext.gregs[REG_RIP]) +# define BASE_REGISTER(context) (context->uc_mcontext.gregs[REG_RBP]) +# define STACK_REGISTER(context) (context->uc_mcontext.gregs[REG_RSP]) +# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX]) + extern "C" uint64_t vmNativeCall(void* function, void* stack, unsigned stackSize, void* gprTable, void* sseTable, unsigned returnType); @@ -79,7 +99,7 @@ dynamicCall(void* function, uint64_t* arguments, uint8_t* argumentTypes, } } - return vmNativeCall(function, stack, stackIndex * 8, + return vmNativeCall(function, stack, stackIndex * BytesPerWord, (gprIndex ? gprTable : 0), (sseIndex ? sseTable : 0), returnType); } @@ -87,7 +107,7 @@ dynamicCall(void* function, uint64_t* arguments, uint8_t* argumentTypes, } // namespace vm #else -# error unsupported platform +# error unsupported architecture #endif