bug 1171649 - Implement arm/iOS support in JS JITs. r=jandem

This patch includes some assembly files from llvm's compiler-rt to implement __aeabi_ividmod and __aeabi_uidivmod.
This commit is contained in:
Ted Mielczarek 2015-09-23 10:21:41 -04:00
parent 01199f04c1
commit 7e7d18e037
9 changed files with 198 additions and 7 deletions

View File

@ -201,6 +201,7 @@ class AutoSetHandlingSignal
#elif defined(XP_DARWIN)
# define EIP_sig(p) ((p)->uc_mcontext->__ss.__eip)
# define RIP_sig(p) ((p)->uc_mcontext->__ss.__rip)
# define R15_sig(p) ((p)->uc_mcontext->__ss.__pc)
#else
# error "Don't know how to read/write to the thread state via the mcontext_t."
#endif
@ -320,12 +321,20 @@ struct macos_x64_context {
x86_float_state64_t float_;
};
# define EMULATOR_CONTEXT macos_x64_context
# else
# elif defined(JS_CODEGEN_X86)
struct macos_x86_context {
x86_thread_state_t thread;
x86_float_state_t float_;
};
# define EMULATOR_CONTEXT macos_x86_context
# elif defined(JS_CODEGEN_ARM)
struct macos_arm_context {
arm_thread_state_t thread;
arm_neon_state_t float_;
};
# define EMULATOR_CONTEXT macos_arm_context
# else
# error Unsupported architecture
# endif
#else
# define EMULATOR_CONTEXT CONTEXT
@ -803,10 +812,16 @@ ContextToPC(EMULATOR_CONTEXT* context)
static_assert(sizeof(context->thread.__rip) == sizeof(void*),
"stored IP should be compile-time pointer-sized");
return reinterpret_cast<uint8_t**>(&context->thread.__rip);
# else
# elif defined(JS_CPU_X86)
static_assert(sizeof(context->thread.uts.ts32.__eip) == sizeof(void*),
"stored IP should be compile-time pointer-sized");
return reinterpret_cast<uint8_t**>(&context->thread.uts.ts32.__eip);
# elif defined(JS_CPU_ARM)
static_assert(sizeof(context->thread.__pc) == sizeof(void*),
"stored IP should be compile-time pointer-sized");
return reinterpret_cast<uint8_t**>(&context->thread.__pc);
# else
# error Unsupported architecture
# endif
}
@ -852,11 +867,18 @@ HandleMachException(JSRuntime* rt, const ExceptionRequest& request)
unsigned int float_state_count = x86_FLOAT_STATE64_COUNT;
int thread_state = x86_THREAD_STATE64;
int float_state = x86_FLOAT_STATE64;
# else
# elif defined(JS_CODEGEN_X86)
unsigned int thread_state_count = x86_THREAD_STATE_COUNT;
unsigned int float_state_count = x86_FLOAT_STATE_COUNT;
int thread_state = x86_THREAD_STATE;
int float_state = x86_FLOAT_STATE;
# elif defined(JS_CODEGEN_ARM)
unsigned int thread_state_count = ARM_THREAD_STATE_COUNT;
unsigned int float_state_count = ARM_NEON_STATE_COUNT;
int thread_state = ARM_THREAD_STATE;
int float_state = ARM_NEON_STATE;
# else
# error Unsupported architecture
# endif
kern_return_t kret;
kret = thread_get_state(rtThread, thread_state,

View File

@ -133,6 +133,14 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
pushedNonVolatileRegisters++;
}
#if defined(XP_IOS) && defined(JS_CODEGEN_ARM)
// The stack is 4-byte aligned on iOS, force 8-byte alignment.
masm.movePtr(StackPointer, temp0);
masm.andPtr(Imm32(~7), StackPointer);
masm.push(temp0);
masm.push(temp0);
#endif
#ifndef JS_CODEGEN_X86
// The InputOutputData* is stored as an argument, save it on the stack
// above the frame.
@ -369,6 +377,11 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
masm.freeStack(frameSize);
#endif
#if defined(XP_IOS) && defined(JS_CODEGEN_ARM)
masm.pop(temp0);
masm.movePtr(temp0, StackPointer);
#endif
// Restore non-volatile registers which were saved on entry.
for (GeneralRegisterBackwardIterator iter(savedNonVolatileRegisters); iter.more(); ++iter)
masm.Pop(*iter);

View File

@ -59,6 +59,10 @@ extern "C" void sync_instruction_memory(caddr_t v, u_int len);
#include <sys/cachectl.h>
#endif
#if defined(JS_CODEGEN_ARM) && defined(XP_IOS)
#include <libkern/OSCacheControl.h>
#endif
namespace JS {
struct CodeSizes;
} // namespace JS
@ -409,6 +413,11 @@ class ExecutableAllocator
{
__clear_cache(code, reinterpret_cast<char*>(code) + size);
}
#elif defined(JS_CODEGEN_ARM) && defined(XP_IOS)
static void cacheFlush(void* code, size_t size)
{
sys_icache_invalidate(code, size);
}
#elif defined(JS_CODEGEN_ARM) && (defined(__linux__) || defined(ANDROID)) && defined(__GNUC__)
static void cacheFlush(void* code, size_t size)
{

View File

@ -6,7 +6,7 @@
#include "jit/arm/Architecture-arm.h"
#ifndef JS_SIMULATOR_ARM
#if !defined(JS_ARM_SIMULATOR) && !defined(__APPLE__)
#include <elf.h>
#endif
@ -245,6 +245,15 @@ InitARMFlags()
flags |= HWCAP_ARMv7;
#endif
#if defined(__APPLE__)
#if defined(__ARM_NEON__)
flags |= HWCAP_NEON;
#endif
#if defined(__ARMVFPV3__)
flags |= HWCAP_VFPv3 | HWCAP_VFPD32
#endif
#endif
#endif // JS_SIMULATOR_ARM
armHwCapFlags = CanonicalizeARMHwCapFlags(flags);

View File

@ -15,8 +15,9 @@
#include "js/Utility.h"
// GCC versions 4.6 and above define __ARM_PCS_VFP to denote a hard-float
// ABI target.
#if defined(__ARM_PCS_VFP)
// ABI target. The iOS toolchain doesn't define anything specific here,
// but iOS always supports VFP.
#if defined(__ARM_PCS_VFP) || defined(XP_IOS)
#define JS_CODEGEN_ARM_HARDFP
#endif
@ -109,7 +110,12 @@ class Registers
(1 << r0) |
(1 << r1) |
(1 << Registers::r2) |
(1 << Registers::r3);
(1 << Registers::r3)
#if defined(XP_IOS)
// per https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html#//apple_ref/doc/uid/TP40009021-SW4
| (1 << Registers::r9)
#endif
;
static const SetType NonVolatileMask =
(1 << Registers::r4) |
@ -117,7 +123,9 @@ class Registers
(1 << Registers::r6) |
(1 << Registers::r7) |
(1 << Registers::r8) |
#if !defined(XP_IOS)
(1 << Registers::r9) |
#endif
(1 << Registers::r10) |
(1 << Registers::r11) |
(1 << Registers::r12) |

View File

@ -0,0 +1,27 @@
//===-- aeabi_idivmod.S - EABI idivmod implementation ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "../assembly.h"
// struct { int quot, int rem} __aeabi_idivmod(int numerator, int denominator) {
// int rem, quot;
// quot = __divmodsi4(numerator, denominator, &rem);
// return {quot, rem};
// }
.syntax unified
.align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod)
push { lr }
sub sp, sp, #4
mov r2, sp
bl SYMBOL_NAME(__divmodsi4)
ldr r1, [sp]
add sp, sp, #4
pop { pc }

View File

@ -0,0 +1,28 @@
//===-- aeabi_uidivmod.S - EABI uidivmod implementation -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "../assembly.h"
// struct { unsigned quot, unsigned rem}
// __aeabi_uidivmod(unsigned numerator, unsigned denominator) {
// unsigned rem, quot;
// quot = __udivmodsi4(numerator, denominator, &rem);
// return {quot, rem};
// }
.syntax unified
.align 2
DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod)
push { lr }
sub sp, sp, #4
mov r2, sp
bl SYMBOL_NAME(__udivmodsi4)
ldr r1, [sp]
add sp, sp, #4
pop { pc }

View File

@ -0,0 +1,70 @@
/* ===-- assembly.h - compiler-rt assembler support macros -----------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
*
* This file defines macros for use in compiler-rt assembler source.
* This file is not part of the interface of this library.
*
* ===----------------------------------------------------------------------===
*/
#ifndef COMPILERRT_ASSEMBLY_H
#define COMPILERRT_ASSEMBLY_H
#if defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__)
#define SEPARATOR @
#else
#define SEPARATOR ;
#endif
#if defined(__APPLE__)
#define HIDDEN_DIRECTIVE .private_extern
#define LOCAL_LABEL(name) L_##name
#else
#define HIDDEN_DIRECTIVE .hidden
#define LOCAL_LABEL(name) .L_##name
#endif
#define GLUE2(a, b) a ## b
#define GLUE(a, b) GLUE2(a, b)
#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
#ifdef VISIBILITY_HIDDEN
#define DECLARE_SYMBOL_VISIBILITY(name) \
HIDDEN_DIRECTIVE SYMBOL_NAME(name) SEPARATOR
#else
#define DECLARE_SYMBOL_VISIBILITY(name)
#endif
#define DEFINE_COMPILERRT_FUNCTION(name) \
.globl SYMBOL_NAME(name) SEPARATOR \
DECLARE_SYMBOL_VISIBILITY(name) \
SYMBOL_NAME(name):
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \
.globl SYMBOL_NAME(name) SEPARATOR \
HIDDEN_DIRECTIVE SYMBOL_NAME(name) SEPARATOR \
SYMBOL_NAME(name):
#define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \
.globl name SEPARATOR \
HIDDEN_DIRECTIVE name SEPARATOR \
name:
#define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \
.globl SYMBOL_NAME(name) SEPARATOR \
.set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR
#if defined (__ARM_EABI__)
# define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \
DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name)
#else
# define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name)
#endif
#endif /* COMPILERRT_ASSEMBLY_H */

View File

@ -438,6 +438,11 @@ elif CONFIG['JS_CODEGEN_ARM']:
UNIFIED_SOURCES += [
'jit/arm/Simulator-arm.cpp'
]
elif CONFIG['OS_ARCH'] == 'Darwin':
SOURCES += [
'jit/arm/llvm-compiler-rt/arm/aeabi_idivmod.S',
'jit/arm/llvm-compiler-rt/arm/aeabi_uidivmod.S',
]
elif CONFIG['JS_CODEGEN_ARM64']:
UNIFIED_SOURCES += [
'jit/arm64/Architecture-arm64.cpp',