Allow unaligned memory accesses on ARM targets that support it.
authorerik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 6 May 2010 12:49:12 +0000 (12:49 +0000)
committererik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 6 May 2010 12:49:12 +0000 (12:49 +0000)
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
src/arm/constants-arm.h
src/arm/regexp-macro-assembler-arm.cc
src/arm/simulator-arm.cc
src/globals.h

index c85ae1a..244e8ac 100644 (file)
@@ -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': {
index 5eed13f..57c5c1c 100644 (file)
 # 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
index 2fdba14..64fe5d6 100644 (file)
@@ -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));
+    }
   }
 }
 
index 5fe7d5f..95827a7 100644 (file)
@@ -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<intptr_t*>(addr);
+  return *ptr;
+#else
   if ((addr & 3) == 0) {
     intptr_t* ptr = reinterpret_cast<intptr_t*>(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<intptr_t*>(addr);
+  *ptr = value;
+  return;
+#else
   if ((addr & 3) == 0) {
     intptr_t* ptr = reinterpret_cast<intptr_t*>(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<uint16_t*>(addr);
+  return *ptr;
+#else
   if ((addr & 1) == 0) {
     uint16_t* ptr = reinterpret_cast<uint16_t*>(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<int16_t*>(addr);
+  return *ptr;
+#else
   if ((addr & 1) == 0) {
     int16_t* ptr = reinterpret_cast<int16_t*>(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<uint16_t*>(addr);
+  *ptr = value;
+  return;
+#else
   if ((addr & 1) == 0) {
     uint16_t* ptr = reinterpret_cast<uint16_t*>(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<int16_t*>(addr);
+  *ptr = value;
+  return;
+#else
   if ((addr & 1) == 0) {
     int16_t* ptr = reinterpret_cast<int16_t*>(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
 }
 
 
index bef5e8e..981ea16 100644 (file)
@@ -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