Allow unaligned accesses for ARMv7.
authorulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 15 Oct 2012 15:19:36 +0000 (15:19 +0000)
committerulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 15 Oct 2012 15:19:36 +0000 (15:19 +0000)
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
src/arm/assembler-arm.h
src/arm/constants-arm.h
src/arm/macro-assembler-arm.cc
src/arm/regexp-macro-assembler-arm.cc
src/arm/regexp-macro-assembler-arm.h
src/arm/simulator-arm.cc
src/flag-definitions.h
src/globals.h
src/regexp-macro-assembler.cc
src/v8globals.h

index 129e62b..86bed1c 100644 (file)
@@ -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
 
index 005c78d..7c80b09 100644 (file)
@@ -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;
   }
 
index 5aadc3c..a6b5843 100644 (file)
 
 #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
index 4da5387..31915a5 100644 (file)
@@ -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);
 
index 66cdd84..17b8677 100644 (file)
@@ -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) {
index f723fa2..c45669a 100644 (file)
@@ -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
index 91df404..a75046a 100644 (file)
@@ -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<intptr_t*>(addr);
-  return *ptr;
-#else
-  if ((addr & 3) == 0) {
+  if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
     return *ptr;
+  } else {
+    PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
+           addr,
+           reinterpret_cast<intptr_t>(instr));
+    UNIMPLEMENTED();
+    return 0;
   }
-  PrintF("Unaligned read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
-         addr,
-         reinterpret_cast<intptr_t>(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<intptr_t*>(addr);
-  *ptr = value;
-  return;
-#else
-  if ((addr & 3) == 0) {
+  if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
     intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
     *ptr = value;
-    return;
+  } else {
+    PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
+           addr,
+           reinterpret_cast<intptr_t>(instr));
+    UNIMPLEMENTED();
   }
-  PrintF("Unaligned write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
-         addr,
-         reinterpret_cast<intptr_t>(instr));
-  UNIMPLEMENTED();
-#endif
 }
 
 
 uint16_t Simulator::ReadHU(int32_t addr, Instruction* instr) {
-#if V8_TARGET_CAN_READ_UNALIGNED
-  uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
-  return *ptr;
-#else
-  if ((addr & 1) == 0) {
+  if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
     return *ptr;
+  } else {
+    PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08"
+           V8PRIxPTR "\n",
+           addr,
+           reinterpret_cast<intptr_t>(instr));
+    UNIMPLEMENTED();
+    return 0;
   }
-  PrintF("Unaligned unsigned halfword read at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
-         addr,
-         reinterpret_cast<intptr_t>(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<int16_t*>(addr);
-  return *ptr;
-#else
-  if ((addr & 1) == 0) {
+  if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
     int16_t* ptr = reinterpret_cast<int16_t*>(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<uint16_t*>(addr);
-  *ptr = value;
-  return;
-#else
-  if ((addr & 1) == 0) {
+  if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
     uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
     *ptr = value;
-    return;
+  } else {
+    PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08"
+           V8PRIxPTR "\n",
+           addr,
+           reinterpret_cast<intptr_t>(instr));
+    UNIMPLEMENTED();
   }
-  PrintF("Unaligned unsigned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
-         addr,
-         reinterpret_cast<intptr_t>(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<int16_t*>(addr);
-  *ptr = value;
-  return;
-#else
-  if ((addr & 1) == 0) {
+  if (FLAG_enable_unaligned_accesses || (addr & 1) == 0) {
     int16_t* ptr = reinterpret_cast<int16_t*>(addr);
     *ptr = value;
-    return;
+  } else {
+    PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
+           addr,
+           reinterpret_cast<intptr_t>(instr));
+    UNIMPLEMENTED();
   }
-  PrintF("Unaligned halfword write at 0x%08x, pc=0x%08" V8PRIxPTR "\n",
-         addr,
-         reinterpret_cast<intptr_t>(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<int32_t*>(addr);
-  return ptr;
-#else
-  if ((addr & 3) == 0) {
+  if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
     int32_t* ptr = reinterpret_cast<int32_t*>(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<int32_t*>(addr);
-  *ptr++ = value1;
-  *ptr = value2;
-  return;
-#else
-  if ((addr & 3) == 0) {
+  if (FLAG_enable_unaligned_accesses || (addr & 3) == 0) {
     int32_t* ptr = reinterpret_cast<int32_t*>(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
 }
 
 
index 02867ba..f925d63 100644 (file)
@@ -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)")
 
index 00ecd63..babffbf 100644 (file)
@@ -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
index a4719b5..82ba34d 100644 (file)
@@ -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(
index 1d22a11..37c4c65 100644 (file)
@@ -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