mirror of
https://github.com/corda/corda.git
synced 2025-01-04 04:04:27 +00:00
remove powerpc support
This commit is contained in:
parent
32d25d79fd
commit
41adb74eb1
@ -59,7 +59,7 @@ Supported Platforms
|
|||||||
|
|
||||||
Avian can currently target the following platforms:
|
Avian can currently target the following platforms:
|
||||||
|
|
||||||
* Linux (i386, x86_64, ARM, and 32-bit PowerPC)
|
* Linux (i386, x86_64, and ARM)
|
||||||
* Windows (i386 and x86_64)
|
* Windows (i386 and x86_64)
|
||||||
* Mac OS X (i386 and x86_64)
|
* Mac OS X (i386 and x86_64)
|
||||||
* Apple iOS (i386 and ARM)
|
* Apple iOS (i386 and ARM)
|
||||||
@ -86,7 +86,7 @@ certain flags described below, all of which are optional.
|
|||||||
|
|
||||||
$ make \
|
$ make \
|
||||||
platform={linux,windows,darwin,freebsd} \
|
platform={linux,windows,darwin,freebsd} \
|
||||||
arch={i386,x86_64,powerpc,arm} \
|
arch={i386,x86_64,arm} \
|
||||||
process={compile,interpret} \
|
process={compile,interpret} \
|
||||||
mode={debug,debug-fast,fast,small} \
|
mode={debug,debug-fast,fast,small} \
|
||||||
lzma=<lzma source directory> \
|
lzma=<lzma source directory> \
|
||||||
|
@ -701,9 +701,6 @@ extern "C" JNIEXPORT jobjectArray JNICALL
|
|||||||
#elif defined ARCH_x86_64
|
#elif defined ARCH_x86_64
|
||||||
e->SetObjectArrayElement(array, index++, e->NewStringUTF("os.arch=x86_64"));
|
e->SetObjectArrayElement(array, index++, e->NewStringUTF("os.arch=x86_64"));
|
||||||
|
|
||||||
#elif defined ARCH_powerpc
|
|
||||||
e->SetObjectArrayElement(array, index++, e->NewStringUTF("os.arch=ppc"));
|
|
||||||
|
|
||||||
#elif defined ARCH_arm
|
#elif defined ARCH_arm
|
||||||
e->SetObjectArrayElement(array, index++, e->NewStringUTF("os.arch=arm"));
|
e->SetObjectArrayElement(array, index++, e->NewStringUTF("os.arch=arm"));
|
||||||
|
|
||||||
|
@ -67,8 +67,6 @@ typedef unsigned __int64 uint64_t;
|
|||||||
# define ARCH_x86_32
|
# define ARCH_x86_32
|
||||||
# elif defined __x86_64__
|
# elif defined __x86_64__
|
||||||
# define ARCH_x86_64
|
# define ARCH_x86_64
|
||||||
# elif (defined __POWERPC__) || (defined __powerpc__)
|
|
||||||
# define ARCH_powerpc
|
|
||||||
# elif defined __arm__
|
# elif defined __arm__
|
||||||
# define ARCH_arm
|
# define ARCH_arm
|
||||||
# endif
|
# endif
|
||||||
|
@ -41,7 +41,7 @@ const bool TailCalls = true;
|
|||||||
const bool TailCalls = false;
|
const bool TailCalls = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined AVIAN_USE_FRAME_POINTER) || (defined ARCH_powerpc)
|
#ifdef AVIAN_USE_FRAME_POINTER
|
||||||
const bool UseFramePointer = true;
|
const bool UseFramePointer = true;
|
||||||
#else
|
#else
|
||||||
const bool UseFramePointer = false;
|
const bool UseFramePointer = false;
|
||||||
|
@ -24,7 +24,6 @@ Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures)
|
|||||||
|
|
||||||
Architecture* makeArchitectureX86(vm::System* system, bool useNativeFeatures);
|
Architecture* makeArchitectureX86(vm::System* system, bool useNativeFeatures);
|
||||||
Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures);
|
Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures);
|
||||||
Architecture* makeArchitecturePowerpc(vm::System* system, bool useNativeFeatures);
|
|
||||||
|
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
@ -114,7 +114,6 @@ public:
|
|||||||
enum Architecture {
|
enum Architecture {
|
||||||
x86 = AVIAN_ARCH_X86,
|
x86 = AVIAN_ARCH_X86,
|
||||||
x86_64 = AVIAN_ARCH_X86_64,
|
x86_64 = AVIAN_ARCH_X86_64,
|
||||||
PowerPC = AVIAN_ARCH_POWERPC,
|
|
||||||
Arm = AVIAN_ARCH_ARM,
|
Arm = AVIAN_ARCH_ARM,
|
||||||
UnknownArch = AVIAN_ARCH_UNKNOWN
|
UnknownArch = AVIAN_ARCH_UNKNOWN
|
||||||
};
|
};
|
||||||
@ -132,10 +131,6 @@ public:
|
|||||||
inline bool operator == (const PlatformInfo& other) {
|
inline bool operator == (const PlatformInfo& other) {
|
||||||
return format == other.format && arch == other.arch;
|
return format == other.format && arch == other.arch;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isLittleEndian() {
|
|
||||||
return arch != PowerPC;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Platform {
|
class Platform {
|
||||||
|
48
makefile
48
makefile
@ -7,12 +7,7 @@ build-arch := $(shell uname -m \
|
|||||||
| sed 's/^i.86$$/i386/' \
|
| sed 's/^i.86$$/i386/' \
|
||||||
| sed 's/^x86pc$$/i386/' \
|
| sed 's/^x86pc$$/i386/' \
|
||||||
| sed 's/amd64/x86_64/' \
|
| sed 's/amd64/x86_64/' \
|
||||||
| sed 's/^arm.*$$/arm/' \
|
| sed 's/^arm.*$$/arm/')
|
||||||
| sed 's/ppc/powerpc/')
|
|
||||||
|
|
||||||
ifeq (Power,$(filter Power,$(build-arch)))
|
|
||||||
build-arch = powerpc
|
|
||||||
endif
|
|
||||||
|
|
||||||
build-platform := \
|
build-platform := \
|
||||||
$(shell uname -s | tr [:upper:] [:lower:] \
|
$(shell uname -s | tr [:upper:] [:lower:] \
|
||||||
@ -428,35 +423,10 @@ codeimage-symbols = _binary_codeimage_bin_start:_binary_codeimage_bin_end
|
|||||||
developer-dir := $(shell if test -d /Developer/Platforms/$(target).platform/Developer/SDKs; then echo /Developer; \
|
developer-dir := $(shell if test -d /Developer/Platforms/$(target).platform/Developer/SDKs; then echo /Developer; \
|
||||||
else echo /Applications/Xcode.app/Contents/Developer; fi)
|
else echo /Applications/Xcode.app/Contents/Developer; fi)
|
||||||
|
|
||||||
ifeq ($(build-arch),powerpc)
|
|
||||||
ifneq ($(arch),$(build-arch))
|
|
||||||
bootimage-cflags += -DTARGET_OPPOSITE_ENDIAN
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(arch),i386)
|
ifeq ($(arch),i386)
|
||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(arch),powerpc)
|
|
||||||
asm = powerpc
|
|
||||||
pointer-size = 4
|
|
||||||
|
|
||||||
ifneq ($(arch),$(build-arch))
|
|
||||||
bootimage-cflags += -DTARGET_OPPOSITE_ENDIAN
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(platform),darwin)
|
|
||||||
ifneq ($(arch),$(build-arch))
|
|
||||||
cxx = powerpc-linux-gnu-g++
|
|
||||||
cc = powerpc-linux-gnu-gcc
|
|
||||||
ar = powerpc-linux-gnu-ar
|
|
||||||
ranlib = powerpc-linux-gnu-ranlib
|
|
||||||
strip = powerpc-linux-gnu-strip
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(arch),arm)
|
ifeq ($(arch),arm)
|
||||||
asm = arm
|
asm = arm
|
||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
@ -709,13 +679,6 @@ ifeq ($(platform),darwin)
|
|||||||
lflags += $(flags)
|
lflags += $(flags)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(arch),powerpc)
|
|
||||||
classpath-extra-cflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
|
||||||
cflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
|
||||||
asmflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
|
||||||
lflags += -arch ppc -mmacosx-version-min=${OSX_SDK_VERSION}
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(arch),i386)
|
ifeq ($(arch),i386)
|
||||||
classpath-extra-cflags += \
|
classpath-extra-cflags += \
|
||||||
-arch i386 -mmacosx-version-min=${OSX_SDK_VERSION}
|
-arch i386 -mmacosx-version-min=${OSX_SDK_VERSION}
|
||||||
@ -1153,12 +1116,9 @@ x86-assembler-sources = $(wildcard $(src)/codegen/target/x86/*.cpp)
|
|||||||
|
|
||||||
arm-assembler-sources = $(wildcard $(src)/codegen/target/arm/*.cpp)
|
arm-assembler-sources = $(wildcard $(src)/codegen/target/arm/*.cpp)
|
||||||
|
|
||||||
powerpc-assembler-sources = $(wildcard $(src)/codegen/target/powerpc/*.cpp)
|
|
||||||
|
|
||||||
all-assembler-sources = \
|
all-assembler-sources = \
|
||||||
$(x86-assembler-sources) \
|
$(x86-assembler-sources) \
|
||||||
$(arm-assembler-sources) \
|
$(arm-assembler-sources)
|
||||||
$(powerpc-assembler-sources)
|
|
||||||
|
|
||||||
native-assembler-sources = $($(target-asm)-assembler-sources)
|
native-assembler-sources = $($(target-asm)-assembler-sources)
|
||||||
|
|
||||||
@ -1424,10 +1384,6 @@ ifeq ($(target-arch),x86_64)
|
|||||||
cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_X86_64
|
cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_X86_64
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(target-arch),powerpc)
|
|
||||||
cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_POWERPC
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(target-arch),arm)
|
ifeq ($(target-arch),arm)
|
||||||
cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_ARM
|
cflags += -DAVIAN_TARGET_ARCH=AVIAN_ARCH_ARM
|
||||||
endif
|
endif
|
||||||
|
@ -41,8 +41,6 @@ compileTimeMemoryBarrier()
|
|||||||
|
|
||||||
#if (defined ARCH_x86_32) || (defined ARCH_x86_64)
|
#if (defined ARCH_x86_32) || (defined ARCH_x86_64)
|
||||||
# include "x86.h"
|
# include "x86.h"
|
||||||
#elif defined ARCH_powerpc
|
|
||||||
# include "powerpc.h"
|
|
||||||
#elif defined ARCH_arm
|
#elif defined ARCH_arm
|
||||||
# include "arm.h"
|
# include "arm.h"
|
||||||
#else
|
#else
|
||||||
|
@ -28,10 +28,6 @@
|
|||||||
#include "float.h"
|
#include "float.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef powerpc
|
|
||||||
# undef powerpc
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef linux
|
#ifdef linux
|
||||||
# undef linux
|
# undef linux
|
||||||
#endif
|
#endif
|
||||||
@ -126,8 +122,6 @@ typedef intptr_t intptr_alias_t;
|
|||||||
# define ARCH_x86_32
|
# define ARCH_x86_32
|
||||||
# elif defined __x86_64__
|
# elif defined __x86_64__
|
||||||
# define ARCH_x86_64
|
# define ARCH_x86_64
|
||||||
# elif (defined __POWERPC__) || (defined __powerpc__)
|
|
||||||
# define ARCH_powerpc
|
|
||||||
# elif defined __arm__
|
# elif defined __arm__
|
||||||
# define ARCH_arm
|
# define ARCH_arm
|
||||||
# else
|
# else
|
||||||
@ -151,7 +145,7 @@ typedef intptr_t __attribute__((__may_alias__)) intptr_alias_t;
|
|||||||
# define PATH_SEPARATOR ':'
|
# define PATH_SEPARATOR ':'
|
||||||
#endif // not PLATFORM_WINDOWS
|
#endif // not PLATFORM_WINDOWS
|
||||||
|
|
||||||
#if (defined ARCH_x86_32) || (defined ARCH_powerpc) || (defined ARCH_arm)
|
#if (defined ARCH_x86_32) || (defined ARCH_arm)
|
||||||
# define LD "ld"
|
# define LD "ld"
|
||||||
# if (defined _MSC_VER) || ((defined __MINGW32__) && __GNUC__ >= 4)
|
# if (defined _MSC_VER) || ((defined __MINGW32__) && __GNUC__ >= 4)
|
||||||
# define LLD "I64d"
|
# define LLD "I64d"
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#define AVIAN_ARCH_X86 (1 << 8)
|
#define AVIAN_ARCH_X86 (1 << 8)
|
||||||
#define AVIAN_ARCH_X86_64 (2 << 8)
|
#define AVIAN_ARCH_X86_64 (2 << 8)
|
||||||
#define AVIAN_ARCH_ARM (3 << 8)
|
#define AVIAN_ARCH_ARM (3 << 8)
|
||||||
#define AVIAN_ARCH_POWERPC (4 << 8)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -184,10 +184,6 @@ struct JavaVMVTable {
|
|||||||
void* reserved1;
|
void* reserved1;
|
||||||
void* reserved2;
|
void* reserved2;
|
||||||
|
|
||||||
#if (! TARGET_RT_MAC_CFM) && defined(__ppc__)
|
|
||||||
void* cfm_vectors[4];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jint
|
jint
|
||||||
(JNICALL *DestroyJavaVM)
|
(JNICALL *DestroyJavaVM)
|
||||||
(JavaVM*);
|
(JavaVM*);
|
||||||
@ -207,10 +203,6 @@ struct JavaVMVTable {
|
|||||||
jint
|
jint
|
||||||
(JNICALL *AttachCurrentThreadAsDaemon)
|
(JNICALL *AttachCurrentThreadAsDaemon)
|
||||||
(JavaVM*, JNIEnv**, void*);
|
(JavaVM*, JNIEnv**, void*);
|
||||||
|
|
||||||
#if TARGET_RT_MAC_CFM && defined(__ppc__)
|
|
||||||
void* real_functions[5];
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct JNIEnvVTable {
|
struct JNIEnvVTable {
|
||||||
@ -219,10 +211,6 @@ struct JNIEnvVTable {
|
|||||||
void* reserved2;
|
void* reserved2;
|
||||||
void* reserved3;
|
void* reserved3;
|
||||||
|
|
||||||
#if (! TARGET_RT_MAC_CFM) && defined(__ppc__)
|
|
||||||
void* cfm_vectors[225];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
jint
|
jint
|
||||||
(JNICALL *GetVersion)
|
(JNICALL *GetVersion)
|
||||||
(JNIEnv*);
|
(JNIEnv*);
|
||||||
@ -1139,9 +1127,6 @@ struct JNIEnvVTable {
|
|||||||
(JNICALL *GetDirectBufferCapacity)
|
(JNICALL *GetDirectBufferCapacity)
|
||||||
(JNIEnv*, jobject);
|
(JNIEnv*, jobject);
|
||||||
|
|
||||||
#if TARGET_RT_MAC_CFM && defined(__ppc__)
|
|
||||||
void* real_functions[228];
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -1,249 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 "avian/types.h"
|
|
||||||
#include "avian/common.h"
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
# include "mach/mach_types.h"
|
|
||||||
# include "mach/ppc/thread_act.h"
|
|
||||||
# include "mach/ppc/thread_status.h"
|
|
||||||
|
|
||||||
# define THREAD_STATE PPC_THREAD_STATE
|
|
||||||
# define THREAD_STATE_TYPE ppc_thread_state_t
|
|
||||||
# define THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT
|
|
||||||
|
|
||||||
# if __DARWIN_UNIX03 && defined(_STRUCT_PPC_EXCEPTION_STATE)
|
|
||||||
# define FIELD(x) __##x
|
|
||||||
# else
|
|
||||||
# define FIELD(x) x
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# define THREAD_STATE_IP(state) ((state).FIELD(srr0))
|
|
||||||
# define THREAD_STATE_STACK(state) ((state).FIELD(r1))
|
|
||||||
# define THREAD_STATE_THREAD(state) ((state).FIELD(r13))
|
|
||||||
# define THREAD_STATE_LINK(state) ((state).FIELD(lr))
|
|
||||||
|
|
||||||
# define IP_REGISTER(context) \
|
|
||||||
THREAD_STATE_IP(context->uc_mcontext->FIELD(ss))
|
|
||||||
# define STACK_REGISTER(context) \
|
|
||||||
THREAD_STATE_STACK(context->uc_mcontext->FIELD(ss))
|
|
||||||
# define THREAD_REGISTER(context) \
|
|
||||||
THREAD_STATE_THREAD(context->uc_mcontext->FIELD(ss))
|
|
||||||
# define LINK_REGISTER(context) \
|
|
||||||
THREAD_STATE_LINK(context->uc_mcontext->FIELD(ss))
|
|
||||||
|
|
||||||
#define VA_LIST(x) (&(x))
|
|
||||||
|
|
||||||
#else // not __APPLE__
|
|
||||||
# define IP_REGISTER(context) (context->uc_mcontext.regs->gpr[32])
|
|
||||||
# define STACK_REGISTER(context) (context->uc_mcontext.regs->gpr[1])
|
|
||||||
# define THREAD_REGISTER(context) (context->uc_mcontext.regs->gpr[13])
|
|
||||||
# define LINK_REGISTER(context) (context->uc_mcontext.regs->gpr[36])
|
|
||||||
|
|
||||||
#define VA_LIST(x) (x)
|
|
||||||
|
|
||||||
#endif // not __APPLE__
|
|
||||||
|
|
||||||
extern "C" uint64_t
|
|
||||||
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
|
|
||||||
unsigned memoryCount, unsigned memoryBase,
|
|
||||||
void* gprTable, void* fprTable, unsigned returnType);
|
|
||||||
|
|
||||||
namespace vm {
|
|
||||||
|
|
||||||
inline void
|
|
||||||
trap()
|
|
||||||
{
|
|
||||||
asm("trap");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
memoryBarrier()
|
|
||||||
{
|
|
||||||
__asm__ __volatile__("sync": : :"memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
storeStoreMemoryBarrier()
|
|
||||||
{
|
|
||||||
memoryBarrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
storeLoadMemoryBarrier()
|
|
||||||
{
|
|
||||||
memoryBarrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
loadMemoryBarrier()
|
|
||||||
{
|
|
||||||
memoryBarrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
syncInstructionCache(const void* start, unsigned size)
|
|
||||||
{
|
|
||||||
const unsigned CacheLineSize = 32;
|
|
||||||
const uintptr_t Mask = ~(CacheLineSize - 1);
|
|
||||||
|
|
||||||
uintptr_t cacheLineStart = reinterpret_cast<uintptr_t>(start) & Mask;
|
|
||||||
uintptr_t cacheLineEnd
|
|
||||||
= (reinterpret_cast<uintptr_t>(start) + size + CacheLineSize - 1) & Mask;
|
|
||||||
|
|
||||||
for (uintptr_t p = cacheLineStart; p < cacheLineEnd; p += CacheLineSize) {
|
|
||||||
__asm__ __volatile__("dcbf 0, %0" : : "r" (p));
|
|
||||||
}
|
|
||||||
|
|
||||||
__asm__ __volatile__("sync");
|
|
||||||
|
|
||||||
for (uintptr_t p = cacheLineStart; p < cacheLineEnd; p += CacheLineSize) {
|
|
||||||
__asm__ __volatile__("icbi 0, %0" : : "r" (p));
|
|
||||||
}
|
|
||||||
|
|
||||||
__asm__ __volatile__("isync");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_ATOMIC_OPERATIONS
|
|
||||||
inline bool
|
|
||||||
atomicCompareAndSwap32(uint32_t* p, uint32_t old, uint32_t new_)
|
|
||||||
{
|
|
||||||
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
|
|
||||||
return __sync_bool_compare_and_swap(p, old, new_);
|
|
||||||
#else // not GCC >= 4.1
|
|
||||||
bool result;
|
|
||||||
|
|
||||||
__asm__ __volatile__(" sync\n"
|
|
||||||
"1:\n"
|
|
||||||
" lwarx %0,0,%2\n"
|
|
||||||
" cmpw %0,%3\n"
|
|
||||||
" bne- 2f\n"
|
|
||||||
" stwcx. %4,0,%2\n"
|
|
||||||
" bne- 1b\n"
|
|
||||||
" isync \n"
|
|
||||||
"2:\n"
|
|
||||||
" xor %0,%0,%3\n"
|
|
||||||
" cntlzw %0,%0\n"
|
|
||||||
" srwi %0,%0,5\n"
|
|
||||||
: "=&r"(result), "+m"(*p)
|
|
||||||
: "r"(p), "r"(old), "r"(new_)
|
|
||||||
: "cc", "memory");
|
|
||||||
|
|
||||||
return result;
|
|
||||||
#endif // not GCC >= 4.1
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
|
|
||||||
{
|
|
||||||
return atomicCompareAndSwap32(reinterpret_cast<uint32_t*>(p), old, new_);
|
|
||||||
}
|
|
||||||
#endif // USE_ATOMIC_OPERATIONS
|
|
||||||
|
|
||||||
inline uint64_t
|
|
||||||
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
|
||||||
unsigned argumentCount, unsigned argumentsSize,
|
|
||||||
unsigned returnType)
|
|
||||||
{
|
|
||||||
#ifdef __APPLE__
|
|
||||||
# define SKIP(var, count) var += count;
|
|
||||||
# define ALIGN(var)
|
|
||||||
const unsigned LinkageArea = 24;
|
|
||||||
const unsigned FprCount = 13;
|
|
||||||
#else
|
|
||||||
# define SKIP(var, count)
|
|
||||||
# define ALIGN(var) if (var & 1) ++var;
|
|
||||||
const unsigned LinkageArea = 8;
|
|
||||||
const unsigned FprCount = 8;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const unsigned GprCount = 8;
|
|
||||||
uintptr_t gprTable[GprCount];
|
|
||||||
unsigned gprIndex = 0;
|
|
||||||
|
|
||||||
uint64_t fprTable[FprCount];
|
|
||||||
unsigned fprIndex = 0;
|
|
||||||
|
|
||||||
uintptr_t stack[argumentsSize / BytesPerWord];
|
|
||||||
unsigned stackSkip = 0;
|
|
||||||
unsigned stackIndex = 0;
|
|
||||||
|
|
||||||
unsigned ai = 0;
|
|
||||||
for (unsigned ati = 0; ati < argumentCount; ++ ati) {
|
|
||||||
switch (argumentTypes[ati]) {
|
|
||||||
case FLOAT_TYPE: {
|
|
||||||
if (fprIndex < FprCount) {
|
|
||||||
double d = bitsToFloat(arguments[ai]);
|
|
||||||
memcpy(fprTable + fprIndex, &d, 8);
|
|
||||||
++ fprIndex;
|
|
||||||
SKIP(gprIndex, 1);
|
|
||||||
SKIP(stackSkip, 1);
|
|
||||||
} else {
|
|
||||||
stack[stackIndex++] = arguments[ai];
|
|
||||||
}
|
|
||||||
++ ai;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case DOUBLE_TYPE: {
|
|
||||||
if (fprIndex + 1 <= FprCount) {
|
|
||||||
memcpy(fprTable + fprIndex, arguments + ai, 8);
|
|
||||||
++ fprIndex;
|
|
||||||
SKIP(gprIndex, 8 / BytesPerWord);
|
|
||||||
SKIP(stackSkip, 8 / BytesPerWord);
|
|
||||||
} else {
|
|
||||||
ALIGN(stackIndex);
|
|
||||||
memcpy(stack + stackIndex, arguments + ai, 8);
|
|
||||||
stackIndex += 8 / BytesPerWord;
|
|
||||||
}
|
|
||||||
ai += 8 / BytesPerWord;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case INT64_TYPE: {
|
|
||||||
if (gprIndex + (8 / BytesPerWord) <= GprCount) {
|
|
||||||
ALIGN(gprIndex);
|
|
||||||
memcpy(gprTable + gprIndex, arguments + ai, 8);
|
|
||||||
gprIndex += 8 / BytesPerWord;
|
|
||||||
SKIP(stackSkip, 8 / BytesPerWord);
|
|
||||||
} else {
|
|
||||||
ALIGN(stackIndex);
|
|
||||||
memcpy(stack + stackIndex, arguments + ai, 8);
|
|
||||||
stackIndex += 8 / BytesPerWord;
|
|
||||||
}
|
|
||||||
ai += 8 / BytesPerWord;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: {
|
|
||||||
if (gprIndex < GprCount) {
|
|
||||||
gprTable[gprIndex++] = arguments[ai];
|
|
||||||
SKIP(stackSkip, 1);
|
|
||||||
} else {
|
|
||||||
stack[stackIndex++] = arguments[ai];
|
|
||||||
}
|
|
||||||
++ ai;
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vmNativeCall
|
|
||||||
(function,
|
|
||||||
(((1 + stackSkip + stackIndex) * BytesPerWord) + LinkageArea + 15) & -16,
|
|
||||||
stack, stackIndex * BytesPerWord,
|
|
||||||
LinkageArea + (stackSkip * BytesPerWord),
|
|
||||||
(gprIndex ? gprTable : 0),
|
|
||||||
(fprIndex ? fprTable : 0), returnType);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace vm
|
|
||||||
|
|
||||||
#endif//POWERPC_H
|
|
@ -2227,11 +2227,7 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
|
|||||||
Avian_java_nio_ByteOrder_isLittleEndian
|
Avian_java_nio_ByteOrder_isLittleEndian
|
||||||
(Thread*, object, uintptr_t*)
|
(Thread*, object, uintptr_t*)
|
||||||
{
|
{
|
||||||
#ifdef ARCH_powerpc
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" AVIAN_EXPORT int64_t JNICALL
|
extern "C" AVIAN_EXPORT int64_t JNICALL
|
||||||
@ -2432,8 +2428,6 @@ Avian_libcore_io_Posix_uname(Thread* t, object, uintptr_t*)
|
|||||||
object arch = makeString(t, "x86");
|
object arch = makeString(t, "x86");
|
||||||
#elif defined ARCH_x86_64
|
#elif defined ARCH_x86_64
|
||||||
object arch = makeString(t, "x86_64");
|
object arch = makeString(t, "x86_64");
|
||||||
#elif defined ARCH_powerpc
|
|
||||||
object arch = makeString(t, "ppc");
|
|
||||||
#elif defined ARCH_arm
|
#elif defined ARCH_arm
|
||||||
object arch = makeString(t, "arm");
|
object arch = makeString(t, "arm");
|
||||||
#else
|
#else
|
||||||
|
@ -2986,8 +2986,6 @@ jvmInitProperties(Thread* t, uintptr_t* arguments)
|
|||||||
local::setProperty(t, method, *properties, "os.arch", "x86");
|
local::setProperty(t, method, *properties, "os.arch", "x86");
|
||||||
#elif defined ARCH_x86_64
|
#elif defined ARCH_x86_64
|
||||||
local::setProperty(t, method, *properties, "os.arch", "x86_64");
|
local::setProperty(t, method, *properties, "os.arch", "x86_64");
|
||||||
#elif defined ARCH_powerpc
|
|
||||||
local::setProperty(t, method, *properties, "os.arch", "ppc");
|
|
||||||
#elif defined ARCH_arm
|
#elif defined ARCH_arm
|
||||||
local::setProperty(t, method, *properties, "os.arch", "arm");
|
local::setProperty(t, method, *properties, "os.arch", "arm");
|
||||||
#else
|
#else
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,42 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 "context.h"
|
|
||||||
#include "block.h"
|
|
||||||
#include "avian/common.h"
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
void resolve(MyBlock*);
|
|
||||||
|
|
||||||
unsigned padding(MyBlock*, unsigned);
|
|
||||||
|
|
||||||
MyBlock::MyBlock(Context* context, unsigned offset):
|
|
||||||
context(context), next(0), jumpOffsetHead(0), jumpOffsetTail(0),
|
|
||||||
lastJumpOffsetTail(0), jumpEventHead(0), jumpEventTail(0),
|
|
||||||
lastEventOffset(0), offset(offset), start(~0), size(0), resolved(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
unsigned MyBlock::resolve(unsigned start, Assembler::Block* next) {
|
|
||||||
this->start = start;
|
|
||||||
this->next = static_cast<MyBlock*>(next);
|
|
||||||
|
|
||||||
powerpc::resolve(this);
|
|
||||||
|
|
||||||
this->resolved = true;
|
|
||||||
|
|
||||||
return start + size + padding(this, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
@ -1,44 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 AVIAN_CODEGEN_ASSEMBLER_POWERPC_BLOCK_H
|
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_BLOCK_H
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
class JumpEvent;
|
|
||||||
|
|
||||||
class MyBlock: public Assembler::Block {
|
|
||||||
public:
|
|
||||||
MyBlock(Context* context, unsigned offset);
|
|
||||||
|
|
||||||
virtual unsigned resolve(unsigned start, Assembler::Block* next);
|
|
||||||
|
|
||||||
Context* context;
|
|
||||||
MyBlock* next;
|
|
||||||
JumpOffset* jumpOffsetHead;
|
|
||||||
JumpOffset* jumpOffsetTail;
|
|
||||||
JumpOffset* lastJumpOffsetTail;
|
|
||||||
JumpEvent* jumpEventHead;
|
|
||||||
JumpEvent* jumpEventTail;
|
|
||||||
unsigned lastEventOffset;
|
|
||||||
unsigned offset;
|
|
||||||
unsigned start;
|
|
||||||
unsigned size;
|
|
||||||
bool resolved;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_BLOCK_H
|
|
@ -1,37 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 "context.h"
|
|
||||||
#include "block.h"
|
|
||||||
#include "avian/common.h"
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
Context::Context(vm::System* s, util::Allocator* a, vm::Zone* zone)
|
|
||||||
: s(s),
|
|
||||||
zone(zone),
|
|
||||||
client(0),
|
|
||||||
code(s, a, 1024),
|
|
||||||
tasks(0),
|
|
||||||
result(0),
|
|
||||||
firstBlock(new (zone) MyBlock(this, 0)),
|
|
||||||
lastBlock(firstBlock),
|
|
||||||
jumpOffsetHead(0),
|
|
||||||
jumpOffsetTail(0),
|
|
||||||
constantPool(0),
|
|
||||||
constantPoolCount(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
@ -1,102 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
|
||||||
|
|
||||||
#include <avian/codegen/assembler.h>
|
|
||||||
#include "avian/alloc-vector.h"
|
|
||||||
|
|
||||||
#ifdef powerpc
|
|
||||||
#undef powerpc
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace vm {
|
|
||||||
class System;
|
|
||||||
class Zone;
|
|
||||||
} // namespace vm
|
|
||||||
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
|
|
||||||
namespace util {
|
|
||||||
class Allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
class Task;
|
|
||||||
class JumpOffset;
|
|
||||||
class ConstantPoolEntry;
|
|
||||||
class MyBlock;
|
|
||||||
|
|
||||||
class Context {
|
|
||||||
public:
|
|
||||||
Context(vm::System* s, util::Allocator* a, vm::Zone* zone);
|
|
||||||
|
|
||||||
vm::System* s;
|
|
||||||
vm::Zone* zone;
|
|
||||||
Assembler::Client* client;
|
|
||||||
vm::Vector code;
|
|
||||||
Task* tasks;
|
|
||||||
uint8_t* result;
|
|
||||||
MyBlock* firstBlock;
|
|
||||||
MyBlock* lastBlock;
|
|
||||||
JumpOffset* jumpOffsetHead;
|
|
||||||
JumpOffset* jumpOffsetTail;
|
|
||||||
ConstantPoolEntry* constantPool;
|
|
||||||
unsigned constantPoolCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*OperationType)(Context*);
|
|
||||||
|
|
||||||
typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*);
|
|
||||||
|
|
||||||
typedef void (*BinaryOperationType)
|
|
||||||
(Context*, unsigned, lir::Operand*, unsigned, lir::Operand*);
|
|
||||||
|
|
||||||
typedef void (*TernaryOperationType)
|
|
||||||
(Context*, unsigned, lir::Operand*, lir::Operand*,
|
|
||||||
lir::Operand*);
|
|
||||||
|
|
||||||
typedef void (*BranchOperationType)
|
|
||||||
(Context*, lir::TernaryOperation, unsigned, lir::Operand*,
|
|
||||||
lir::Operand*, lir::Operand*);
|
|
||||||
|
|
||||||
class ArchitectureContext {
|
|
||||||
public:
|
|
||||||
ArchitectureContext(vm::System* s): s(s) { }
|
|
||||||
|
|
||||||
vm::System* s;
|
|
||||||
OperationType operations[lir::OperationCount];
|
|
||||||
UnaryOperationType unaryOperations[lir::UnaryOperationCount
|
|
||||||
* lir::OperandTypeCount];
|
|
||||||
BinaryOperationType binaryOperations
|
|
||||||
[lir::BinaryOperationCount * lir::OperandTypeCount * lir::OperandTypeCount];
|
|
||||||
TernaryOperationType ternaryOperations
|
|
||||||
[lir::NonBranchTernaryOperationCount * lir::OperandTypeCount];
|
|
||||||
BranchOperationType branchOperations
|
|
||||||
[lir::BranchOperationCount * lir::OperandTypeCount * lir::OperandTypeCount];
|
|
||||||
};
|
|
||||||
|
|
||||||
inline avian::util::Aborter* getAborter(Context* con) {
|
|
||||||
return con->s;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline avian::util::Aborter* getAborter(ArchitectureContext* con) {
|
|
||||||
return con->s;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
|
@ -1,141 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 AVIAN_CODEGEN_ASSEMBLER_POWERPC_ENCODE_H
|
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_ENCODE_H
|
|
||||||
|
|
||||||
#ifdef powerpc
|
|
||||||
#undef powerpc
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
namespace isa {
|
|
||||||
// INSTRUCTION FORMATS
|
|
||||||
inline int D(int op, int rt, int ra, int d) { return op<<26|rt<<21|ra<<16|(d & 0xFFFF); }
|
|
||||||
// inline int DS(int op, int rt, int ra, int ds, int xo) { return op<<26|rt<<21|ra<<16|ds<<2|xo; }
|
|
||||||
inline int I(int op, int li, int aa, int lk) { return op<<26|(li & 0x3FFFFFC)|aa<<1|lk; }
|
|
||||||
inline int B(int op, int bo, int bi, int bd, int aa, int lk) { return op<<26|bo<<21|bi<<16|(bd & 0xFFFC)|aa<<1|lk; }
|
|
||||||
// inline int SC(int op, int lev) { return op<<26|lev<<5|2; }
|
|
||||||
inline int X(int op, int rt, int ra, int rb, int xo, int rc) { return op<<26|rt<<21|ra<<16|rb<<11|xo<<1|rc; }
|
|
||||||
inline int XL(int op, int bt, int ba, int bb, int xo, int lk) { return op<<26|bt<<21|ba<<16|bb<<11|xo<<1|lk; }
|
|
||||||
inline int XFX(int op, int rt, int spr, int xo) { return op<<26|rt<<21|((spr >> 5) | ((spr << 5) & 0x3E0))<<11|xo<<1; }
|
|
||||||
// inline int XFL(int op, int flm, int frb, int xo, int rc) { return op<<26|flm<<17|frb<<11|xo<<1|rc; }
|
|
||||||
// inline int XS(int op, int rs, int ra, int sh, int xo, int sh2, int rc) { return op<<26|rs<<21|ra<<16|sh<<11|xo<<2|sh2<<1|rc; }
|
|
||||||
inline int XO(int op, int rt, int ra, int rb, int oe, int xo, int rc) { return op<<26|rt<<21|ra<<16|rb<<11|oe<<10|xo<<1|rc; }
|
|
||||||
// inline int A(int op, int frt, int fra, int frb, int frc, int xo, int rc) { return op<<26|frt<<21|fra<<16|frb<<11|frc<<6|xo<<1|rc; }
|
|
||||||
inline int M(int op, int rs, int ra, int rb, int mb, int me, int rc) { return op<<26|rs<<21|ra<<16|rb<<11|mb<<6|me<<1|rc; }
|
|
||||||
// inline int MD(int op, int rs, int ra, int sh, int mb, int xo, int sh2, int rc) { return op<<26|rs<<21|ra<<16|sh<<11|mb<<5|xo<<2|sh2<<1|rc; }
|
|
||||||
// inline int MDS(int op, int rs, int ra, int rb, int mb, int xo, int rc) { return op<<26|rs<<21|ra<<16|rb<<11|mb<<5|xo<<1|rc; }
|
|
||||||
// INSTRUCTIONS
|
|
||||||
inline int lbz(int rt, int ra, int i) { return D(34, rt, ra, i); }
|
|
||||||
inline int lbzx(int rt, int ra, int rb) { return X(31, rt, ra, rb, 87, 0); }
|
|
||||||
inline int lha(int rt, int ra, int i) { return D(42, rt, ra, i); }
|
|
||||||
inline int lhax(int rt, int ra, int rb) { return X(31, rt, ra, rb, 343, 0); }
|
|
||||||
// inline int lhz(int rt, int ra, int i) { return D(40, rt, ra, i); }
|
|
||||||
inline int lhzx(int rt, int ra, int rb) { return X(31, rt, ra, rb, 279, 0); }
|
|
||||||
inline int lwz(int rt, int ra, int i) { return D(32, rt, ra, i); }
|
|
||||||
inline int lwzx(int rt, int ra, int rb) { return X(31, rt, ra, rb, 23, 0); }
|
|
||||||
inline int stb(int rs, int ra, int i) { return D(38, rs, ra, i); }
|
|
||||||
inline int stbx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 215, 0); }
|
|
||||||
inline int sth(int rs, int ra, int i) { return D(44, rs, ra, i); }
|
|
||||||
inline int sthx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 407, 0); }
|
|
||||||
inline int stw(int rs, int ra, int i) { return D(36, rs, ra, i); }
|
|
||||||
inline int stwu(int rs, int ra, int i) { return D(37, rs, ra, i); }
|
|
||||||
inline int stwux(int rs, int ra, int rb) { return X(31, rs, ra, rb, 183, 0); }
|
|
||||||
inline int stwx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 151, 0); }
|
|
||||||
inline int add(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 266, 0); }
|
|
||||||
inline int addc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 10, 0); }
|
|
||||||
inline int adde(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 138, 0); }
|
|
||||||
inline int addi(int rt, int ra, int i) { return D(14, rt, ra, i); }
|
|
||||||
inline int addic(int rt, int ra, int i) { return D(12, rt, ra, i); }
|
|
||||||
inline int addis(int rt, int ra, int i) { return D(15, rt, ra, i); }
|
|
||||||
inline int subf(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 40, 0); }
|
|
||||||
inline int subfc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 8, 0); }
|
|
||||||
inline int subfe(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 136, 0); }
|
|
||||||
inline int subfic(int rt, int ra, int i) { return D(8, rt, ra, i); }
|
|
||||||
inline int subfze(int rt, int ra) { return XO(31, rt, ra, 0, 0, 200, 0); }
|
|
||||||
inline int mullw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 235, 0); }
|
|
||||||
// inline int mulhw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 75, 0); }
|
|
||||||
inline int mulhwu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 11, 0); }
|
|
||||||
// inline int mulli(int rt, int ra, int i) { return D(7, rt, ra, i); }
|
|
||||||
inline int divw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 491, 0); }
|
|
||||||
// inline int divwu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 459, 0); }
|
|
||||||
// inline int divd(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 489, 0); }
|
|
||||||
// inline int divdu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 457, 0); }
|
|
||||||
inline int neg(int rt, int ra) { return XO(31, rt, ra, 0, 0, 104, 0); }
|
|
||||||
inline int and_(int rt, int ra, int rb) { return X(31, ra, rt, rb, 28, 0); }
|
|
||||||
inline int andi(int rt, int ra, int i) { return D(28, ra, rt, i); }
|
|
||||||
inline int andis(int rt, int ra, int i) { return D(29, ra, rt, i); }
|
|
||||||
inline int or_(int rt, int ra, int rb) { return X(31, ra, rt, rb, 444, 0); }
|
|
||||||
inline int ori(int rt, int ra, int i) { return D(24, rt, ra, i); }
|
|
||||||
inline int xor_(int rt, int ra, int rb) { return X(31, ra, rt, rb, 316, 0); }
|
|
||||||
inline int oris(int rt, int ra, int i) { return D(25, rt, ra, i); }
|
|
||||||
inline int xori(int rt, int ra, int i) { return D(26, rt, ra, i); }
|
|
||||||
inline int xoris(int rt, int ra, int i) { return D(27, rt, ra, i); }
|
|
||||||
inline int rlwinm(int rt, int ra, int i, int mb, int me) { return M(21, ra, rt, i, mb, me, 0); }
|
|
||||||
inline int rlwimi(int rt, int ra, int i, int mb, int me) { return M(20, ra, rt, i, mb, me, 0); }
|
|
||||||
inline int slw(int rt, int ra, int sh) { return X(31, ra, rt, sh, 24, 0); }
|
|
||||||
// inline int sld(int rt, int ra, int rb) { return X(31, ra, rt, rb, 27, 0); }
|
|
||||||
inline int srw(int rt, int ra, int sh) { return X(31, ra, rt, sh, 536, 0); }
|
|
||||||
inline int sraw(int rt, int ra, int sh) { return X(31, ra, rt, sh, 792, 0); }
|
|
||||||
inline int srawi(int rt, int ra, int sh) { return X(31, ra, rt, sh, 824, 0); }
|
|
||||||
inline int extsb(int rt, int rs) { return X(31, rs, rt, 0, 954, 0); }
|
|
||||||
inline int extsh(int rt, int rs) { return X(31, rs, rt, 0, 922, 0); }
|
|
||||||
inline int mfspr(int rt, int spr) { return XFX(31, rt, spr, 339); }
|
|
||||||
inline int mtspr(int spr, int rs) { return XFX(31, rs, spr, 467); }
|
|
||||||
inline int b(int i) { return I(18, i, 0, 0); }
|
|
||||||
inline int bl(int i) { return I(18, i, 0, 1); }
|
|
||||||
inline int bcctr(int bo, int bi, int lk) { return XL(19, bo, bi, 0, 528, lk); }
|
|
||||||
inline int bclr(int bo, int bi, int lk) { return XL(19, bo, bi, 0, 16, lk); }
|
|
||||||
inline int bc(int bo, int bi, int bd, int lk) { return B(16, bo, bi, bd, 0, lk); }
|
|
||||||
inline int cmp(int bf, int ra, int rb) { return X(31, bf << 2, ra, rb, 0, 0); }
|
|
||||||
inline int cmpl(int bf, int ra, int rb) { return X(31, bf << 2, ra, rb, 32, 0); }
|
|
||||||
inline int cmpi(int bf, int ra, int i) { return D(11, bf << 2, ra, i); }
|
|
||||||
inline int cmpli(int bf, int ra, int i) { return D(10, bf << 2, ra, i); }
|
|
||||||
inline int sync(int L) { return X(31, L, 0, 0, 598, 0); }
|
|
||||||
// PSEUDO-INSTRUCTIONS
|
|
||||||
inline int li(int rt, int i) { return addi(rt, 0, i); }
|
|
||||||
inline int lis(int rt, int i) { return addis(rt, 0, i); }
|
|
||||||
inline int slwi(int rt, int ra, int i) { return rlwinm(rt, ra, i, 0, 31-i); }
|
|
||||||
inline int srwi(int rt, int ra, int i) { return rlwinm(rt, ra, 32-i, i, 31); }
|
|
||||||
// inline int sub(int rt, int ra, int rb) { return subf(rt, rb, ra); }
|
|
||||||
// inline int subc(int rt, int ra, int rb) { return subfc(rt, rb, ra); }
|
|
||||||
// inline int subi(int rt, int ra, int i) { return addi(rt, ra, -i); }
|
|
||||||
// inline int subis(int rt, int ra, int i) { return addis(rt, ra, -i); }
|
|
||||||
inline int mr(int rt, int ra) { return or_(rt, ra, ra); }
|
|
||||||
inline int mflr(int rx) { return mfspr(rx, 8); }
|
|
||||||
inline int mtlr(int rx) { return mtspr(8, rx); }
|
|
||||||
inline int mtctr(int rd) { return mtspr(9, rd); }
|
|
||||||
inline int bctr() { return bcctr(20, 0, 0); }
|
|
||||||
inline int bctrl() { return bcctr(20, 0, 1); }
|
|
||||||
inline int blr() { return bclr(20, 0, 0); }
|
|
||||||
inline int blt(int i) { return bc(12, 0, i, 0); }
|
|
||||||
inline int bgt(int i) { return bc(12, 1, i, 0); }
|
|
||||||
inline int bge(int i) { return bc(4, 0, i, 0); }
|
|
||||||
inline int ble(int i) { return bc(4, 1, i, 0); }
|
|
||||||
inline int beq(int i) { return bc(12, 2, i, 0); }
|
|
||||||
inline int bne(int i) { return bc(4, 2, i, 0); }
|
|
||||||
inline int cmpw(int ra, int rb) { return cmp(0, ra, rb); }
|
|
||||||
inline int cmplw(int ra, int rb) { return cmpl(0, ra, rb); }
|
|
||||||
inline int cmpwi(int ra, int i) { return cmpi(0, ra, i); }
|
|
||||||
inline int cmplwi(int ra, int i) { return cmpli(0, ra, i); }
|
|
||||||
inline int trap() { return 0x7fe00008; } // todo: macro-ify
|
|
||||||
|
|
||||||
} // namespace isa
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_ENCODE_H
|
|
||||||
|
|
@ -1,243 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 "context.h"
|
|
||||||
#include "block.h"
|
|
||||||
#include "fixup.h"
|
|
||||||
#include "encode.h"
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
using namespace isa;
|
|
||||||
using namespace util;
|
|
||||||
|
|
||||||
unsigned padding(MyBlock*, unsigned);
|
|
||||||
|
|
||||||
int ha16(int32_t i);
|
|
||||||
|
|
||||||
bool bounded(int right, int left, int32_t v) {
|
|
||||||
return ((v << left) >> left) == v and ((v >> right) << right) == v;
|
|
||||||
}
|
|
||||||
|
|
||||||
OffsetPromise::OffsetPromise(Context* c, MyBlock* block, unsigned offset):
|
|
||||||
c(c), block(block), offset(offset)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool OffsetPromise::resolved() {
|
|
||||||
return block->resolved;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t OffsetPromise::value() {
|
|
||||||
assert(c, resolved());
|
|
||||||
|
|
||||||
unsigned o = offset - block->offset;
|
|
||||||
return block->start + padding(block, o) + o;
|
|
||||||
}
|
|
||||||
|
|
||||||
Promise* offsetPromise(Context* c) {
|
|
||||||
return new(c->zone) OffsetPromise(c, c->lastBlock, c->code.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
void* updateOffset(vm::System* s, uint8_t* instruction, bool conditional, int64_t value,
|
|
||||||
void* jumpAddress)
|
|
||||||
{
|
|
||||||
int32_t v = reinterpret_cast<uint8_t*>(value) - instruction;
|
|
||||||
|
|
||||||
int32_t mask;
|
|
||||||
if (conditional) {
|
|
||||||
if (not bounded(2, 16, v)) {
|
|
||||||
*static_cast<uint32_t*>(jumpAddress) = isa::b(0);
|
|
||||||
updateOffset(s, static_cast<uint8_t*>(jumpAddress), false, value, 0);
|
|
||||||
|
|
||||||
v = static_cast<uint8_t*>(jumpAddress) - instruction;
|
|
||||||
|
|
||||||
expect(s, bounded(2, 16, v));
|
|
||||||
}
|
|
||||||
mask = 0xFFFC;
|
|
||||||
} else {
|
|
||||||
expect(s, bounded(2, 6, v));
|
|
||||||
mask = 0x3FFFFFC;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t* p = reinterpret_cast<int32_t*>(instruction);
|
|
||||||
*p = vm::targetV4((v & mask) | ((~mask) & vm::targetV4(*p)));
|
|
||||||
|
|
||||||
return instruction + 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
OffsetListener::OffsetListener(vm::System* s, uint8_t* instruction, bool conditional,
|
|
||||||
void* jumpAddress):
|
|
||||||
s(s),
|
|
||||||
instruction(instruction),
|
|
||||||
jumpAddress(jumpAddress),
|
|
||||||
conditional(conditional)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool OffsetListener::resolve(int64_t value, void** location) {
|
|
||||||
void* p = updateOffset(s, instruction, conditional, value, jumpAddress);
|
|
||||||
if (location) *location = p;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
OffsetTask::OffsetTask(Task* next, Promise* promise, Promise* instructionOffset,
|
|
||||||
bool conditional):
|
|
||||||
Task(next),
|
|
||||||
promise(promise),
|
|
||||||
instructionOffset(instructionOffset),
|
|
||||||
jumpAddress(0),
|
|
||||||
conditional(conditional)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void OffsetTask::run(Context* c) {
|
|
||||||
if (promise->resolved()) {
|
|
||||||
updateOffset
|
|
||||||
(c->s, c->result + instructionOffset->value(), conditional,
|
|
||||||
promise->value(), jumpAddress);
|
|
||||||
} else {
|
|
||||||
new (promise->listen(sizeof(OffsetListener)))
|
|
||||||
OffsetListener(c->s, c->result + instructionOffset->value(),
|
|
||||||
conditional, jumpAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JumpOffset::JumpOffset(MyBlock* block, OffsetTask* task, unsigned offset):
|
|
||||||
block(block), task(task), next(0), offset(offset)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
JumpEvent::JumpEvent(JumpOffset* jumpOffsetHead, JumpOffset* jumpOffsetTail,
|
|
||||||
unsigned offset):
|
|
||||||
jumpOffsetHead(jumpOffsetHead), jumpOffsetTail(jumpOffsetTail), next(0),
|
|
||||||
offset(offset)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void appendOffsetTask(Context* c, Promise* promise, Promise* instructionOffset,
|
|
||||||
bool conditional)
|
|
||||||
{
|
|
||||||
OffsetTask* task = new(c->zone) OffsetTask(c->tasks, promise, instructionOffset, conditional);
|
|
||||||
|
|
||||||
c->tasks = task;
|
|
||||||
|
|
||||||
if (conditional) {
|
|
||||||
JumpOffset* offset =
|
|
||||||
new(c->zone) JumpOffset(c->lastBlock, task, c->code.length() - c->lastBlock->offset);
|
|
||||||
|
|
||||||
if (c->lastBlock->jumpOffsetTail) {
|
|
||||||
c->lastBlock->jumpOffsetTail->next = offset;
|
|
||||||
} else {
|
|
||||||
c->lastBlock->jumpOffsetHead = offset;
|
|
||||||
}
|
|
||||||
c->lastBlock->jumpOffsetTail = offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void appendJumpEvent(Context* c, MyBlock* b, unsigned offset, JumpOffset* head,
|
|
||||||
JumpOffset* tail)
|
|
||||||
{
|
|
||||||
JumpEvent* e = new(c->zone) JumpEvent
|
|
||||||
(head, tail, offset);
|
|
||||||
|
|
||||||
if (b->jumpEventTail) {
|
|
||||||
b->jumpEventTail->next = e;
|
|
||||||
} else {
|
|
||||||
b->jumpEventHead = e;
|
|
||||||
}
|
|
||||||
b->jumpEventTail = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftMaskPromise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask) {
|
|
||||||
return new (c->zone) ShiftMaskPromise(base, shift, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
updateImmediate(vm::System* s, void* dst, int32_t src, unsigned size, bool address)
|
|
||||||
{
|
|
||||||
switch (size) {
|
|
||||||
case 4: {
|
|
||||||
int32_t* p = static_cast<int32_t*>(dst);
|
|
||||||
int r = (vm::targetV4(p[1]) >> 21) & 31;
|
|
||||||
|
|
||||||
if (address) {
|
|
||||||
p[0] = vm::targetV4(lis(r, ha16(src)));
|
|
||||||
p[1] |= vm::targetV4(src & 0xFFFF);
|
|
||||||
} else {
|
|
||||||
p[0] = vm::targetV4(lis(r, src >> 16));
|
|
||||||
p[1] = vm::targetV4(ori(r, r, src));
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: abort(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImmediateListener::ImmediateListener(vm::System* s, void* dst, unsigned size, unsigned offset,
|
|
||||||
bool address):
|
|
||||||
s(s), dst(dst), size(size), offset(offset), address(address)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool ImmediateListener::resolve(int64_t value, void** location) {
|
|
||||||
updateImmediate(s, dst, value, size, address);
|
|
||||||
if (location) *location = static_cast<uint8_t*>(dst) + offset;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImmediateTask::ImmediateTask(Task* next, Promise* promise, Promise* offset, unsigned size,
|
|
||||||
unsigned promiseOffset, bool address):
|
|
||||||
Task(next),
|
|
||||||
promise(promise),
|
|
||||||
offset(offset),
|
|
||||||
size(size),
|
|
||||||
promiseOffset(promiseOffset),
|
|
||||||
address(address)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void ImmediateTask::run(Context* c) {
|
|
||||||
if (promise->resolved()) {
|
|
||||||
updateImmediate
|
|
||||||
(c->s, c->result + offset->value(), promise->value(), size, address);
|
|
||||||
} else {
|
|
||||||
new (promise->listen(sizeof(ImmediateListener))) ImmediateListener
|
|
||||||
(c->s, c->result + offset->value(), size, promiseOffset, address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
appendImmediateTask(Context* c, Promise* promise, Promise* offset,
|
|
||||||
unsigned size, unsigned promiseOffset, bool address)
|
|
||||||
{
|
|
||||||
c->tasks = new(c->zone) ImmediateTask(c->tasks, promise, offset, size, promiseOffset, address);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstantPoolEntry::ConstantPoolEntry(Context* c, Promise* constant):
|
|
||||||
c(c), constant(constant), next(c->constantPool), address(0)
|
|
||||||
{
|
|
||||||
c->constantPool = this;
|
|
||||||
++ c->constantPoolCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t ConstantPoolEntry::value() {
|
|
||||||
assert(c, resolved());
|
|
||||||
|
|
||||||
return reinterpret_cast<intptr_t>(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConstantPoolEntry::resolved() {
|
|
||||||
return address != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstantPoolEntry* appendConstantPoolEntry(Context* c, Promise* constant) {
|
|
||||||
return new (c->zone) ConstantPoolEntry(c, constant);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
@ -1,160 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 AVIAN_CODEGEN_ASSEMBLER_POWERPC_FIXUP_H
|
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_FIXUP_H
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
|
|
||||||
class Task {
|
|
||||||
public:
|
|
||||||
Task(Task* next): next(next) { }
|
|
||||||
|
|
||||||
virtual void run(Context* c) = 0;
|
|
||||||
|
|
||||||
Task* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
class OffsetPromise: public Promise {
|
|
||||||
public:
|
|
||||||
OffsetPromise(Context* c, MyBlock* block, unsigned offset);
|
|
||||||
|
|
||||||
virtual bool resolved();
|
|
||||||
|
|
||||||
virtual int64_t value();
|
|
||||||
|
|
||||||
Context* c;
|
|
||||||
MyBlock* block;
|
|
||||||
unsigned offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
Promise* offsetPromise(Context* c);
|
|
||||||
|
|
||||||
void*
|
|
||||||
updateOffset(vm::System* s, uint8_t* instruction, bool conditional, int64_t value,
|
|
||||||
void* jumpAddress);
|
|
||||||
|
|
||||||
class OffsetListener: public Promise::Listener {
|
|
||||||
public:
|
|
||||||
OffsetListener(vm::System* s, uint8_t* instruction, bool conditional,
|
|
||||||
void* jumpAddress);
|
|
||||||
|
|
||||||
virtual bool resolve(int64_t value, void** location);
|
|
||||||
|
|
||||||
vm::System* s;
|
|
||||||
uint8_t* instruction;
|
|
||||||
void* jumpAddress;
|
|
||||||
bool conditional;
|
|
||||||
};
|
|
||||||
|
|
||||||
class OffsetTask: public Task {
|
|
||||||
public:
|
|
||||||
OffsetTask(Task* next, Promise* promise, Promise* instructionOffset,
|
|
||||||
bool conditional);
|
|
||||||
|
|
||||||
virtual void run(Context* c);
|
|
||||||
|
|
||||||
Promise* promise;
|
|
||||||
Promise* instructionOffset;
|
|
||||||
void* jumpAddress;
|
|
||||||
bool conditional;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JumpOffset {
|
|
||||||
public:
|
|
||||||
JumpOffset(MyBlock* block, OffsetTask* task, unsigned offset);
|
|
||||||
|
|
||||||
MyBlock* block;
|
|
||||||
OffsetTask* task;
|
|
||||||
JumpOffset* next;
|
|
||||||
unsigned offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JumpEvent {
|
|
||||||
public:
|
|
||||||
JumpEvent(JumpOffset* jumpOffsetHead, JumpOffset* jumpOffsetTail,
|
|
||||||
unsigned offset);
|
|
||||||
|
|
||||||
JumpOffset* jumpOffsetHead;
|
|
||||||
JumpOffset* jumpOffsetTail;
|
|
||||||
JumpEvent* next;
|
|
||||||
unsigned offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
void appendOffsetTask(Context* c, Promise* promise, Promise* instructionOffset,
|
|
||||||
bool conditional);
|
|
||||||
|
|
||||||
void appendJumpEvent(Context* c, MyBlock* b, unsigned offset, JumpOffset* head,
|
|
||||||
JumpOffset* tail);
|
|
||||||
|
|
||||||
ShiftMaskPromise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask);
|
|
||||||
|
|
||||||
void updateImmediate(vm::System* s, void* dst, int32_t src, unsigned size, bool address);
|
|
||||||
|
|
||||||
class ImmediateListener: public Promise::Listener {
|
|
||||||
public:
|
|
||||||
ImmediateListener(vm::System* s, void* dst, unsigned size, unsigned offset,
|
|
||||||
bool address);
|
|
||||||
|
|
||||||
virtual bool resolve(int64_t value, void** location);
|
|
||||||
|
|
||||||
vm::System* s;
|
|
||||||
void* dst;
|
|
||||||
unsigned size;
|
|
||||||
unsigned offset;
|
|
||||||
bool address;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ImmediateTask: public Task {
|
|
||||||
public:
|
|
||||||
ImmediateTask(Task* next, Promise* promise, Promise* offset, unsigned size,
|
|
||||||
unsigned promiseOffset, bool address);
|
|
||||||
|
|
||||||
virtual void run(Context* c);
|
|
||||||
|
|
||||||
Promise* promise;
|
|
||||||
Promise* offset;
|
|
||||||
unsigned size;
|
|
||||||
unsigned promiseOffset;
|
|
||||||
bool address;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
appendImmediateTask(Context* c, Promise* promise, Promise* offset,
|
|
||||||
unsigned size, unsigned promiseOffset, bool address);
|
|
||||||
|
|
||||||
class ConstantPoolEntry: public Promise {
|
|
||||||
public:
|
|
||||||
ConstantPoolEntry(Context* c, Promise* constant);
|
|
||||||
|
|
||||||
virtual int64_t value();
|
|
||||||
|
|
||||||
virtual bool resolved();
|
|
||||||
|
|
||||||
Context* c;
|
|
||||||
Promise* constant;
|
|
||||||
ConstantPoolEntry* next;
|
|
||||||
void* address;
|
|
||||||
};
|
|
||||||
|
|
||||||
ConstantPoolEntry* appendConstantPoolEntry(Context* c, Promise* constant);
|
|
||||||
|
|
||||||
inline int ha16(int32_t i) {
|
|
||||||
return ((i >> 16) + ((i & 0x8000) ? 1 : 0)) & 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_FIXUP_H
|
|
@ -1,139 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 "context.h"
|
|
||||||
#include "block.h"
|
|
||||||
#include "avian/common.h"
|
|
||||||
#include "operations.h"
|
|
||||||
|
|
||||||
#include "multimethod.h"
|
|
||||||
#include "../multimethod.h"
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
using namespace util;
|
|
||||||
|
|
||||||
unsigned index(ArchitectureContext*,
|
|
||||||
lir::BinaryOperation operation,
|
|
||||||
lir::OperandType operand1,
|
|
||||||
lir::OperandType operand2)
|
|
||||||
{
|
|
||||||
return operation
|
|
||||||
+ (lir::BinaryOperationCount * operand1)
|
|
||||||
+ (lir::BinaryOperationCount * lir::OperandTypeCount * operand2);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned index(ArchitectureContext* c UNUSED,
|
|
||||||
lir::TernaryOperation operation,
|
|
||||||
lir::OperandType operand1)
|
|
||||||
{
|
|
||||||
assert(c, not isBranch(operation));
|
|
||||||
|
|
||||||
return operation + (lir::NonBranchTernaryOperationCount * operand1);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned branchIndex(ArchitectureContext* c UNUSED, lir::OperandType operand1,
|
|
||||||
lir::OperandType operand2)
|
|
||||||
{
|
|
||||||
return operand1 + (lir::OperandTypeCount * operand2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void populateTables(ArchitectureContext* c) {
|
|
||||||
const lir::OperandType C = lir::ConstantOperand;
|
|
||||||
const lir::OperandType A = lir::AddressOperand;
|
|
||||||
const lir::OperandType R = lir::RegisterOperand;
|
|
||||||
const lir::OperandType M = lir::MemoryOperand;
|
|
||||||
|
|
||||||
OperationType* zo = c->operations;
|
|
||||||
UnaryOperationType* uo = c->unaryOperations;
|
|
||||||
BinaryOperationType* bo = c->binaryOperations;
|
|
||||||
TernaryOperationType* to = c->ternaryOperations;
|
|
||||||
BranchOperationType* bro = c->branchOperations;
|
|
||||||
|
|
||||||
zo[lir::Return] = return_;
|
|
||||||
zo[lir::LoadBarrier] = memoryBarrier;
|
|
||||||
zo[lir::StoreStoreBarrier] = memoryBarrier;
|
|
||||||
zo[lir::StoreLoadBarrier] = memoryBarrier;
|
|
||||||
zo[lir::Trap] = trap;
|
|
||||||
|
|
||||||
uo[Multimethod::index(lir::LongCall, C)] = CAST1(longCallC);
|
|
||||||
|
|
||||||
uo[Multimethod::index(lir::AlignedLongCall, C)] = CAST1(alignedLongCallC);
|
|
||||||
|
|
||||||
uo[Multimethod::index(lir::LongJump, C)] = CAST1(longJumpC);
|
|
||||||
|
|
||||||
uo[Multimethod::index(lir::AlignedLongJump, C)] = CAST1(alignedLongJumpC);
|
|
||||||
|
|
||||||
uo[Multimethod::index(lir::Jump, R)] = CAST1(jumpR);
|
|
||||||
uo[Multimethod::index(lir::Jump, C)] = CAST1(jumpC);
|
|
||||||
|
|
||||||
uo[Multimethod::index(lir::AlignedJump, R)] = CAST1(jumpR);
|
|
||||||
uo[Multimethod::index(lir::AlignedJump, C)] = CAST1(jumpC);
|
|
||||||
|
|
||||||
uo[Multimethod::index(lir::Call, C)] = CAST1(callC);
|
|
||||||
uo[Multimethod::index(lir::Call, R)] = CAST1(callR);
|
|
||||||
|
|
||||||
uo[Multimethod::index(lir::AlignedCall, C)] = CAST1(callC);
|
|
||||||
uo[Multimethod::index(lir::AlignedCall, R)] = CAST1(callR);
|
|
||||||
|
|
||||||
bo[index(c, lir::Move, R, R)] = CAST2(moveRR);
|
|
||||||
bo[index(c, lir::Move, C, R)] = CAST2(moveCR);
|
|
||||||
bo[index(c, lir::Move, C, M)] = CAST2(moveCM);
|
|
||||||
bo[index(c, lir::Move, M, R)] = CAST2(moveMR);
|
|
||||||
bo[index(c, lir::Move, R, M)] = CAST2(moveRM);
|
|
||||||
bo[index(c, lir::Move, A, R)] = CAST2(moveAR);
|
|
||||||
|
|
||||||
bo[index(c, lir::MoveZ, R, R)] = CAST2(moveZRR);
|
|
||||||
bo[index(c, lir::MoveZ, M, R)] = CAST2(moveZMR);
|
|
||||||
bo[index(c, lir::MoveZ, C, R)] = CAST2(moveCR);
|
|
||||||
|
|
||||||
bo[index(c, lir::Negate, R, R)] = CAST2(negateRR);
|
|
||||||
|
|
||||||
to[index(c, lir::Add, R)] = CAST3(addR);
|
|
||||||
to[index(c, lir::Add, C)] = CAST3(addC);
|
|
||||||
|
|
||||||
to[index(c, lir::Subtract, R)] = CAST3(subR);
|
|
||||||
to[index(c, lir::Subtract, C)] = CAST3(subC);
|
|
||||||
|
|
||||||
to[index(c, lir::Multiply, R)] = CAST3(multiplyR);
|
|
||||||
|
|
||||||
to[index(c, lir::Divide, R)] = CAST3(divideR);
|
|
||||||
|
|
||||||
to[index(c, lir::Remainder, R)] = CAST3(remainderR);
|
|
||||||
|
|
||||||
to[index(c, lir::ShiftLeft, R)] = CAST3(shiftLeftR);
|
|
||||||
to[index(c, lir::ShiftLeft, C)] = CAST3(shiftLeftC);
|
|
||||||
|
|
||||||
to[index(c, lir::ShiftRight, R)] = CAST3(shiftRightR);
|
|
||||||
to[index(c, lir::ShiftRight, C)] = CAST3(shiftRightC);
|
|
||||||
|
|
||||||
to[index(c, lir::UnsignedShiftRight, R)] = CAST3(unsignedShiftRightR);
|
|
||||||
to[index(c, lir::UnsignedShiftRight, C)] = CAST3(unsignedShiftRightC);
|
|
||||||
|
|
||||||
to[index(c, lir::And, C)] = CAST3(andC);
|
|
||||||
to[index(c, lir::And, R)] = CAST3(andR);
|
|
||||||
|
|
||||||
to[index(c, lir::Or, C)] = CAST3(orC);
|
|
||||||
to[index(c, lir::Or, R)] = CAST3(orR);
|
|
||||||
|
|
||||||
to[index(c, lir::Xor, C)] = CAST3(xorC);
|
|
||||||
to[index(c, lir::Xor, R)] = CAST3(xorR);
|
|
||||||
|
|
||||||
bro[branchIndex(c, R, R)] = CAST_BRANCH(branchRR);
|
|
||||||
bro[branchIndex(c, C, R)] = CAST_BRANCH(branchCR);
|
|
||||||
bro[branchIndex(c, C, M)] = CAST_BRANCH(branchCM);
|
|
||||||
bro[branchIndex(c, R, M)] = CAST_BRANCH(branchRM);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
@ -1,41 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 AVIAN_CODEGEN_ASSEMBLER_POWERPC_MULTIMETHOD_H
|
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_MULTIMETHOD_H
|
|
||||||
|
|
||||||
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
|
||||||
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
|
|
||||||
#define CAST3(x) reinterpret_cast<TernaryOperationType>(x)
|
|
||||||
#define CAST_BRANCH(x) reinterpret_cast<BranchOperationType>(x)
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
unsigned index(ArchitectureContext*,
|
|
||||||
lir::BinaryOperation operation,
|
|
||||||
lir::OperandType operand1,
|
|
||||||
lir::OperandType operand2);
|
|
||||||
|
|
||||||
unsigned index(ArchitectureContext* c UNUSED,
|
|
||||||
lir::TernaryOperation operation,
|
|
||||||
lir::OperandType operand1);
|
|
||||||
|
|
||||||
unsigned branchIndex(ArchitectureContext* c UNUSED, lir::OperandType operand1,
|
|
||||||
lir::OperandType operand2);
|
|
||||||
|
|
||||||
void populateTables(ArchitectureContext* c);
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_MULTIMETHOD_H
|
|
File diff suppressed because it is too large
Load Diff
@ -1,197 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 AVIAN_CODEGEN_ASSEMBLER_POWERPC_OPERATIONS_H
|
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_OPERATIONS_H
|
|
||||||
|
|
||||||
#include "context.h"
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
inline void emit(Context* con, int code) { con->code.append4(vm::targetV4(code)); }
|
|
||||||
inline int newTemp(Context* con) { return con->client->acquireTemporary(); }
|
|
||||||
inline void freeTemp(Context* con, int r) { con->client->releaseTemporary(r); }
|
|
||||||
inline int64_t getValue(lir::Constant* c) { return c->value->value(); }
|
|
||||||
|
|
||||||
void andC(Context* c, unsigned size, lir::Constant* a,
|
|
||||||
lir::Register* b, lir::Register* dst);
|
|
||||||
|
|
||||||
void shiftLeftR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void moveRR(Context* c, unsigned srcSize, lir::Register* src,
|
|
||||||
unsigned dstSize, lir::Register* dst);
|
|
||||||
|
|
||||||
void shiftLeftC(Context* con, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void shiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void shiftRightC(Context* con, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void unsignedShiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void unsignedShiftRightC(Context* con, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void jumpR(Context* c, unsigned size UNUSED, lir::Register* target);
|
|
||||||
|
|
||||||
void swapRR(Context* c, unsigned aSize, lir::Register* a,
|
|
||||||
unsigned bSize, lir::Register* b);
|
|
||||||
|
|
||||||
void moveRR(Context* c, unsigned srcSize, lir::Register* src,
|
|
||||||
unsigned dstSize, lir::Register* dst);
|
|
||||||
|
|
||||||
void moveZRR(Context* c, unsigned srcSize, lir::Register* src,
|
|
||||||
unsigned, lir::Register* dst);
|
|
||||||
|
|
||||||
void moveCR2(Context* c, unsigned, lir::Constant* src,
|
|
||||||
unsigned dstSize, lir::Register* dst, unsigned promiseOffset);
|
|
||||||
|
|
||||||
void moveCR(Context* c, unsigned srcSize, lir::Constant* src,
|
|
||||||
unsigned dstSize, lir::Register* dst);
|
|
||||||
|
|
||||||
void addR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void addC(Context* con, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void subR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void subC(Context* c, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void multiplyR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void divideR(Context* con, unsigned size UNUSED, lir::Register* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
void remainderR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t);
|
|
||||||
|
|
||||||
int
|
|
||||||
normalize(Context* c, int offset, int index, unsigned scale,
|
|
||||||
bool* preserveIndex, bool* release);
|
|
||||||
|
|
||||||
void store(Context* c, unsigned size, lir::Register* src,
|
|
||||||
int base, int offset, int index, unsigned scale, bool preserveIndex);
|
|
||||||
|
|
||||||
void moveRM(Context* c, unsigned srcSize, lir::Register* src,
|
|
||||||
unsigned dstSize UNUSED, lir::Memory* dst);
|
|
||||||
|
|
||||||
void moveAndUpdateRM(Context* c, unsigned srcSize UNUSED, lir::Register* src,
|
|
||||||
unsigned dstSize UNUSED, lir::Memory* dst);
|
|
||||||
|
|
||||||
void load(Context* c, unsigned srcSize, int base, int offset, int index,
|
|
||||||
unsigned scale, unsigned dstSize, lir::Register* dst,
|
|
||||||
bool preserveIndex, bool signExtend);
|
|
||||||
|
|
||||||
void moveMR(Context* c, unsigned srcSize, lir::Memory* src,
|
|
||||||
unsigned dstSize, lir::Register* dst);
|
|
||||||
|
|
||||||
void moveZMR(Context* c, unsigned srcSize, lir::Memory* src,
|
|
||||||
unsigned dstSize, lir::Register* dst);
|
|
||||||
|
|
||||||
void andR(Context* c, unsigned size, lir::Register* a,
|
|
||||||
lir::Register* b, lir::Register* dst);
|
|
||||||
|
|
||||||
void andC(Context* c, unsigned size, lir::Constant* a,
|
|
||||||
lir::Register* b, lir::Register* dst);
|
|
||||||
|
|
||||||
void orR(Context* c, unsigned size, lir::Register* a,
|
|
||||||
lir::Register* b, lir::Register* dst);
|
|
||||||
|
|
||||||
void orC(Context* c, unsigned size, lir::Constant* a,
|
|
||||||
lir::Register* b, lir::Register* dst);
|
|
||||||
|
|
||||||
void xorR(Context* c, unsigned size, lir::Register* a,
|
|
||||||
lir::Register* b, lir::Register* dst);
|
|
||||||
|
|
||||||
void xorC(Context* c, unsigned size, lir::Constant* a,
|
|
||||||
lir::Register* b, lir::Register* dst);
|
|
||||||
|
|
||||||
void moveAR2(Context* c, unsigned srcSize UNUSED, lir::Address* src,
|
|
||||||
unsigned dstSize, lir::Register* dst, unsigned promiseOffset);
|
|
||||||
|
|
||||||
void moveAR(Context* c, unsigned srcSize, lir::Address* src,
|
|
||||||
unsigned dstSize, lir::Register* dst);
|
|
||||||
|
|
||||||
void compareRR(Context* c, unsigned aSize UNUSED, lir::Register* a,
|
|
||||||
unsigned bSize UNUSED, lir::Register* b);
|
|
||||||
|
|
||||||
void compareCR(Context* c, unsigned aSize, lir::Constant* a,
|
|
||||||
unsigned bSize, lir::Register* b);
|
|
||||||
|
|
||||||
void compareCM(Context* c, unsigned aSize, lir::Constant* a,
|
|
||||||
unsigned bSize, lir::Memory* b);
|
|
||||||
|
|
||||||
void compareRM(Context* c, unsigned aSize, lir::Register* a,
|
|
||||||
unsigned bSize, lir::Memory* b);
|
|
||||||
|
|
||||||
void compareUnsignedRR(Context* c, unsigned aSize UNUSED, lir::Register* a,
|
|
||||||
unsigned bSize UNUSED, lir::Register* b);
|
|
||||||
|
|
||||||
void compareUnsignedCR(Context* c, unsigned aSize, lir::Constant* a,
|
|
||||||
unsigned bSize, lir::Register* b);
|
|
||||||
|
|
||||||
int32_t branch(Context* c, lir::TernaryOperation op);
|
|
||||||
|
|
||||||
void conditional(Context* c, int32_t branch, lir::Constant* target);
|
|
||||||
|
|
||||||
void branch(Context* c, lir::TernaryOperation op, lir::Constant* target);
|
|
||||||
|
|
||||||
void branchLong(Context* c, lir::TernaryOperation op, lir::Operand* al,
|
|
||||||
lir::Operand* ah, lir::Operand* bl,
|
|
||||||
lir::Operand* bh, lir::Constant* target,
|
|
||||||
BinaryOperationType compareSigned,
|
|
||||||
BinaryOperationType compareUnsigned);
|
|
||||||
|
|
||||||
void branchRR(Context* c, lir::TernaryOperation op, unsigned size,
|
|
||||||
lir::Register* a, lir::Register* b,
|
|
||||||
lir::Constant* target);
|
|
||||||
|
|
||||||
void branchCR(Context* c, lir::TernaryOperation op, unsigned size,
|
|
||||||
lir::Constant* a, lir::Register* b,
|
|
||||||
lir::Constant* target);
|
|
||||||
|
|
||||||
void branchRM(Context* c, lir::TernaryOperation op, unsigned size,
|
|
||||||
lir::Register* a, lir::Memory* b,
|
|
||||||
lir::Constant* target);
|
|
||||||
|
|
||||||
void branchCM(Context* c, lir::TernaryOperation op, unsigned size,
|
|
||||||
lir::Constant* a, lir::Memory* b,
|
|
||||||
lir::Constant* target);
|
|
||||||
|
|
||||||
void moveCM(Context* c, unsigned srcSize, lir::Constant* src,
|
|
||||||
unsigned dstSize, lir::Memory* dst);
|
|
||||||
|
|
||||||
void negateRR(Context* c, unsigned srcSize, lir::Register* src,
|
|
||||||
unsigned dstSize UNUSED, lir::Register* dst);
|
|
||||||
|
|
||||||
void callR(Context* c, unsigned size UNUSED, lir::Register* target);
|
|
||||||
|
|
||||||
void callC(Context* c, unsigned size UNUSED, lir::Constant* target);
|
|
||||||
|
|
||||||
void longCallC(Context* c, unsigned size UNUSED, lir::Constant* target);
|
|
||||||
|
|
||||||
void alignedLongCallC(Context* c, unsigned size UNUSED, lir::Constant* target);
|
|
||||||
|
|
||||||
void longJumpC(Context* c, unsigned size UNUSED, lir::Constant* target);
|
|
||||||
|
|
||||||
void alignedLongJumpC(Context* c, unsigned size UNUSED, lir::Constant* target);
|
|
||||||
|
|
||||||
void jumpC(Context* c, unsigned size UNUSED, lir::Constant* target);
|
|
||||||
|
|
||||||
void return_(Context* c);
|
|
||||||
|
|
||||||
void trap(Context* c);
|
|
||||||
|
|
||||||
void memoryBarrier(Context* c);
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_OPERATIONS_H
|
|
@ -1,23 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 AVIAN_CODEGEN_ASSEMBLER_POWERPC_REGISTERS_H
|
|
||||||
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_REGISTERS_H
|
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
namespace powerpc {
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace powerpc
|
|
||||||
} // namespace codegen
|
|
||||||
} // namespace avian
|
|
||||||
|
|
||||||
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_REGISTERS_H
|
|
@ -29,8 +29,6 @@ Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures
|
|||||||
return makeArchitectureX86(system, useNativeFeatures);
|
return makeArchitectureX86(system, useNativeFeatures);
|
||||||
#elif AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM
|
#elif AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM
|
||||||
return makeArchitectureArm(system, useNativeFeatures);
|
return makeArchitectureArm(system, useNativeFeatures);
|
||||||
#elif AVIAN_TARGET_ARCH == AVIAN_ARCH_POWERPC
|
|
||||||
return makeArchitecturePowerpc(system, useNativeFeatures);
|
|
||||||
#else
|
#else
|
||||||
#error "Unsupported codegen target"
|
#error "Unsupported codegen target"
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,295 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 "avian/types.h"
|
|
||||||
#include "avian/target-fields.h"
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
#define BYTES_PER_WORD 4
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
# define GLOBAL(x) _##x
|
|
||||||
# define LOCAL(x) L##x
|
|
||||||
# define LINKAGE_AREA 6
|
|
||||||
# define RETURN_ADDRESS_OFFSET 8
|
|
||||||
#else
|
|
||||||
# define GLOBAL(x) x
|
|
||||||
# define LOCAL(x) .L##x
|
|
||||||
# define LINKAGE_AREA 2
|
|
||||||
# define RETURN_ADDRESS_OFFSET 4
|
|
||||||
# include "powerpc-regs.S"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ARGUMENT_BASE BYTES_PER_WORD * LINKAGE_AREA
|
|
||||||
|
|
||||||
#define CONTINUATION_NEXT 4
|
|
||||||
#define CONTINUATION_ADDRESS 16
|
|
||||||
#define CONTINUATION_RETURN_ADDRESS_OFFSET 20
|
|
||||||
#define CONTINUATION_FRAME_POINTER_OFFSET 24
|
|
||||||
#define CONTINUATION_LENGTH 28
|
|
||||||
#define CONTINUATION_BODY 32
|
|
||||||
|
|
||||||
.globl GLOBAL(vmInvoke)
|
|
||||||
GLOBAL(vmInvoke):
|
|
||||||
// save return address
|
|
||||||
mflr r0
|
|
||||||
stw r0,RETURN_ADDRESS_OFFSET(r1)
|
|
||||||
|
|
||||||
// r3: thread
|
|
||||||
// r4: function
|
|
||||||
// r5: arguments
|
|
||||||
// r6: argumentFootprint
|
|
||||||
// r7: frameSize
|
|
||||||
// r8: returnType
|
|
||||||
|
|
||||||
// r9: temporary
|
|
||||||
|
|
||||||
// allocate stack space, adding room for callee-saved registers and
|
|
||||||
// return type
|
|
||||||
subfic r9,r7,-80
|
|
||||||
stwux r1,r1,r9
|
|
||||||
|
|
||||||
// save callee-saved registers
|
|
||||||
add r9,r7,r1
|
|
||||||
|
|
||||||
stw r13,0(r9)
|
|
||||||
stw r14,4(r9)
|
|
||||||
stw r15,8(r9)
|
|
||||||
stw r16,12(r9)
|
|
||||||
stw r17,16(r9)
|
|
||||||
stw r18,20(r9)
|
|
||||||
stw r19,24(r9)
|
|
||||||
stw r20,28(r9)
|
|
||||||
stw r21,32(r9)
|
|
||||||
stw r22,36(r9)
|
|
||||||
stw r23,40(r9)
|
|
||||||
stw r24,44(r9)
|
|
||||||
stw r25,48(r9)
|
|
||||||
stw r26,52(r9)
|
|
||||||
stw r27,56(r9)
|
|
||||||
stw r28,60(r9)
|
|
||||||
stw r29,64(r9)
|
|
||||||
stw r30,68(r9)
|
|
||||||
stw r31,72(r9)
|
|
||||||
|
|
||||||
// save return type
|
|
||||||
stw r8,76(r9)
|
|
||||||
|
|
||||||
// we use r13 to hold the thread pointer, by convention
|
|
||||||
mr r13,r3
|
|
||||||
|
|
||||||
// copy arguments into place
|
|
||||||
li r16,0
|
|
||||||
addi r18,r1,ARGUMENT_BASE
|
|
||||||
b LOCAL(vmInvoke_argumentTest)
|
|
||||||
|
|
||||||
LOCAL(vmInvoke_argumentLoop):
|
|
||||||
lwzx r17,r16,r5
|
|
||||||
stwx r17,r16,r18
|
|
||||||
addi r16,r16,BYTES_PER_WORD
|
|
||||||
|
|
||||||
LOCAL(vmInvoke_argumentTest):
|
|
||||||
cmplw r16,r6
|
|
||||||
blt LOCAL(vmInvoke_argumentLoop)
|
|
||||||
|
|
||||||
// load and call function address
|
|
||||||
mtctr r4
|
|
||||||
bctrl
|
|
||||||
|
|
||||||
.globl GLOBAL(vmInvoke_returnAddress)
|
|
||||||
GLOBAL(vmInvoke_returnAddress):
|
|
||||||
// restore stack pointer
|
|
||||||
lwz r1,0(r1)
|
|
||||||
|
|
||||||
// clear MyThread::stack to avoid confusing another thread calling
|
|
||||||
// java.lang.Thread.getStackTrace on this one. See
|
|
||||||
// MyProcess::getStackTrace in compile.cpp for details on how we get
|
|
||||||
// a reliable stack trace from a thread that might be interrupted at
|
|
||||||
// any point in its execution.
|
|
||||||
li r5,0
|
|
||||||
stw r5,TARGET_THREAD_STACK(r13)
|
|
||||||
|
|
||||||
.globl GLOBAL(vmInvoke_safeStack)
|
|
||||||
GLOBAL(vmInvoke_safeStack):
|
|
||||||
|
|
||||||
#ifdef AVIAN_CONTINUATIONS
|
|
||||||
// call the next continuation, if any
|
|
||||||
lwz r5,TARGET_THREAD_CONTINUATION(r13)
|
|
||||||
cmplwi r5,0
|
|
||||||
beq LOCAL(vmInvoke_exit)
|
|
||||||
|
|
||||||
lwz r6,CONTINUATION_LENGTH(r5)
|
|
||||||
slwi r6,r6,2
|
|
||||||
subfic r7,r6,-80
|
|
||||||
stwux r1,r1,r7
|
|
||||||
|
|
||||||
addi r7,r5,CONTINUATION_BODY
|
|
||||||
|
|
||||||
li r8,0
|
|
||||||
addi r10,r1,ARGUMENT_BASE
|
|
||||||
b LOCAL(vmInvoke_continuationTest)
|
|
||||||
|
|
||||||
LOCAL(vmInvoke_continuationLoop):
|
|
||||||
lwzx r9,r7,r8
|
|
||||||
stwx r9,r10,r8
|
|
||||||
addi r8,r8,4
|
|
||||||
|
|
||||||
LOCAL(vmInvoke_continuationTest):
|
|
||||||
cmplw r8,r6
|
|
||||||
ble LOCAL(vmInvoke_continuationLoop)
|
|
||||||
|
|
||||||
lwz r7,CONTINUATION_RETURN_ADDRESS_OFFSET(r5)
|
|
||||||
bl LOCAL(vmInvoke_getPC)
|
|
||||||
|
|
||||||
LOCAL(vmInvoke_getPC):
|
|
||||||
mflr r10
|
|
||||||
#ifdef __APPLE__
|
|
||||||
la r10,lo16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmInvoke_getPC))(r10)
|
|
||||||
#else
|
|
||||||
lwz r10,LOCAL(vmInvoke_returnAddress_address)-LOCAL(vmInvoke_getPC)(r10)
|
|
||||||
#endif
|
|
||||||
stwx r10,r1,r7
|
|
||||||
|
|
||||||
lwz r7,CONTINUATION_FRAME_POINTER_OFFSET(r5)
|
|
||||||
lwz r8,0(r1)
|
|
||||||
add r7,r7,r1
|
|
||||||
stw r8,0(r7)
|
|
||||||
stw r7,0(r1)
|
|
||||||
|
|
||||||
lwz r7,CONTINUATION_NEXT(r5)
|
|
||||||
stw r7,TARGET_THREAD_CONTINUATION(r13)
|
|
||||||
|
|
||||||
// call the continuation unless we're handling an exception
|
|
||||||
lwz r7,TARGET_THREAD_EXCEPTION(r13)
|
|
||||||
cmpwi r7,0
|
|
||||||
bne LOCAL(vmInvoke_handleException)
|
|
||||||
lwz r7,CONTINUATION_ADDRESS(r5)
|
|
||||||
mtctr r7
|
|
||||||
bctr
|
|
||||||
|
|
||||||
LOCAL(vmInvoke_handleException):
|
|
||||||
// we're handling an exception - call the exception handler instead
|
|
||||||
li r8,0
|
|
||||||
stw r8,TARGET_THREAD_EXCEPTION(r13)
|
|
||||||
lwz r8,TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT(r13)
|
|
||||||
lwz r9,0(r1)
|
|
||||||
subfic r8,r8,0
|
|
||||||
stwux r9,r1,r8
|
|
||||||
lwz r8,TARGET_THREAD_EXCEPTIONOFFSET(r13)
|
|
||||||
stwx r7,r1,r8
|
|
||||||
|
|
||||||
lwz r7,TARGET_THREAD_EXCEPTIONHANDLER(r13)
|
|
||||||
mtctr r7
|
|
||||||
bctr
|
|
||||||
|
|
||||||
LOCAL(vmInvoke_exit):
|
|
||||||
#endif // AVIAN_CONTINUATIONS
|
|
||||||
|
|
||||||
// restore callee-saved registers
|
|
||||||
subi r9,r1,80
|
|
||||||
|
|
||||||
lwz r13,0(r9)
|
|
||||||
lwz r14,4(r9)
|
|
||||||
lwz r15,8(r9)
|
|
||||||
lwz r16,12(r9)
|
|
||||||
lwz r17,16(r9)
|
|
||||||
lwz r18,20(r9)
|
|
||||||
lwz r19,24(r9)
|
|
||||||
lwz r20,28(r9)
|
|
||||||
lwz r21,32(r9)
|
|
||||||
lwz r22,36(r9)
|
|
||||||
lwz r23,40(r9)
|
|
||||||
lwz r24,44(r9)
|
|
||||||
lwz r25,48(r9)
|
|
||||||
lwz r26,52(r9)
|
|
||||||
lwz r27,56(r9)
|
|
||||||
lwz r28,60(r9)
|
|
||||||
lwz r29,64(r9)
|
|
||||||
lwz r30,68(r9)
|
|
||||||
lwz r31,72(r9)
|
|
||||||
|
|
||||||
// handle return value based on expected type
|
|
||||||
lwz r8,76(r9)
|
|
||||||
|
|
||||||
LOCAL(vmInvoke_return):
|
|
||||||
// load return address
|
|
||||||
lwz r0,RETURN_ADDRESS_OFFSET(r1)
|
|
||||||
mtlr r0
|
|
||||||
|
|
||||||
// return
|
|
||||||
blr
|
|
||||||
|
|
||||||
#ifndef __APPLE__
|
|
||||||
LOCAL(vmInvoke_returnAddress_address):
|
|
||||||
.long GLOBAL(vmInvoke_returnAddress)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.globl GLOBAL(vmJumpAndInvoke)
|
|
||||||
GLOBAL(vmJumpAndInvoke):
|
|
||||||
#ifdef AVIAN_CONTINUATIONS
|
|
||||||
// r3: thread
|
|
||||||
// r4: address
|
|
||||||
// r5: stack
|
|
||||||
// r6: argumentFootprint
|
|
||||||
// r7: arguments
|
|
||||||
// r8: frameSize
|
|
||||||
|
|
||||||
// restore (pseudo)-stack pointer (we don't want to touch the real
|
|
||||||
// stack pointer, since we haven't copied the arguments yet)
|
|
||||||
lwz r5,0(r5)
|
|
||||||
|
|
||||||
// make everything between r1 and r5 one big stack frame while we
|
|
||||||
// shuffle things around
|
|
||||||
stw r5,0(r1)
|
|
||||||
|
|
||||||
// allocate new frame, adding room for callee-saved registers
|
|
||||||
subfic r10,r8,-80
|
|
||||||
stwux r5,r5,r10
|
|
||||||
|
|
||||||
mr r13,r3
|
|
||||||
|
|
||||||
// copy arguments into place
|
|
||||||
li r8,0
|
|
||||||
addi r11,r5,ARGUMENT_BASE
|
|
||||||
b LOCAL(vmJumpAndInvoke_argumentTest)
|
|
||||||
|
|
||||||
LOCAL(vmJumpAndInvoke_argumentLoop):
|
|
||||||
lwzx r12,r7,r8
|
|
||||||
stwx r12,r11,r8
|
|
||||||
addi r8,r8,4
|
|
||||||
|
|
||||||
LOCAL(vmJumpAndInvoke_argumentTest):
|
|
||||||
cmplw r8,r6
|
|
||||||
ble LOCAL(vmJumpAndInvoke_argumentLoop)
|
|
||||||
|
|
||||||
// the arguments have been copied, so we can set the real stack
|
|
||||||
// pointer now
|
|
||||||
mr r1,r5
|
|
||||||
|
|
||||||
// set return address to vmInvoke_returnAddress
|
|
||||||
bl LOCAL(vmJumpAndInvoke_getPC)
|
|
||||||
|
|
||||||
LOCAL(vmJumpAndInvoke_getPC):
|
|
||||||
mflr r10
|
|
||||||
#ifdef __APPLE__
|
|
||||||
la r10,lo16(GLOBAL(vmInvoke_returnAddress)-LOCAL(vmJumpAndInvoke_getPC))(r10)
|
|
||||||
#else
|
|
||||||
lwz r10,LOCAL(vmInvoke_returnAddress_address)-LOCAL(vmJumpAndInvoke_getPC)(r10)
|
|
||||||
#endif
|
|
||||||
mtlr r10
|
|
||||||
|
|
||||||
mtctr r4
|
|
||||||
bctr
|
|
||||||
#else // not AVIAN_CONTINUATIONS
|
|
||||||
// vmJumpAndInvoke should only be called when continuations are
|
|
||||||
// enabled
|
|
||||||
trap
|
|
||||||
#endif // not AVIAN_CONTINUATIONS
|
|
@ -8981,10 +8981,10 @@ class MyProcessor: public Processor {
|
|||||||
} else if (isThunk(t, ip) or isVirtualThunk(t, ip)) {
|
} else if (isThunk(t, ip) or isVirtualThunk(t, ip)) {
|
||||||
// we caught the thread in a thunk where the stack register
|
// we caught the thread in a thunk where the stack register
|
||||||
// indicates the most recent Java frame on the stack
|
// indicates the most recent Java frame on the stack
|
||||||
|
|
||||||
// On e.g. x86, the return address will have already been
|
// On e.g. x86, the return address will have already been
|
||||||
// pushed onto the stack, in which case we use getIp to
|
// pushed onto the stack, in which case we use getIp to
|
||||||
// retrieve it. On e.g. PowerPC and ARM, it will be in the
|
// retrieve it. On e.g. ARM, it will be in the
|
||||||
// link register. Note that we can't just check if the link
|
// link register. Note that we can't just check if the link
|
||||||
// argument is null here, since we use ecx/rcx as a
|
// argument is null here, since we use ecx/rcx as a
|
||||||
// pseudo-link register on x86 for the purpose of tail
|
// pseudo-link register on x86 for the purpose of tail
|
||||||
|
259
src/powerpc.S
259
src/powerpc.S
@ -1,259 +0,0 @@
|
|||||||
/* Copyright (c) 2008-2014, 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 "avian/types.h"
|
|
||||||
|
|
||||||
.text
|
|
||||||
|
|
||||||
#define BYTES_PER_WORD 4
|
|
||||||
#define GPR_COUNT 8
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
# define GLOBAL(x) _##x
|
|
||||||
# define LOCAL(x) L##x
|
|
||||||
# define LINKAGE_AREA 6
|
|
||||||
# define MEMORY_BASE BYTES_PER_WORD * (LINKAGE_AREA + GPR_COUNT)
|
|
||||||
# define RETURN_ADDRESS_OFFSET 8
|
|
||||||
#else
|
|
||||||
# define GLOBAL(x) x
|
|
||||||
# define LOCAL(x) .L##x
|
|
||||||
# define LINKAGE_AREA 2
|
|
||||||
# define MEMORY_BASE BYTES_PER_WORD * LINKAGE_AREA
|
|
||||||
# define RETURN_ADDRESS_OFFSET 4
|
|
||||||
# include "powerpc-regs.S"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.globl GLOBAL(vmNativeCall)
|
|
||||||
GLOBAL(vmNativeCall):
|
|
||||||
// save return address
|
|
||||||
mflr r0
|
|
||||||
stw r0,RETURN_ADDRESS_OFFSET(r1)
|
|
||||||
|
|
||||||
// r3 aka r13: function
|
|
||||||
// r4 : stackTotal
|
|
||||||
// r5 : memoryTable
|
|
||||||
// r6 : memoryCount
|
|
||||||
// r7 : memoryBase
|
|
||||||
// r8 : gprTable
|
|
||||||
// r9 : fprTable
|
|
||||||
// r10 aka r14: returnType
|
|
||||||
|
|
||||||
// r15 : stack frame size
|
|
||||||
// r16 : temporary
|
|
||||||
// r17 : temporary
|
|
||||||
// r18 : temporary
|
|
||||||
|
|
||||||
// allocate stack space, adding room for callee-saved registers and
|
|
||||||
// scratch space for copying a FP return value into GPRs
|
|
||||||
subfic r11,r4,-48
|
|
||||||
stwux r1,r1,r11
|
|
||||||
|
|
||||||
// save callee-saved registers used for local variables
|
|
||||||
add r11,r4,r1
|
|
||||||
|
|
||||||
// save registers used for local variables
|
|
||||||
stw r13,0(r11)
|
|
||||||
stw r14,4(r11)
|
|
||||||
stw r15,8(r11)
|
|
||||||
stw r16,12(r11)
|
|
||||||
stw r17,16(r11)
|
|
||||||
stw r18,20(r11)
|
|
||||||
stw r19,24(r11)
|
|
||||||
|
|
||||||
// remember where we saved the local variables
|
|
||||||
mr r19,r11
|
|
||||||
|
|
||||||
// save our argument registers so we can clobber them
|
|
||||||
mr r13,r3
|
|
||||||
mr r14,r10
|
|
||||||
|
|
||||||
li r16,0
|
|
||||||
b LOCAL(test)
|
|
||||||
|
|
||||||
LOCAL(loop):
|
|
||||||
lwzx r17,r16,r5
|
|
||||||
add r18,r16,r7
|
|
||||||
stwx r17,r18,r1
|
|
||||||
addi r16,r16,BYTES_PER_WORD
|
|
||||||
|
|
||||||
LOCAL(test):
|
|
||||||
cmplw r16,r6
|
|
||||||
blt LOCAL(loop)
|
|
||||||
|
|
||||||
// do we need to load the floating point registers?
|
|
||||||
cmpwi r9,0
|
|
||||||
beq LOCAL(gpr)
|
|
||||||
|
|
||||||
// yes, we do
|
|
||||||
lfd f1,0(r9)
|
|
||||||
lfd f2,8(r9)
|
|
||||||
lfd f3,16(r9)
|
|
||||||
lfd f4,24(r9)
|
|
||||||
lfd f5,32(r9)
|
|
||||||
lfd f6,40(r9)
|
|
||||||
lfd f7,48(r9)
|
|
||||||
lfd f8,56(r9)
|
|
||||||
#ifdef __APPLE__
|
|
||||||
lfd f9,64(r9)
|
|
||||||
lfd f10,72(r9)
|
|
||||||
lfd f11,80(r9)
|
|
||||||
lfd f12,88(r9)
|
|
||||||
lfd f13,96(r9)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LOCAL(gpr):
|
|
||||||
// do we need to load the general-purpose registers?
|
|
||||||
cmpwi r8,0
|
|
||||||
beq LOCAL(call)
|
|
||||||
|
|
||||||
// yes, we do
|
|
||||||
mr r16,r8
|
|
||||||
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)
|
|
||||||
|
|
||||||
LOCAL(call):
|
|
||||||
// load and call function address
|
|
||||||
mtctr r13
|
|
||||||
bctrl
|
|
||||||
|
|
||||||
// handle return value based on expected type
|
|
||||||
cmpwi r14,VOID_TYPE
|
|
||||||
bne LOCAL(float)
|
|
||||||
b LOCAL(exit)
|
|
||||||
|
|
||||||
LOCAL(float):
|
|
||||||
cmpwi r14,FLOAT_TYPE
|
|
||||||
bne LOCAL(double)
|
|
||||||
stfs f1,32(r19)
|
|
||||||
lwz r4,32(r19)
|
|
||||||
b LOCAL(exit)
|
|
||||||
LOCAL(double):
|
|
||||||
cmpwi r14,DOUBLE_TYPE
|
|
||||||
bne LOCAL(int64)
|
|
||||||
stfd f1,32(r19)
|
|
||||||
lwz r3,32(r19)
|
|
||||||
lwz r4,36(r19)
|
|
||||||
b LOCAL(exit)
|
|
||||||
LOCAL(int64):
|
|
||||||
cmpwi r14,INT64_TYPE
|
|
||||||
beq LOCAL(exit)
|
|
||||||
mr r4,r3
|
|
||||||
b LOCAL(exit)
|
|
||||||
|
|
||||||
LOCAL(copy):
|
|
||||||
// move floating point return value to GPRs via memory
|
|
||||||
stfd f1,32(r19)
|
|
||||||
lwz r3,32(r19)
|
|
||||||
lwz r4,36(r19)
|
|
||||||
b LOCAL(exit)
|
|
||||||
|
|
||||||
LOCAL(exit):
|
|
||||||
// restore callee-saved registers used for local variables
|
|
||||||
lwz r13,0(r19)
|
|
||||||
lwz r14,4(r19)
|
|
||||||
lwz r15,8(r19)
|
|
||||||
lwz r16,12(r19)
|
|
||||||
lwz r17,16(r19)
|
|
||||||
lwz r18,20(r19)
|
|
||||||
lwz r19,24(r19)
|
|
||||||
|
|
||||||
// restore stack pointer
|
|
||||||
lwz r1,0(r1)
|
|
||||||
|
|
||||||
// load return address
|
|
||||||
lwz r0,RETURN_ADDRESS_OFFSET(r1)
|
|
||||||
mtlr r0
|
|
||||||
|
|
||||||
// return
|
|
||||||
blr
|
|
||||||
|
|
||||||
.globl GLOBAL(vmJump)
|
|
||||||
GLOBAL(vmJump):
|
|
||||||
mtlr r3
|
|
||||||
mr r1,r5
|
|
||||||
mr r13,r6
|
|
||||||
mr r4,r7
|
|
||||||
mr r3,r8
|
|
||||||
blr
|
|
||||||
|
|
||||||
#define CHECKPOINT_THREAD 4
|
|
||||||
#define CHECKPOINT_STACK 24
|
|
||||||
|
|
||||||
.globl GLOBAL(vmRun)
|
|
||||||
GLOBAL(vmRun):
|
|
||||||
// r3: function
|
|
||||||
// r4: arguments
|
|
||||||
// r5: checkpoint
|
|
||||||
|
|
||||||
mflr r0
|
|
||||||
stw r0,RETURN_ADDRESS_OFFSET(r1)
|
|
||||||
|
|
||||||
stwu r1,-(MEMORY_BASE+88)(r1)
|
|
||||||
|
|
||||||
stw r13,MEMORY_BASE+0(r1)
|
|
||||||
stw r14,MEMORY_BASE+4(r1)
|
|
||||||
stw r15,MEMORY_BASE+8(r1)
|
|
||||||
stw r16,MEMORY_BASE+12(r1)
|
|
||||||
stw r17,MEMORY_BASE+16(r1)
|
|
||||||
stw r18,MEMORY_BASE+20(r1)
|
|
||||||
stw r19,MEMORY_BASE+24(r1)
|
|
||||||
stw r20,MEMORY_BASE+28(r1)
|
|
||||||
stw r21,MEMORY_BASE+32(r1)
|
|
||||||
stw r22,MEMORY_BASE+36(r1)
|
|
||||||
stw r23,MEMORY_BASE+40(r1)
|
|
||||||
stw r24,MEMORY_BASE+44(r1)
|
|
||||||
stw r25,MEMORY_BASE+48(r1)
|
|
||||||
stw r26,MEMORY_BASE+52(r1)
|
|
||||||
stw r27,MEMORY_BASE+56(r1)
|
|
||||||
stw r28,MEMORY_BASE+60(r1)
|
|
||||||
stw r29,MEMORY_BASE+64(r1)
|
|
||||||
stw r30,MEMORY_BASE+68(r1)
|
|
||||||
stw r31,MEMORY_BASE+72(r1)
|
|
||||||
|
|
||||||
stw r1,CHECKPOINT_STACK(r5)
|
|
||||||
|
|
||||||
mr r6,r3
|
|
||||||
lwz r3,CHECKPOINT_THREAD(r5)
|
|
||||||
|
|
||||||
mtctr r6
|
|
||||||
bctrl
|
|
||||||
|
|
||||||
.globl GLOBAL(vmRun_returnAddress)
|
|
||||||
GLOBAL(vmRun_returnAddress):
|
|
||||||
lwz r13,MEMORY_BASE+0(r1)
|
|
||||||
lwz r14,MEMORY_BASE+4(r1)
|
|
||||||
lwz r15,MEMORY_BASE+8(r1)
|
|
||||||
lwz r16,MEMORY_BASE+12(r1)
|
|
||||||
lwz r17,MEMORY_BASE+16(r1)
|
|
||||||
lwz r18,MEMORY_BASE+20(r1)
|
|
||||||
lwz r19,MEMORY_BASE+24(r1)
|
|
||||||
lwz r20,MEMORY_BASE+28(r1)
|
|
||||||
lwz r21,MEMORY_BASE+32(r1)
|
|
||||||
lwz r22,MEMORY_BASE+36(r1)
|
|
||||||
lwz r23,MEMORY_BASE+40(r1)
|
|
||||||
lwz r24,MEMORY_BASE+44(r1)
|
|
||||||
lwz r25,MEMORY_BASE+48(r1)
|
|
||||||
lwz r26,MEMORY_BASE+52(r1)
|
|
||||||
lwz r27,MEMORY_BASE+56(r1)
|
|
||||||
lwz r28,MEMORY_BASE+60(r1)
|
|
||||||
lwz r29,MEMORY_BASE+64(r1)
|
|
||||||
lwz r30,MEMORY_BASE+68(r1)
|
|
||||||
lwz r31,MEMORY_BASE+72(r1)
|
|
||||||
|
|
||||||
lwz r1,0(r1)
|
|
||||||
lwz r0,RETURN_ADDRESS_OFFSET(r1)
|
|
||||||
mtlr r0
|
|
||||||
blr
|
|
@ -1907,9 +1907,9 @@ main(int ac, const char** av)
|
|||||||
|
|
||||||
// todo: currently, the compiler cannot compile code with jumps or
|
// todo: currently, the compiler cannot compile code with jumps or
|
||||||
// calls spanning more than the maximum size of an immediate value
|
// calls spanning more than the maximum size of an immediate value
|
||||||
// in a branch instruction for the target architecture (~32MB on
|
// in a branch instruction for the target architecture (~32MB on ARM).
|
||||||
// PowerPC and ARM). When that limitation is removed, we'll be able
|
// When that limitation is removed, we'll be able to specify a
|
||||||
// to specify a capacity as large as we like here:
|
// capacity as large as we like here:
|
||||||
#if (AVIAN_TARGET_ARCH == AVIAN_ARCH_X86_64) \
|
#if (AVIAN_TARGET_ARCH == AVIAN_ARCH_X86_64) \
|
||||||
|| (AVIAN_TARGET_ARCH == AVIAN_ARCH_X86)
|
|| (AVIAN_TARGET_ARCH == AVIAN_ARCH_X86)
|
||||||
const unsigned CodeCapacity = 128 * 1024 * 1024;
|
const unsigned CodeCapacity = 128 * 1024 * 1024;
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
#define EM_386 3
|
#define EM_386 3
|
||||||
#define EM_X86_64 62
|
#define EM_X86_64 62
|
||||||
#define EM_ARM 40
|
#define EM_ARM 40
|
||||||
#define EM_PPC 20
|
|
||||||
|
|
||||||
#define SHT_PROGBITS 1
|
#define SHT_PROGBITS 1
|
||||||
#define SHT_SYMTAB 2
|
#define SHT_SYMTAB 2
|
||||||
@ -130,8 +129,6 @@ unsigned getElfPlatform(PlatformInfo::Architecture arch) {
|
|||||||
return EM_386;
|
return EM_386;
|
||||||
case PlatformInfo::Arm:
|
case PlatformInfo::Arm:
|
||||||
return EM_ARM;
|
return EM_ARM;
|
||||||
case PlatformInfo::PowerPC:
|
|
||||||
return EM_PPC;
|
|
||||||
default:
|
default:
|
||||||
return ~0;
|
return ~0;
|
||||||
}
|
}
|
||||||
@ -375,7 +372,6 @@ public:
|
|||||||
|
|
||||||
ElfPlatform<uint32_t> elfX86Platform(PlatformInfo::x86);
|
ElfPlatform<uint32_t> elfX86Platform(PlatformInfo::x86);
|
||||||
ElfPlatform<uint32_t> elfArmPlatform(PlatformInfo::Arm);
|
ElfPlatform<uint32_t> elfArmPlatform(PlatformInfo::Arm);
|
||||||
ElfPlatform<uint32_t, false> elfPowerPCPlatform(PlatformInfo::PowerPC);
|
|
||||||
ElfPlatform<uint64_t> elfX86_64Platform(PlatformInfo::x86_64);
|
ElfPlatform<uint64_t> elfX86_64Platform(PlatformInfo::x86_64);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -32,13 +32,11 @@
|
|||||||
|
|
||||||
#define CPU_TYPE_I386 7
|
#define CPU_TYPE_I386 7
|
||||||
#define CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64)
|
#define CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64)
|
||||||
#define CPU_TYPE_POWERPC 18
|
|
||||||
#define CPU_TYPE_ARM 12
|
#define CPU_TYPE_ARM 12
|
||||||
|
|
||||||
#define CPU_SUBTYPE_I386_ALL 3
|
#define CPU_SUBTYPE_I386_ALL 3
|
||||||
#define CPU_SUBTYPE_X86_64_ALL CPU_SUBTYPE_I386_ALL
|
#define CPU_SUBTYPE_X86_64_ALL CPU_SUBTYPE_I386_ALL
|
||||||
#define CPU_SUBTYPE_POWERPC_ALL 0
|
#define CPU_SUBTYPE_ARM_V7 9
|
||||||
#define CPU_SUBTYPE_ARM_V7 9
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -153,10 +151,6 @@ public:
|
|||||||
cpuType = CPU_TYPE_I386;
|
cpuType = CPU_TYPE_I386;
|
||||||
cpuSubType = CPU_SUBTYPE_I386_ALL;
|
cpuSubType = CPU_SUBTYPE_I386_ALL;
|
||||||
break;
|
break;
|
||||||
case PlatformInfo::PowerPC:
|
|
||||||
cpuType = CPU_TYPE_POWERPC;
|
|
||||||
cpuSubType = CPU_SUBTYPE_POWERPC_ALL;
|
|
||||||
break;
|
|
||||||
case PlatformInfo::Arm:
|
case PlatformInfo::Arm:
|
||||||
cpuType = CPU_TYPE_ARM;
|
cpuType = CPU_TYPE_ARM;
|
||||||
cpuSubType = CPU_SUBTYPE_ARM_V7;
|
cpuSubType = CPU_SUBTYPE_ARM_V7;
|
||||||
@ -293,7 +287,6 @@ public:
|
|||||||
|
|
||||||
MachOPlatform<uint32_t> darwinx86Platform(PlatformInfo::x86);
|
MachOPlatform<uint32_t> darwinx86Platform(PlatformInfo::x86);
|
||||||
MachOPlatform<uint32_t> darwinArmPlatform(PlatformInfo::Arm);
|
MachOPlatform<uint32_t> darwinArmPlatform(PlatformInfo::Arm);
|
||||||
MachOPlatform<uint32_t, false> darwinPowerPCPlatform(PlatformInfo::PowerPC);
|
|
||||||
MachOPlatform<uint64_t> darwinx86_64Platform(PlatformInfo::x86_64);
|
MachOPlatform<uint64_t> darwinx86_64Platform(PlatformInfo::x86_64);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -108,8 +108,6 @@ PlatformInfo::Architecture PlatformInfo::archFromString(const char* arch) {
|
|||||||
return x86;
|
return x86;
|
||||||
} else if(strcmp(arch, "x86_64") == 0) {
|
} else if(strcmp(arch, "x86_64") == 0) {
|
||||||
return x86_64;
|
return x86_64;
|
||||||
} else if(strcmp(arch, "powerpc") == 0) {
|
|
||||||
return PowerPC;
|
|
||||||
} else if(strcmp(arch, "arm") == 0) {
|
} else if(strcmp(arch, "arm") == 0) {
|
||||||
return Arm;
|
return Arm;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user