Skip to content

Commit

Permalink
Incomplete Backend support for Apple Silicon
Browse files Browse the repository at this point in the history
- Enables dynamic interpretor thunks on Apple Silicon
- Remainder of the JIT will compile with these edits but not yet work
  • Loading branch information
rhuanjl committed Mar 22, 2023
1 parent edb1ee9 commit 40b603e
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 27 deletions.
82 changes: 57 additions & 25 deletions lib/Backend/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,59 @@
if(CC_TARGETS_AMD64)
set (CC_BACKEND_ARCH_FOLDER amd64)
set (CC_BACKEND_ARCH_FILES
amd64/EncoderMD.cpp
amd64/LinearScanMD.cpp
amd64/LowererMDArch.cpp
amd64/PeepsMD.cpp
amd64/PrologEncoderMD.cpp
amd64/LinearScanMdA.S
amd64/Thunks.S
AgenPeeps.cpp
EhFrame.cpp
LowerMDShared.cpp
LowerMDSharedSimd128.cpp
PrologEncoder.cpp
)
elseif(CC_TARGETS_X86)
set (CC_BACKEND_ARCH_FOLDER i386)
set (CC_BACKEND_ARCH_FILES
i386/EncoderMD.cpp
i386/LinearScanMD.cpp
i386/LowererMDArch.cpp
i386/PeepsMD.cpp
AgenPeeps.cpp
LowerMDShared.cpp
LowerMDSharedSimd128.cpp
)
elseif(CC_TARGETS_ARM64)
set (CC_BACKEND_ARCH_FOLDER arm64)
set (CC_BACKEND_ARCH_FILES
arm64/ARM64LogicalImmediates.cpp
arm64/ARM64UnwindEncoder.cpp
arm64/EncoderMD.cpp
arm64/LegalizeMD.cpp
arm64/LinearScanMD.cpp
arm64/LinearScanMdA.S
arm64/LowerMD.cpp
arm64/PeepsMD.cpp
arm64/Thunks.S
arm64/UnwindInfoManager.cpp
)
elseif(CC_TARGETS_ARM)
set (CC_BACKEND_ARCH_FOLDER arm)
set (CC_BACKEND_ARCH_FILES
arm/EncoderMD.cpp
arm/LegalizeMD.cpp
arm/LinearScanMD.cpp
arm/LinearScanMdA.asm
arm/LowerMD.cpp
arm/PeepsMD.cpp
arm/Thunks.asm
arm/UnwindInfoManager.cpp
)
endif()

add_library (Chakra.Backend OBJECT
AgenPeeps.cpp
AsmJsJITInfo.cpp
Backend.cpp
BackendApi.cpp
Expand All @@ -12,7 +66,6 @@ add_library (Chakra.Backend OBJECT
CodeGenWorkItem.cpp
DbCheckPostLower.cpp
Debug.cpp
EhFrame.cpp
EmitBuffer.cpp
Encoder.cpp
EquivalentTypeSet.cpp
Expand Down Expand Up @@ -57,8 +110,6 @@ add_library (Chakra.Backend OBJECT
JnHelperMethod.cpp
LinearScan.cpp
Lower.cpp
LowerMDShared.cpp
LowerMDSharedSimd128.cpp
NativeCodeData.cpp
NativeCodeGenerator.cpp
NativeEntryPointData.cpp
Expand All @@ -68,7 +119,6 @@ add_library (Chakra.Backend OBJECT
PageAllocatorPool.cpp
Peeps.cpp
PreLowerPeeps.cpp
PrologEncoder.cpp
QueuedFullJitWorkItem.cpp
Region.cpp
SccLiveness.cpp
Expand All @@ -83,30 +133,12 @@ add_library (Chakra.Backend OBJECT
TempTracker.cpp
ValueInfo.cpp
ValueRelativeOffset.cpp
amd64/EncoderMD.cpp
amd64/LinearScanMD.cpp
amd64/LowererMDArch.cpp
amd64/PeepsMD.cpp
amd64/PrologEncoderMD.cpp
amd64/LinearScanMdA.S
amd64/Thunks.S
# arm64/EncoderMD.cpp
# arm64/LowerMD.cpp
# arm/EncoderMD.cpp
# arm/LegalizeMD.cpp
# arm/LinearScanMD.cpp
# arm/LowerMD.cpp
# arm/PeepsMD.cpp
# arm/UnwindInfoManager.cpp
# i386/EncoderMD.cpp
# i386/LinearScanMD.cpp
# i386/LowererMDArch.cpp
# i386/PeepsMD.cpp
${CC_BACKEND_ARCH_FILES}
)

target_include_directories (
Chakra.Backend PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
amd64
${CC_BACKEND_ARCH_FOLDER}
../Common
../JITIDL
../Runtime
Expand Down
17 changes: 17 additions & 0 deletions lib/Backend/InterpreterThunkEmitter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "Backend.h"
Expand Down Expand Up @@ -157,19 +158,31 @@ constexpr BYTE Epilog[] = {
};
#elif defined(_M_ARM64)

#ifdef _WIN32
constexpr BYTE FunctionInfoOffset = 24;
constexpr BYTE FunctionProxyOffset = 28;
constexpr BYTE DynamicThunkAddressOffset = 32;
constexpr BYTE ThunkAddressOffset = 36;
#else
constexpr BYTE FunctionInfoOffset = 8;
constexpr BYTE FunctionProxyOffset = 12;
constexpr BYTE DynamicThunkAddressOffset = 16;
constexpr BYTE ThunkAddressOffset = 20;
#endif

//TODO: saravind :Implement Range Check for ARM64
constexpr BYTE InterpreterThunk[InterpreterThunkEmitter::InterpreterThunkSize] = {
#ifdef _WIN32
0xFD, 0x7B, 0xBB, 0xA9, //stp fp, lr, [sp, #-80]! ;Prologue
0xFD, 0x03, 0x00, 0x91, //mov fp, sp ;update frame pointer to the stack pointer
0xE0, 0x07, 0x01, 0xA9, //stp x0, x1, [sp, #16] ;Prologue again; save all registers
0xE2, 0x0F, 0x02, 0xA9, //stp x2, x3, [sp, #32]
0xE4, 0x17, 0x03, 0xA9, //stp x4, x5, [sp, #48]
0xE6, 0x1F, 0x04, 0xA9, //stp x6, x7, [sp, #64]
#else
0xFD, 0x7B, 0xBF, 0xA9, //stp fp, lr, [sp, #-16]! ;Prologue
0xFD, 0x03, 0x00, 0x91, //mov fp, sp ;update frame pointer to the stack pointer
#endif
0x02, 0x00, 0x40, 0xF9, //ldr x2, [x0, #0x00] ;offset will be replaced with Offset of FunctionInfo
0x40, 0x00, 0x40, 0xF9, //ldr x0, [x2, #0x00] ;offset will be replaced with Offset of FunctionProxy
0x03, 0x00, 0x40, 0xF9, //ldr x3, [x0, #0x00] ;offset will be replaced with offset of DynamicInterpreterThunk
Expand All @@ -191,7 +204,11 @@ constexpr BYTE Call[] = {
};

constexpr BYTE Epilog[] = {
#ifdef _WIN32
0xfd, 0x7b, 0xc5, 0xa8, // ldp fp, lr, [sp], #80
#else
0xfd, 0x7b, 0xc1, 0xa8, // ldp fp, lr, [sp], #16
#endif
0xc0, 0x03, 0x5f, 0xd6 // ret
};
#else // x86
Expand Down
5 changes: 5 additions & 0 deletions lib/Backend/InterpreterThunkEmitter.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
Expand Down Expand Up @@ -68,7 +69,11 @@ class InterpreterThunkEmitter
#elif defined(_M_ARM)
static constexpr size_t InterpreterThunkSize = 72;
#elif defined(_M_ARM64)
#ifdef _WIN32
static constexpr size_t InterpreterThunkSize = 64;
#else
static constexpr size_t InterpreterThunkSize = 48;
#endif
#else
static constexpr size_t InterpreterThunkSize = 56;
#endif
Expand Down
4 changes: 3 additions & 1 deletion lib/Backend/LinearScan.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
// Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

Expand Down Expand Up @@ -4948,6 +4948,8 @@ LinearScan::GeneratorBailIn::GeneratorBailIn(Func* func, LinearScan* linearScan)
RegRAX, RegRCX
#elif defined(_M_IX86)
RegEAX, RegECX
#elif defined(_M_ARM64)
RegR0, RegR1
#endif
},
interpreterFrameRegOpnd { IR::RegOpnd::New(nullptr, regs[0], TyMachPtr, func) },
Expand Down
12 changes: 12 additions & 0 deletions lib/Backend/arm64/ARM64Encoder.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
Expand Down Expand Up @@ -817,6 +818,17 @@ EmitDiv0Exception(
//
// MRS dest, systemreg
//
#ifndef _WIN32
#define ARM64_SYSREG(op0, op1, crn, crm, op2) \
( ((op0 & 1) << 14) | \
((op1 & 7) << 11) | \
((crn & 15) << 7) | \
((crm & 15) << 3) | \
((op2 & 7) << 0) )

#define ARM64_FPCR ARM64_SYSREG(3, 3, 4, 4, 0) // Floating point control register (EL0)
#define ARM64_FPSR ARM64_SYSREG(3, 3, 4, 4, 1) // Floating point status register (EL0)
#endif

#define ARM64_NZCV ARM64_SYSREG(3,3, 4, 2,0) // Flags (EL0); arm64_x.h
#define ARM64_CNTVCT ARM64_SYSREG(3,3,14, 0,2) // Generic Timer virtual count
Expand Down
107 changes: 107 additions & 0 deletions lib/Backend/arm64/LinearScanMdA.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
;-------------------------------------------------------------------------------------------------------
; Copyright (C) Microsoft. All rights reserved.
; Copyright (c) ChakraCore Project Contributors. All rights reserved.
; Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
;-------------------------------------------------------------------------------------------------------

#include "unixasmmacros.inc"

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LinearScanMD::SaveAllRegistersAndBailOut(BailOutRecord *const bailOutRecord)

NESTED_ENTRY _ZN12LinearScanMD26SaveAllRegistersAndBailOutEP13BailOutRecord, _TEXT, NoHandler

; x0 == bailOutRecord
; lr == return address

; Save all registers except the above, which would have already been saved by jitted code if necessary
ldr x17, [x0] ; bailOutRecord->globalBailOutRecordDataTable
ldr x17, [x17] ; bailOutRecord->globalBailOutRecordDataTable->registerSaveSpace
str x1, [x17, #1*8]
stp x2, x3, [x17, #2*8]
stp x4, x5, [x17, #4*8]
stp x6, x7, [x17, #6*8]
stp x8, x9, [x17, #8*8]
stp x10, x11, [x17, #10*8]
stp x12, x13, [x17, #12*8]
stp x14, x15, [x17, #14*8]
str x16, [x17, #16*8]
; skip x17/x18
stp x19, x20, [x17, #19*8]
stp x21, x22, [x17, #21*8]
stp x23, x24, [x17, #23*8]
stp x25, x26, [x17, #25*8]
stp x27, x28, [x17, #27*8]
str fp, [x17, #29*8]
; skip lr, sp, zr
add x17, x17, #33*8
stp d0, d1, [x17, #0*8]
stp d2, d3, [x17, #2*8]
stp d4, d5, [x17, #4*8]
stp d6, d7, [x17, #6*8]
stp d8, d9, [x17, #8*8]
stp d10, d11, [x17, #10*8]
stp d12, d13, [x17, #12*8]
stp d14, d15, [x17, #14*8]
stp d16, d17, [x17, #16*8]
stp d18, d19, [x17, #18*8]
stp d20, d21, [x17, #20*8]
stp d22, d23, [x17, #22*8]
stp d24, d25, [x17, #24*8]
stp d26, d27, [x17, #26*8]
stp d28, d29, [x17, #28*8]
;stp d30, d31, [x17, #30*8]

b C_FUNC(_ZN13BailOutRecord7BailOutEPKS_)

NESTED_END _ZN12LinearScanMD26SaveAllRegistersAndBailOutEP13BailOutRecord, _TEXT

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LinearScanMD::SaveAllRegistersAndBranchBailOut(BranchBailOutRecord *const bailOutRecord, const BOOL condition)

NESTED_ENTRY _ZN12LinearScanMD32SaveAllRegistersAndBranchBailOutEP19BranchBailOutRecordi, _TEXT, NoHandler

; x0 == bailOutRecord
; x1 == condition
; lr == return address

; Save all registers except the above, which would have already been saved by jitted code if necessary
ldr x17, [x0] ; bailOutRecord->globalBailOutRecordDataTable
ldr x17, [x17] ; bailOutRecord->globalBailOutRecordDataTable->registerSaveSpace
stp x2, x3, [x17, #2*8]
stp x4, x5, [x17, #4*8]
stp x6, x7, [x17, #6*8]
stp x8, x9, [x17, #8*8]
stp x10, x11, [x17, #10*8]
stp x12, x13, [x17, #12*8]
stp x14, x15, [x17, #14*8]
str x16, [x17, #16*8]
; skip x17/x18
stp x19, x20, [x17, #19*8]
stp x21, x22, [x17, #21*8]
stp x23, x24, [x17, #23*8]
stp x25, x26, [x17, #25*8]
stp x27, x28, [x17, #27*8]
str fp, [x17, #29*8]
; skip lr, sp, zr
add x17, x17, #33*8
stp d0, d1, [x17, #0*8]
stp d2, d3, [x17, #2*8]
stp d4, d5, [x17, #4*8]
stp d6, d7, [x17, #6*8]
stp d8, d9, [x17, #8*8]
stp d10, d11, [x17, #10*8]
stp d12, d13, [x17, #12*8]
stp d14, d15, [x17, #14*8]
stp d16, d17, [x17, #16*8]
stp d18, d19, [x17, #18*8]
stp d20, d21, [x17, #20*8]
stp d22, d23, [x17, #22*8]
stp d24, d25, [x17, #24*8]
stp d26, d27, [x17, #26*8]
stp d28, d29, [x17, #28*8]
;stp d30, d31, [x17, #30*8]

b C_FUNC(_ZN19BranchBailOutRecord7BailOutEPKS_i)

NESTED_END _ZN12LinearScanMD32SaveAllRegistersAndBranchBailOutEP19BranchBailOutRecordi, _TEXT
3 changes: 2 additions & 1 deletion lib/Backend/arm64/LowerMD.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
Expand Down Expand Up @@ -105,7 +106,7 @@ class LowererMD
template <bool Saturate>
void GenerateTruncWithCheck(IR::Instr * instr) { Assert(UNREACHED); }
void GenerateFastDivByPow2(IR::Instr *instr);
bool GenerateFastDivAndRem(IR::Instr* instrDiv, IR::LabelInstr* bailOutLabel = false);
bool GenerateFastDivAndRem(IR::Instr* instrDiv, IR::LabelInstr* bailOutLabel = nullptr);
bool GenerateFastAdd(IR::Instr * instrAdd);
bool GenerateFastSub(IR::Instr * instrSub);
bool GenerateFastMul(IR::Instr * instrMul);
Expand Down
Loading

0 comments on commit 40b603e

Please # to comment.