mirror of
https://github.com/corda/corda.git
synced 2025-01-17 02:09:50 +00:00
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:
parent
4d9c649676
commit
b3bd58aeff
@ -28,8 +28,6 @@ namespace codegen {
|
|||||||
|
|
||||||
class Assembler;
|
class Assembler;
|
||||||
|
|
||||||
class RegisterFile;
|
|
||||||
|
|
||||||
class OperandMask {
|
class OperandMask {
|
||||||
public:
|
public:
|
||||||
uint8_t typeMask;
|
uint8_t typeMask;
|
||||||
|
@ -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*)
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
1218
src/codegen/target/arm/operations64.cpp
Normal file
1218
src/codegen/target/arm/operations64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||||
|
@ -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__
|
||||||
|
Loading…
Reference in New Issue
Block a user