diff --git a/libpolyml/arm64assembly.S b/libpolyml/arm64assembly.S index 17195a41..4f77130a 100644 --- a/libpolyml/arm64assembly.S +++ b/libpolyml/arm64assembly.S @@ -1,233 +1,233 @@ // // Assembly code for the ARM64 for Poly/ML // Author: David Matthews // Copyright (c) David C. J. Matthews 2021 // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License version 2.1 as published by the Free Software Foundation. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library// if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // The syntax of directives in the GNU assembler and in the MS ARMASM // are somewhat different. ARMASMSYNTAX is defined in the VS project files. #ifdef ARMASMSYNTAX #define LABEL(x) x #else #define LABEL(x) x: #endif #ifdef ARMASMSYNTAX AREA |.text|, CODE, READONLY #else .section .text,"x" .balign 4 #endif #ifdef HAVE_CONFIG_H // Specifically for POLYML32IN64 #include "config.h" #endif #ifdef SYMBOLS_REQUIRE_UNDERSCORE #define EXTNAME(x) _##x #else #define EXTNAME(x) x #endif // Offsets into the assembly code interface #define TrapHandlerEntry 32 #define HandlerRegister 40 #define ExceptionPacket 56 #define ThreadId 64 #define RegisterArray 72 #define FPRegisterArray 272 #define LocalMBottom 336 #define LocalMPointer 344 #define MLStackPointer 352 #define LinkRegister 360 #define EntryPoint 368 #define ReturnReason 376 #ifdef ARMASMSYNTAX EXPORT Arm64AsmEnterCompiledCode Arm64AsmEnterCompiledCode PROC #else .global EXTNAME(Arm64AsmEnterCompiledCode) EXTNAME(Arm64AsmEnterCompiledCode): #endif // This is called once the thread has been initialised to run the ML code. // It never returns. The RTS may be entered either by a compiled RTS call // or by a call to a "trap" function. // We only need to load a subset of the registers. mov x26,x0 // Copy the address of the assembly-code section into X26 ldr x0,[x26, RegisterArray] // Argument ldr x8,[x26, RegisterArray+8*8] // Closure address #ifdef POLYML32IN64 ldr x24,[x26, RegisterArray+24 * 8] add x16,x24,x8,LSL #2 ldr x16,[x16] #else ldr x16,[x8] // Code address - first word of closure #endif ldr x25,[x26, LocalMBottom] // Limit of heap ldp x27,x28,[x26, LocalMPointer] // Allocation pointer and stack pointer ldr x30,[x26, LinkRegister] // Link register - always zero because we don't return br x16 // Jump to code #ifdef ARMASMSYNTAX ENDP #endif #ifdef ARMASMSYNTAX EXPORT Arm64AsmCallExtraRETURN_HEAP_OVERFLOW Arm64AsmCallExtraRETURN_HEAP_OVERFLOW PROC #else .global EXTNAME(Arm64AsmCallExtraRETURN_HEAP_OVERFLOW) EXTNAME(Arm64AsmCallExtraRETURN_HEAP_OVERFLOW) : #endif mov x16, 1 // Common code to call into the RTS LABEL(trapHandle) strb w16,[x26, ReturnReason] stp x0,x1,[x26, RegisterArray] stp x2,x3, [x26, RegisterArray+2*8] stp x4,x5, [x26, RegisterArray + 4*8] stp x6, x7, [x26, RegisterArray + 6*8] stp x8, x9, [x26, RegisterArray + 8*8] stp x10, x11, [x26, RegisterArray + 10*8] stp x12, x13, [x26, RegisterArray + 12*8] stp x14, x15, [x26, RegisterArray + 14*8] stp x19, x20, [x26, RegisterArray + 19 * 8] stp x21,x22,[x26, RegisterArray + 21 * 8] stp x23,x24, [x26, RegisterArray + 23 * 8] stp d0,d1,[x26, FPRegisterArray] stp d2,d3,[x26, FPRegisterArray+2*8] stp d4,d5,[x26, FPRegisterArray+4*8] stp d6,d7,[x26, FPRegisterArray+6*8] str x27,[x26,LocalMPointer] str x28,[x26,MLStackPointer] str x30,[x26,LinkRegister] ldr x0,[x26,ThreadId] // Pass the thread id as an argument so that we can get the task data ldr x16,[x26,TrapHandlerEntry] blr x16 // Load the registers. Even though some are callee-save the RTS may have updated them. // x26, though, should have been preserved. ldr x1,[x26, RegisterArray+1*8] ldp x2,x3, [x26, RegisterArray+2*8] ldp x4,x5, [x26, RegisterArray + 4*8] ldp x6, x7, [x26, RegisterArray + 6*8] ldp x8, x9, [x26, RegisterArray + 8*8] ldp x10, x11, [x26, RegisterArray + 10*8] ldp x12, x13, [x26, RegisterArray + 12*8] ldp x14, x15, [x26, RegisterArray + 14*8] ldp x19, x20, [x26, RegisterArray + 19 * 8] ldp x21,x22,[x26, RegisterArray + 21 * 8] ldp x23,x24, [x26, RegisterArray + 23 * 8] ldp d0,d1,[x26, FPRegisterArray] ldp d2,d3,[x26, FPRegisterArray+2*8] ldp d4,d5,[x26, FPRegisterArray+4*8] ldp d6,d7,[x26, FPRegisterArray+6*8] ldr x25,[x26, LocalMBottom] ldp x27,x28,[x26,LocalMPointer] ldr x30,[x26,LinkRegister] // Check whether we've raised an exception e.g. Interrupt ldr x0,[x26,ExceptionPacket] cmp x0,#1 bne raiseexcept ldr x0,[x26, RegisterArray] ldr x16,[x26,EntryPoint] // Normally this will be x30 but not always br x16 LABEL(raiseexcept) ldr x28,[x26,HandlerRegister] // Set the stack ptr to this ldr x16,[x28] br x16 #ifdef ARMASMSYNTAX ENDP #endif #ifdef ARMASMSYNTAX EXPORT Arm64AsmCallExtraRETURN_STACK_OVERFLOW Arm64AsmCallExtraRETURN_STACK_OVERFLOW PROC #else .global EXTNAME(Arm64AsmCallExtraRETURN_STACK_OVERFLOW) EXTNAME(Arm64AsmCallExtraRETURN_STACK_OVERFLOW) : #endif mov x16, 2 b trapHandle #ifdef ARMASMSYNTAX ENDP #endif #ifdef ARMASMSYNTAX EXPORT Arm64AsmCallExtraRETURN_STACK_OVERFLOWEX Arm64AsmCallExtraRETURN_STACK_OVERFLOWEX PROC #else .global EXTNAME(Arm64AsmCallExtraRETURN_STACK_OVERFLOWEX) EXTNAME(Arm64AsmCallExtraRETURN_STACK_OVERFLOWEX) : #endif mov x16, 3 b trapHandle #ifdef ARMASMSYNTAX ENDP #endif #ifdef ARMASMSYNTAX EXPORT Arm64AsmCallExtraRETURN_ENTER_INTERPRETER Arm64AsmCallExtraRETURN_ENTER_INTERPRETER PROC #else - .global Arm64AsmCallExtraRETURN_ENTER_INTERPRETER -Arm64AsmCallExtraRETURN_ENTER_INTERPRETER : + .global EXTNAME(Arm64AsmCallExtraRETURN_ENTER_INTERPRETER) +EXTNAME(Arm64AsmCallExtraRETURN_ENTER_INTERPRETER) : #endif mov x16,4 b trapHandle #ifdef ARMASMSYNTAX ENDP #endif // POLYUNSIGNED Arm64AsmAtomicExchange(PolyObject*, POLYSIGNED); // This is not actually used with the VS build. #ifdef ARMASMSYNTAX EXPORT Arm64AsmAtomicExchange Arm64AsmAtomicExchange PROC #else .global EXTNAME(Arm64AsmAtomicExchange) EXTNAME(Arm64AsmAtomicExchange): #endif // The easiest way to do this is with swpal but that is only available // in ARM 8.1 and above. For the moment we use the old version. // swpal x0,xzr,[x0] LABEL(aaea1) ldaxr x3,[x0] stlxr w4,xzr,[x0] cbnz w4,aaea1 dmb ish mov x0,x3 ret #ifdef ARMASMSYNTAX ENDP END #endif