__ 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));
+ }
}
}
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;
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;
}
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;
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;
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;
}
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;
}
PrintF("Unaligned halfword write at 0x%08x, pc=%p\n", addr, instr);
UNIMPLEMENTED();
+#endif
}
#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
#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