From 6a03e12123c26a15bbe7c27bb1fde3c416bc7893 Mon Sep 17 00:00:00 2001 From: "erik.corry@gmail.com" Date: Thu, 6 May 2010 12:49:12 +0000 Subject: [PATCH] Allow unaligned memory accesses on ARM targets that support it. The build process must add -DCAN_USE_UNALIGNED_ACCESSES=1 to the C++ flags to activate the support. This is a commit for Subrato of CodeAurora. See http://codereview.chromium.org/1731013 Small edits by Erik Corry to activate unaligned accesses by default on the simulator and testing Android builds. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4604 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- SConstruct | 3 ++- src/arm/constants-arm.h | 4 +++ src/arm/regexp-macro-assembler-arm.cc | 25 +++++++++++++++--- src/arm/simulator-arm.cc | 50 ++++++++++++++++++++++++++++++----- src/globals.h | 12 +++++++++ 5 files changed, 83 insertions(+), 11 deletions(-) diff --git a/SConstruct b/SConstruct index c85ae1a..244e8ac 100644 --- a/SConstruct +++ b/SConstruct @@ -84,6 +84,7 @@ ANDROID_FLAGS = ['-march=armv7-a', '-finline-limit=64', '-DCAN_USE_VFP_INSTRUCTIONS=1', '-DCAN_USE_ARMV7_INSTRUCTIONS=1', + '-DCAN_USE_UNALIGNED_ACCESSES=1', '-MD'] ANDROID_INCLUDES = [ANDROID_TOP + '/bionic/libc/arch-arm/include', @@ -203,7 +204,7 @@ LIBRARY_FLAGS = { 'CPPDEFINES': ['V8_TARGET_ARCH_ARM'] }, 'simulator:arm': { - 'CCFLAGS': ['-m32'], + 'CCFLAGS': ['-m32', '-DCAN_USE_UNALIGNED_ACCESSES=1'], 'LINKFLAGS': ['-m32'] }, 'armvariant:thumb2': { diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h index 5eed13f..57c5c1c 100644 --- a/src/arm/constants-arm.h +++ b/src/arm/constants-arm.h @@ -72,6 +72,10 @@ # define CAN_USE_THUMB_INSTRUCTIONS 1 #endif +#if CAN_USE_UNALIGNED_ACCESSES +#define V8_TARGET_CAN_READ_UNALIGNED 1 +#endif + // Using blx may yield better code, so use it when required or when available #if defined(USE_THUMB_INTERWORK) || defined(CAN_USE_ARMV5_INSTRUCTIONS) #define USE_BLX 1 diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc index 2fdba14..64fe5d6 100644 --- a/src/arm/regexp-macro-assembler-arm.cc +++ b/src/arm/regexp-macro-assembler-arm.cc @@ -1210,14 +1210,31 @@ void RegExpMacroAssemblerARM::LoadCurrentCharacterUnchecked(int cp_offset, __ add(r0, current_input_offset(), Operand(cp_offset * char_size())); offset = r0; } - // We assume that we cannot do unaligned loads on ARM, so this function - // must only be used to load a single character at a time. + // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU + // and the operating system running on the target allow it. + // If unaligned load/stores are not supported then this function must only + // be used to load a single character at a time. +#if !V8_TARGET_CAN_READ_UNALIGNED ASSERT(characters == 1); +#endif + if (mode_ == ASCII) { - __ ldrb(current_character(), MemOperand(end_of_input_address(), offset)); + if (characters == 4) { + __ ldr(current_character(), MemOperand(end_of_input_address(), offset)); + } else if (characters == 2) { + __ ldrh(current_character(), MemOperand(end_of_input_address(), offset)); + } else { + ASSERT(characters == 1); + __ ldrb(current_character(), MemOperand(end_of_input_address(), offset)); + } } else { ASSERT(mode_ == UC16); - __ ldrh(current_character(), MemOperand(end_of_input_address(), offset)); + if (characters == 2) { + __ ldr(current_character(), MemOperand(end_of_input_address(), offset)); + } else { + ASSERT(characters == 1); + __ ldrh(current_character(), MemOperand(end_of_input_address(), offset)); + } } } diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index 5fe7d5f..95827a7 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -864,16 +864,25 @@ void Simulator::TrashCallerSaveRegisters() { registers_[12] = 0x50Bad4U; } - -// The ARM cannot do unaligned reads and writes. On some ARM platforms an -// interrupt is caused. On others it does a funky rotation thing. For now we -// simply disallow unaligned reads, but at some point we may want to move to -// emulating the rotate behaviour. Note that simulator runs have the runtime +// Some Operating Systems allow unaligned access on ARMv7 targets. We +// assume that unaligned accesses are not allowed unless the v8 build system +// defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero. +// The following statements below describes the behavior of the ARM CPUs +// that don't support unaligned access. +// Some ARM platforms raise an interrupt on detecting unaligned access. +// On others it does a funky rotation thing. For now we +// simply disallow unaligned reads. Note that simulator runs have the runtime // system running directly on the host system and only generated code is // executed in the simulator. Since the host is typically IA32 we will not -// get the correct ARM-like behaviour on unaligned accesses. +// get the correct ARM-like behaviour on unaligned accesses for those ARM +// targets that don't support unaligned loads and stores. + int Simulator::ReadW(int32_t addr, Instr* instr) { +#if V8_TARGET_CAN_READ_UNALIGNED + intptr_t* ptr = reinterpret_cast(addr); + return *ptr; +#else if ((addr & 3) == 0) { intptr_t* ptr = reinterpret_cast(addr); return *ptr; @@ -881,10 +890,16 @@ int Simulator::ReadW(int32_t addr, Instr* instr) { PrintF("Unaligned read at 0x%08x\n", addr); UNIMPLEMENTED(); return 0; +#endif } void Simulator::WriteW(int32_t addr, int value, Instr* instr) { +#if V8_TARGET_CAN_READ_UNALIGNED + intptr_t* ptr = reinterpret_cast(addr); + *ptr = value; + return; +#else if ((addr & 3) == 0) { intptr_t* ptr = reinterpret_cast(addr); *ptr = value; @@ -892,10 +907,15 @@ void Simulator::WriteW(int32_t addr, int value, Instr* instr) { } PrintF("Unaligned write at 0x%08x, pc=%p\n", addr, instr); UNIMPLEMENTED(); +#endif } uint16_t Simulator::ReadHU(int32_t addr, Instr* instr) { +#if V8_TARGET_CAN_READ_UNALIGNED + uint16_t* ptr = reinterpret_cast(addr); + return *ptr; +#else if ((addr & 1) == 0) { uint16_t* ptr = reinterpret_cast(addr); return *ptr; @@ -903,10 +923,15 @@ uint16_t Simulator::ReadHU(int32_t addr, Instr* instr) { PrintF("Unaligned unsigned halfword read at 0x%08x, pc=%p\n", addr, instr); UNIMPLEMENTED(); return 0; +#endif } int16_t Simulator::ReadH(int32_t addr, Instr* instr) { +#if V8_TARGET_CAN_READ_UNALIGNED + int16_t* ptr = reinterpret_cast(addr); + return *ptr; +#else if ((addr & 1) == 0) { int16_t* ptr = reinterpret_cast(addr); return *ptr; @@ -914,10 +939,16 @@ int16_t Simulator::ReadH(int32_t addr, Instr* instr) { PrintF("Unaligned signed halfword read at 0x%08x\n", addr); UNIMPLEMENTED(); return 0; +#endif } void Simulator::WriteH(int32_t addr, uint16_t value, Instr* instr) { +#if V8_TARGET_CAN_READ_UNALIGNED + uint16_t* ptr = reinterpret_cast(addr); + *ptr = value; + return; +#else if ((addr & 1) == 0) { uint16_t* ptr = reinterpret_cast(addr); *ptr = value; @@ -925,10 +956,16 @@ void Simulator::WriteH(int32_t addr, uint16_t value, Instr* instr) { } PrintF("Unaligned unsigned halfword write at 0x%08x, pc=%p\n", addr, instr); UNIMPLEMENTED(); +#endif } void Simulator::WriteH(int32_t addr, int16_t value, Instr* instr) { +#if V8_TARGET_CAN_READ_UNALIGNED + int16_t* ptr = reinterpret_cast(addr); + *ptr = value; + return; +#else if ((addr & 1) == 0) { int16_t* ptr = reinterpret_cast(addr); *ptr = value; @@ -936,6 +973,7 @@ void Simulator::WriteH(int32_t addr, int16_t value, Instr* instr) { } PrintF("Unaligned halfword write at 0x%08x, pc=%p\n", addr, instr); UNIMPLEMENTED(); +#endif } diff --git a/src/globals.h b/src/globals.h index bef5e8e..981ea16 100644 --- a/src/globals.h +++ b/src/globals.h @@ -46,6 +46,12 @@ namespace internal { #elif defined(__ARMEL__) #define V8_HOST_ARCH_ARM 1 #define V8_HOST_ARCH_32_BIT 1 +// Some CPU-OS combinations allow unaligned access on ARM. We assume +// that unaligned accesses are not allowed unless the build system +// defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero. +#if CAN_USE_UNALIGNED_ACCESSES +#define V8_HOST_CAN_READ_UNALIGNED 1 +#endif #elif defined(_MIPS_ARCH_MIPS32R2) #define V8_HOST_ARCH_MIPS 1 #define V8_HOST_ARCH_32_BIT 1 @@ -73,6 +79,12 @@ namespace internal { #if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_IA32) #define V8_TARGET_CAN_READ_UNALIGNED 1 #elif V8_TARGET_ARCH_ARM +// Some CPU-OS combinations allow unaligned access on ARM. We assume +// that unaligned accesses are not allowed unless the build system +// defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero. +#if CAN_USE_UNALIGNED_ACCESSES +#define V8_TARGET_CAN_READ_UNALIGNED 1 +#endif #elif V8_TARGET_ARCH_MIPS #else #error Target architecture is not supported by v8 -- 2.7.4