work in progress towards 64-bit ARM JIT support

This won't build, it's just a snapshot of what I have so far.

Conflicts:
	include/avian/codegen/architecture.h
	include/avian/codegen/registers.h
	src/codegen/compiler.cpp
	src/codegen/compiler/event.cpp
	src/codegen/compiler/site.cpp
	src/codegen/compiler/site.h
	src/codegen/registers.cpp
	src/codegen/target/arm/assembler.cpp
	src/codegen/target/arm/registers.h
This commit is contained in:
Joshua Warner 2014-12-05 15:58:52 -07:00 committed by Joel Dice
parent 4d9c649676
commit b3bd58aeff
7 changed files with 1362 additions and 31 deletions

View File

@ -28,8 +28,6 @@ namespace codegen {
class Assembler; class Assembler;
class RegisterFile;
class OperandMask { class OperandMask {
public: public:
uint8_t typeMask; uint8_t typeMask;

View File

@ -123,7 +123,7 @@ class Site {
virtual RegisterMask registerMask(Context*) virtual RegisterMask registerMask(Context*)
{ {
return 0; return RegisterMask(0);
} }
virtual bool isVolatile(Context*) virtual bool isVolatile(Context*)

View File

@ -39,7 +39,7 @@ namespace isa {
bool vfpSupported() bool vfpSupported()
{ {
// TODO: Use at runtime detection // TODO: Use at runtime detection
#if defined(__ARM_PCS_VFP) #if (defined __ARM_PCS_VFP) || (defined ARCH_arm64)
// armhf // armhf
return true; return true;
#else #else
@ -55,9 +55,9 @@ bool vfpSupported()
const RegisterFile MyRegisterFileWithoutFloats(GPR_MASK, 0); const RegisterFile MyRegisterFileWithoutFloats(GPR_MASK, 0);
const RegisterFile MyRegisterFileWithFloats(GPR_MASK, FPR_MASK); const RegisterFile MyRegisterFileWithFloats(GPR_MASK, FPR_MASK);
const unsigned FrameHeaderSize = 1; const unsigned FrameHeaderSize = TargetBytesPerWord / 4;
const unsigned StackAlignmentInBytes = 8; const unsigned StackAlignmentInBytes = TargetBytesPerWord * 2;
const unsigned StackAlignmentInWords = StackAlignmentInBytes const unsigned StackAlignmentInWords = StackAlignmentInBytes
/ TargetBytesPerWord; / TargetBytesPerWord;
@ -258,7 +258,7 @@ class MyArchitecture : public Architecture {
virtual unsigned argumentRegisterCount() virtual unsigned argumentRegisterCount()
{ {
return 4; return TargetBytesPerWord;
} }
virtual Register argumentRegister(unsigned index) virtual Register argumentRegister(unsigned index)
@ -434,11 +434,11 @@ class MyArchitecture : public Architecture {
break; break;
case lir::Float2Int: case lir::Float2Int:
// todo: Java requires different semantics than SSE for // todo: Java requires different semantics than VFP for
// converting floats to integers, we we need to either use // converting floats to integers, we we need to either use
// thunks or produce inline machine code which handles edge // thunks or produce inline machine code which handles edge
// cases properly. // cases properly.
if (false && vfpSupported() && bSize == 4) { if (false && vfpSupported() && bSize <= TargetBytesPerWord) {
aMask.typeMask = lir::Operand::RegisterPairMask; aMask.typeMask = lir::Operand::RegisterPairMask;
aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK); aMask.setLowHighRegisterMasks(FPR_MASK, FPR_MASK);
} else { } else {
@ -447,7 +447,7 @@ class MyArchitecture : public Architecture {
break; break;
case lir::Int2Float: case lir::Int2Float:
if (vfpSupported() && aSize == 4) { if (vfpSupported() && aSize <= TargetBytesPerWord) {
aMask.typeMask = lir::Operand::RegisterPairMask; aMask.typeMask = lir::Operand::RegisterPairMask;
aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK); aMask.setLowHighRegisterMasks(GPR_MASK, GPR_MASK);
} else { } else {
@ -544,7 +544,7 @@ class MyArchitecture : public Architecture {
case lir::ShiftLeft: case lir::ShiftLeft:
case lir::ShiftRight: case lir::ShiftRight:
case lir::UnsignedShiftRight: case lir::UnsignedShiftRight:
if (bSize == 8) if (bSize > TargetBytesPerWord)
aMask.typeMask = bMask.typeMask = lir::Operand::RegisterPairMask; aMask.typeMask = bMask.typeMask = lir::Operand::RegisterPairMask;
break; break;

View File

@ -15,6 +15,8 @@
#include "fixup.h" #include "fixup.h"
#include "multimethod.h" #include "multimethod.h"
#if AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM
namespace avian { namespace avian {
namespace codegen { namespace codegen {
namespace arm { namespace arm {
@ -1554,3 +1556,5 @@ void storeLoadBarrier(Context* con)
} // namespace arm } // namespace arm
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian
#endif // AVIAN_TARGET_ARCH == AVIAN_ARCH_ARM

File diff suppressed because it is too large Load Diff

View File

@ -21,10 +21,29 @@ namespace arm {
const uint64_t MASK_LO32 = 0xffffffff; const uint64_t MASK_LO32 = 0xffffffff;
const unsigned MASK_LO8 = 0xff; const unsigned MASK_LO8 = 0xff;
#ifdef ARCH_arm64
constexpr Register ThreadRegister(19);
constexpr Register StackRegister(31);
constexpr Register LinkRegister(30);
constexpr Register LinkRegister(29);
constexpr Register ProgramCounter(0xFE); // i.e. unaddressable
const int N_GPRS = 32;
const int N_FPRS = 32;
const uint64_t GPR_MASK = 0xffffffff;
const uint64_t FPR_MASK = 0xffffffff00000000;
#else
constexpr Register ThreadRegister(8);
constexpr Register StackRegister(13);
constexpr Register LinkRegister(14);
constexpr Register FrameRegister(0xFE); // i.e. there is none
constexpr Register ProgramCounter(15);
const int N_GPRS = 16; const int N_GPRS = 16;
const int N_FPRS = 16; const int N_FPRS = 16;
const RegisterMask GPR_MASK = 0xffff; const RegisterMask GPR_MASK = 0xffff;
const RegisterMask FPR_MASK = 0xffff0000; const RegisterMask FPR_MASK = 0xffff0000;
#endif
inline bool isFpr(lir::RegisterPair* reg) inline bool isFpr(lir::RegisterPair* reg)
{ {
@ -48,18 +67,6 @@ inline int fpr32(lir::RegisterPair* reg)
return fpr64(reg) << 1; return fpr64(reg) << 1;
} }
#ifdef ARCH_arm64
constexpr Register ThreadRegister(19);
constexpr Register StackRegister(31);
constexpr Register LinkRegister(30);
constexpr Register ProgramCounter(0xFE); // i.e. unaddressable
#else
constexpr Register ThreadRegister(8);
constexpr Register StackRegister(13);
constexpr Register LinkRegister(14);
constexpr Register ProgramCounter(15);
#endif
} // namespace arm } // namespace arm
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian

View File

@ -16,20 +16,122 @@
#define BYTES_PER_WORD 4 #define BYTES_PER_WORD 4
#define LOCAL(x) .L##x #define LOCAL(x) .L##x
#ifdef __APPLE__ #ifdef __APPLE__
# define GLOBAL(x) _##x # define GLOBAL(x) _##x
#else #else
# define GLOBAL(x) x # define GLOBAL(x) x
#endif #endif
#ifdef __aarch64__
.globl GLOBAL(vmInvoke)
.align 2
GLOBAL(vmInvoke):
// arguments:
// x0 : thread
// x1 : function
// x2 : arguments
// w3 : argumentFootprint
// w4 : frameSize (not used)
// w5 : returnType
// allocate frame
stp x29, x30, [sp,#-96]!
// save callee-saved register values
stp x19, x20, [sp,#16]
stp x21, x22, [sp,#32]
stp x23, x24, [sp,#48]
stp x25, x26, [sp,#64]
stp x27, x28, [sp,#80]
// save return type
str w5, [sp,#-16]!
mov x5, sp
str x5, [x0,#TARGET_THREAD_SCRATCH]
// copy arguments into place
sub sp, sp, w3
mov x5, #0
b LOCAL(vmInvoke_argumentTest)
LOCAL(vmInvoke_argumentLoop):
ldr x5, [x2, x4]
str x5, [sp, x4]
add x4, x4, #BYTES_PER_WORD
LOCAL(vmInvoke_argumentTest):
cmp x4, x3
blt LOCAL(vmInvoke_argumentLoop)
// we use x19 to hold the thread pointer, by convention
mov x19, x0
// load and call function address
blr x1
.globl GLOBAL(vmInvoke_returnAddress)
.align 2
GLOBAL(vmInvoke_returnAddress):
// restore stack pointer
ldr x5, [x19, #TARGET_THREAD_SCRATCH]
mov sp, x5
// 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.
mov x5, #0
str x5, [x19, #TARGET_THREAD_STACK]
.globl GLOBAL(vmInvoke_safeStack)
.align 2
GLOBAL(vmInvoke_safeStack):
#ifdef AVIAN_CONTINUATIONS
#error todo
#endif // AVIAN_CONTINUATIONS
mov x5, #0
str x5, [x19, #TARGET_THREAD_STACK]
// restore return type
ldr w5, [sp], #4
// restore callee-saved register values
ldp x19, x20, [sp,#16]
ldp x21, x22, [sp,#32]
ldp x23, x24, [sp,#48]
ldp x25, x26, [sp,#64]
ldp x27, x28, [sp,#80]
ldp x29, x30, [sp],#96
LOCAL(vmInvoke_return):
br x30
.globl GLOBAL(vmJumpAndInvoke)
.align 2
GLOBAL(vmJumpAndInvoke):
#ifdef AVIAN_CONTINUATIONS
#error todo
#else // not AVIAN_CONTINUATIONS
// vmJumpAndInvoke should only be called when continuations are
// enabled, so we force a crash if we reach here:
brk 0
#endif // not AVIAN_CONTINUATIONS
#elif defined __arm__
#define CONTINUATION_NEXT 4 #define CONTINUATION_NEXT 4
#define CONTINUATION_ADDRESS 16 #define CONTINUATION_ADDRESS 16
#define CONTINUATION_RETURN_ADDRESS_OFFSET 20 #define CONTINUATION_RETURN_ADDRESS_OFFSET 20
#define CONTINUATION_FRAME_POINTER_OFFSET 24 #define CONTINUATION_FRAME_POINTER_OFFSET 24
#define CONTINUATION_LENGTH 28 #define CONTINUATION_LENGTH 28
#define CONTINUATION_BODY 32 #define CONTINUATION_BODY 32
.globl GLOBAL(vmInvoke) .globl GLOBAL(vmInvoke)
.align 2 .align 2
GLOBAL(vmInvoke): GLOBAL(vmInvoke):
@ -56,7 +158,7 @@ GLOBAL(vmInvoke):
eor r4, sp, r3 eor r4, sp, r3
tst r4, #4 tst r4, #4
subne sp, sp, #4 subne sp, sp, #4
// copy arguments into place // copy arguments into place
sub sp, r3 sub sp, r3
mov r4, #0 mov r4, #0
@ -87,7 +189,7 @@ LOCAL(vmInvoke_argumentTest):
GLOBAL(vmInvoke_returnAddress): GLOBAL(vmInvoke_returnAddress):
// restore stack pointer // restore stack pointer
ldr sp, [r8, #TARGET_THREAD_SCRATCH] ldr sp, [r8, #TARGET_THREAD_SCRATCH]
// clear MyThread::stack to avoid confusing another thread calling // clear MyThread::stack to avoid confusing another thread calling
// java.lang.Thread.getStackTrace on this one. See // java.lang.Thread.getStackTrace on this one. See
// MyProcess::getStackTrace in compile.cpp for details on how we get // MyProcess::getStackTrace in compile.cpp for details on how we get
@ -201,7 +303,7 @@ GLOBAL(vmJumpAndInvoke):
// which is not true in this case // which is not true in this case
sub r2,r2,r6 sub r2,r2,r6
sub r2,r2,#84 sub r2,r2,#84
mov r8,r0 mov r8,r0
// copy arguments into place // copy arguments into place
@ -220,7 +322,7 @@ LOCAL(vmJumpAndInvoke_argumentTest):
// the arguments have been copied, so we can set the real stack // the arguments have been copied, so we can set the real stack
// pointer now // pointer now
mov sp,r2 mov sp,r2
// set return address to vmInvoke_returnAddress // set return address to vmInvoke_returnAddress
#ifdef __APPLE__ #ifdef __APPLE__
movw r11, :lower16:(GLOBAL(vmInvoke_returnAddress)-(LOCAL(vmJumpAndInvoke_getAddress)+8)) movw r11, :lower16:(GLOBAL(vmInvoke_returnAddress)-(LOCAL(vmJumpAndInvoke_getAddress)+8))
@ -246,10 +348,12 @@ LOCAL(vmInvoke_getAddress_word):
LOCAL(vmJumpAndInvoke_getAddress_word): LOCAL(vmJumpAndInvoke_getAddress_word):
.word _GLOBAL_OFFSET_TABLE_-(LOCAL(vmJumpAndInvoke_getAddress)+8) .word _GLOBAL_OFFSET_TABLE_-(LOCAL(vmJumpAndInvoke_getAddress)+8)
#endif // not __APPLE__ #endif // not __APPLE__
#else // not AVIAN_CONTINUATIONS #else // not AVIAN_CONTINUATIONS
// vmJumpAndInvoke should only be called when continuations are // vmJumpAndInvoke should only be called when continuations are
// enabled, so we force a crash if we reach here: // enabled, so we force a crash if we reach here:
mov r1,#0 mov r1,#0
ldr r1,[r1] ldr r1,[r1]
#endif // not AVIAN_CONTINUATIONS #endif // not AVIAN_CONTINUATIONS
#endif // __arm__