From 86eedc26b568bdfbf039d25ef73fc6cc34c358be Mon Sep 17 00:00:00 2001 From: "ulan@chromium.org" Date: Mon, 15 Oct 2012 15:19:36 +0000 Subject: [PATCH] Allow unaligned accesses for ARMv7. R=mstarzinger@chromium.org,jfb@chromium.org Review URL: https://chromiumcodereview.appspot.com/11087047 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12735 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/assembler-arm.cc | 7 ++ src/arm/assembler-arm.h | 3 + src/arm/constants-arm.h | 4 - src/arm/macro-assembler-arm.cc | 22 ++--- src/arm/regexp-macro-assembler-arm.cc | 11 ++- src/arm/regexp-macro-assembler-arm.h | 1 + src/arm/simulator-arm.cc | 135 +++++++++----------------- src/flag-definitions.h | 2 + src/globals.h | 15 --- src/regexp-macro-assembler.cc | 6 +- src/v8globals.h | 1 + 11 files changed, 82 insertions(+), 125 deletions(-) diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc index 129e62bf2a..86bed1caac 100644 --- a/src/arm/assembler-arm.cc +++ b/src/arm/assembler-arm.cc @@ -77,6 +77,9 @@ static unsigned CpuFeaturesImpliedByCompiler() { #endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) // && !defined(__SOFTFP__) #endif // _arm__ + if (answer & (1u << ARMv7)) { + answer |= 1u << UNALIGNED_ACCESSES; + } return answer; } @@ -133,6 +136,10 @@ void CpuFeatures::Probe() { found_by_runtime_probing_ |= 1u << SUDIV; } + if (!IsSupported(UNALIGNED_ACCESSES) && OS::ArmCpuHasFeature(ARMv7)) { + found_by_runtime_probing_ |= 1u << UNALIGNED_ACCESSES; + } + supported_ |= found_by_runtime_probing_; #endif diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h index 005c78d5d8..7c80b09119 100644 --- a/src/arm/assembler-arm.h +++ b/src/arm/assembler-arm.h @@ -512,6 +512,9 @@ class CpuFeatures : public AllStatic { if (f == VFP3 && !FLAG_enable_vfp3) return false; if (f == VFP2 && !FLAG_enable_vfp2) return false; if (f == SUDIV && !FLAG_enable_sudiv) return false; + if (f == UNALIGNED_ACCESSES && !FLAG_enable_unaligned_accesses) { + return false; + } return (supported_ & (1u << f)) != 0; } diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h index 5aadc3caeb..a6b584394f 100644 --- a/src/arm/constants-arm.h +++ b/src/arm/constants-arm.h @@ -75,10 +75,6 @@ #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/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index 4da5387998..31915a5194 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -3231,17 +3231,17 @@ void MacroAssembler::CopyBytes(Register src, cmp(length, Operand(kPointerSize)); b(lt, &byte_loop); ldr(scratch, MemOperand(src, kPointerSize, PostIndex)); -#if CAN_USE_UNALIGNED_ACCESSES - str(scratch, MemOperand(dst, kPointerSize, PostIndex)); -#else - strb(scratch, MemOperand(dst, 1, PostIndex)); - mov(scratch, Operand(scratch, LSR, 8)); - strb(scratch, MemOperand(dst, 1, PostIndex)); - mov(scratch, Operand(scratch, LSR, 8)); - strb(scratch, MemOperand(dst, 1, PostIndex)); - mov(scratch, Operand(scratch, LSR, 8)); - strb(scratch, MemOperand(dst, 1, PostIndex)); -#endif + if (CpuFeatures::IsSupported(UNALIGNED_ACCESSES)) { + str(scratch, MemOperand(dst, kPointerSize, PostIndex)); + } else { + strb(scratch, MemOperand(dst, 1, PostIndex)); + mov(scratch, Operand(scratch, LSR, 8)); + strb(scratch, MemOperand(dst, 1, PostIndex)); + mov(scratch, Operand(scratch, LSR, 8)); + strb(scratch, MemOperand(dst, 1, PostIndex)); + mov(scratch, Operand(scratch, LSR, 8)); + strb(scratch, MemOperand(dst, 1, PostIndex)); + } sub(length, length, Operand(kPointerSize)); b(&word_loop); diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc index 66cdd8435e..17b8677842 100644 --- a/src/arm/regexp-macro-assembler-arm.cc +++ b/src/arm/regexp-macro-assembler-arm.cc @@ -1358,6 +1358,11 @@ void RegExpMacroAssemblerARM::CallCFunctionUsingStub( } +bool RegExpMacroAssemblerARM::CanReadUnaligned() { + return CpuFeatures::IsSupported(UNALIGNED_ACCESSES) && !slow_safe(); +} + + void RegExpMacroAssemblerARM::LoadCurrentCharacterUnchecked(int cp_offset, int characters) { Register offset = current_input_offset(); @@ -1370,9 +1375,9 @@ void RegExpMacroAssemblerARM::LoadCurrentCharacterUnchecked(int cp_offset, // 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 (!CanReadUnaligned()) { + ASSERT(characters == 1); + } if (mode_ == ASCII) { if (characters == 4) { diff --git a/src/arm/regexp-macro-assembler-arm.h b/src/arm/regexp-macro-assembler-arm.h index f723fa212f..c45669ae89 100644 --- a/src/arm/regexp-macro-assembler-arm.h +++ b/src/arm/regexp-macro-assembler-arm.h @@ -109,6 +109,7 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler { virtual void WriteCurrentPositionToRegister(int reg, int cp_offset); virtual void ClearRegisters(int reg_from, int reg_to); virtual void WriteStackPointerToRegister(int reg); + virtual bool CanReadUnaligned(); // Called from RegExp if the stack-guard is triggered. // If the code object is relocated, the return address is fixed before diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index 91df404f9a..a75046a195 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -1066,111 +1066,83 @@ void Simulator::TrashCallerSaveRegisters() { int Simulator::ReadW(int32_t addr, Instruction* instr) { -#if V8_TARGET_CAN_READ_UNALIGNED - intptr_t* ptr = reinterpret_cast(addr); - return *ptr; -#else - if ((addr & 3) == 0) { + if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) { intptr_t* ptr = reinterpret_cast(addr); return *ptr; + } else { + PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", + addr, + reinterpret_cast(instr)); + UNIMPLEMENTED(); + return 0; } - PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", - addr, - reinterpret_cast(instr)); - UNIMPLEMENTED(); - return 0; -#endif } void Simulator::WriteW(int32_t addr, int value, Instruction* instr) { -#if V8_TARGET_CAN_READ_UNALIGNED - intptr_t* ptr = reinterpret_cast(addr); - *ptr = value; - return; -#else - if ((addr & 3) == 0) { + if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) { intptr_t* ptr = reinterpret_cast(addr); *ptr = value; - return; + } else { + PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", + addr, + reinterpret_cast(instr)); + UNIMPLEMENTED(); } - PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", - addr, - reinterpret_cast(instr)); - UNIMPLEMENTED(); -#endif } uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) { -#if V8_TARGET_CAN_READ_UNALIGNED - uint16_t* ptr = reinterpret_cast(addr); - return *ptr; -#else - if ((addr & 1) == 0) { + if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) { uint16_t* ptr = reinterpret_cast(addr); return *ptr; + } else { + PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" + V8PRIxPTR "\n", + addr, + reinterpret_cast(instr)); + UNIMPLEMENTED(); + return 0; } - PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n", - addr, - reinterpret_cast(instr)); - UNIMPLEMENTED(); - return 0; -#endif } int16_t Simulator::ReadH(int32_t addr, Instruction* instr) { -#if V8_TARGET_CAN_READ_UNALIGNED - int16_t* ptr = reinterpret_cast(addr); - return *ptr; -#else - if ((addr & 1) == 0) { + if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) { int16_t* ptr = reinterpret_cast(addr); return *ptr; + } else { + PrintF("Unaligned signed halfword read at 0x%08x\n", addr); + UNIMPLEMENTED(); + return 0; } - PrintF("Unaligned signed halfword read at 0x%08x\n", addr); - UNIMPLEMENTED(); - return 0; -#endif } void Simulator::WriteH(int32_t addr, uint16_t value, Instruction* instr) { -#if V8_TARGET_CAN_READ_UNALIGNED - uint16_t* ptr = reinterpret_cast(addr); - *ptr = value; - return; -#else - if ((addr & 1) == 0) { + if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) { uint16_t* ptr = reinterpret_cast(addr); *ptr = value; - return; + } else { + PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08" + V8PRIxPTR "\n", + addr, + reinterpret_cast(instr)); + UNIMPLEMENTED(); } - PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", - addr, - reinterpret_cast(instr)); - UNIMPLEMENTED(); -#endif } void Simulator::WriteH(int32_t addr, int16_t value, Instruction* instr) { -#if V8_TARGET_CAN_READ_UNALIGNED - int16_t* ptr = reinterpret_cast(addr); - *ptr = value; - return; -#else - if ((addr & 1) == 0) { + if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) { int16_t* ptr = reinterpret_cast(addr); *ptr = value; - return; + } else { + PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", + addr, + reinterpret_cast(instr)); + UNIMPLEMENTED(); } - PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n", - addr, - reinterpret_cast(instr)); - UNIMPLEMENTED(); -#endif } @@ -1199,37 +1171,26 @@ void Simulator::WriteB(int32_t addr, int8_t value) { int32_t* Simulator::ReadDW(int32_t addr) { -#if V8_TARGET_CAN_READ_UNALIGNED - int32_t* ptr = reinterpret_cast(addr); - return ptr; -#else - if ((addr & 3) == 0) { + if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) { int32_t* ptr = reinterpret_cast(addr); return ptr; + } else { + PrintF("Unaligned read at 0x%08x\n", addr); + UNIMPLEMENTED(); + return 0; } - PrintF("Unaligned read at 0x%08x\n", addr); - UNIMPLEMENTED(); - return 0; -#endif } void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) { -#if V8_TARGET_CAN_READ_UNALIGNED - int32_t* ptr = reinterpret_cast(addr); - *ptr++ = value1; - *ptr = value2; - return; -#else - if ((addr & 3) == 0) { + if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) { int32_t* ptr = reinterpret_cast(addr); *ptr++ = value1; *ptr = value2; - return; + } else { + PrintF("Unaligned write at 0x%08x\n", addr); + UNIMPLEMENTED(); } - PrintF("Unaligned write at 0x%08x\n", addr); - UNIMPLEMENTED(); -#endif } diff --git a/src/flag-definitions.h b/src/flag-definitions.h index 02867ba6fe..f925d634db 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -288,6 +288,8 @@ DEFINE_bool(enable_armv7, true, "enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_sudiv, true, "enable use of SDIV and UDIV instructions if available (ARM only)") +DEFINE_bool(enable_unaligned_accesses, true, + "enable unaligned accesses for ARMv7 (ARM only)") DEFINE_bool(enable_fpu, true, "enable use of MIPS FPU instructions if available (MIPS only)") diff --git a/src/globals.h b/src/globals.h index 00ecd63d2a..babffbf659 100644 --- a/src/globals.h +++ b/src/globals.h @@ -136,21 +136,6 @@ namespace internal { #endif #endif -// Define unaligned read for the target architectures supporting it. -#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 -#endif - // Support for alternative bool type. This is only enabled if the code is // compiled with USE_MYBOOL defined. This catches some nasty type bugs. // For instance, 'bool b = "false";' results in b == true! This is a hidden diff --git a/src/regexp-macro-assembler.cc b/src/regexp-macro-assembler.cc index a4719b53fc..82ba34d5c8 100644 --- a/src/regexp-macro-assembler.cc +++ b/src/regexp-macro-assembler.cc @@ -67,11 +67,7 @@ NativeRegExpMacroAssembler::~NativeRegExpMacroAssembler() { bool NativeRegExpMacroAssembler::CanReadUnaligned() { -#ifdef V8_TARGET_CAN_READ_UNALIGNED - return !slow_safe(); -#else - return false; -#endif + return FLAG_enable_unaligned_accesses && !slow_safe(); } const byte* NativeRegExpMacroAssembler::StringCharacterPosition( diff --git a/src/v8globals.h b/src/v8globals.h index 1d22a11032..37c4c65a87 100644 --- a/src/v8globals.h +++ b/src/v8globals.h @@ -439,6 +439,7 @@ enum CpuFeature { SSE4_1 = 32 + 19, // x86 ARMv7 = 2, // ARM VFP2 = 3, // ARM SUDIV = 4, // ARM + UNALIGNED_ACCESSES = 5, // ARM SAHF = 0, // x86 FPU = 1}; // MIPS