Commit 1f5c91e4 authored by akos.palfi's avatar akos.palfi Committed by Commit bot

MIPS: Fix unaligned read/write operations in wasm.

TEST=cctest/test-run-wasm/*, cctest/test-run-wasm-module/*, unittests
BUG=

Review URL: https://codereview.chromium.org/1581223002

Cr-Commit-Position: refs/heads/master@{#33678}
parent 23943d0e
...@@ -1715,75 +1715,47 @@ inline uintptr_t GetCurrentStackPosition() { ...@@ -1715,75 +1715,47 @@ inline uintptr_t GetCurrentStackPosition() {
return limit; return limit;
} }
static inline double ReadDoubleValue(const void* p) { template <typename V>
#ifndef V8_TARGET_ARCH_MIPS static inline V ReadUnalignedValue(const void* p) {
return *reinterpret_cast<const double*>(p); #if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64)
return *reinterpret_cast<const V*>(p);
#else
V r;
memmove(&r, p, sizeof(V));
return r;
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
}
template <typename V>
static inline void WriteUnalignedValue(void* p, V value) {
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64)
*(reinterpret_cast<V*>(p)) = value;
#else // V8_TARGET_ARCH_MIPS #else // V8_TARGET_ARCH_MIPS
// Prevent compiler from using load-double (mips ldc1) on (possibly) memmove(p, &value, sizeof(V));
// non-64-bit aligned address. #endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
union conversion { }
double d;
uint32_t u[2]; static inline double ReadDoubleValue(const void* p) {
} c; return ReadUnalignedValue<double>(p);
const uint32_t* ptr = reinterpret_cast<const uint32_t*>(p);
c.u[0] = *ptr;
c.u[1] = *(ptr + 1);
return c.d;
#endif // V8_TARGET_ARCH_MIPS
} }
static inline void WriteDoubleValue(void* p, double value) { static inline void WriteDoubleValue(void* p, double value) {
#ifndef V8_TARGET_ARCH_MIPS WriteUnalignedValue(p, value);
*(reinterpret_cast<double*>(p)) = value;
#else // V8_TARGET_ARCH_MIPS
// Prevent compiler from using load-double (mips sdc1) on (possibly)
// non-64-bit aligned address.
union conversion {
double d;
uint32_t u[2];
} c;
c.d = value;
uint32_t* ptr = reinterpret_cast<uint32_t*>(p);
*ptr = c.u[0];
*(ptr + 1) = c.u[1];
#endif // V8_TARGET_ARCH_MIPS
} }
static inline uint16_t ReadUnalignedUInt16(const void* p) { static inline uint16_t ReadUnalignedUInt16(const void* p) {
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64) return ReadUnalignedValue<uint16_t>(p);
return *reinterpret_cast<const uint16_t*>(p);
#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
// Prevent compiler from using load-half (mips lh) on (possibly)
// non-16-bit aligned address.
union conversion {
uint16_t h;
uint8_t b[2];
} c;
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(p);
c.b[0] = *ptr;
c.b[1] = *(ptr + 1);
return c.h;
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
} }
static inline void WriteUnalignedUInt16(void* p, uint16_t value) { static inline void WriteUnalignedUInt16(void* p, uint16_t value) {
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64) WriteUnalignedValue(p, value);
*(reinterpret_cast<uint16_t*>(p)) = value; }
#else // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
// Prevent compiler from using store-half (mips sh) on (possibly) static inline void WriteUnalignedUInt32(void* p, uint32_t value) {
// non-16-bit aligned address. WriteUnalignedValue(p, value);
union conversion {
uint16_t h;
uint8_t b[2];
} c;
c.h = value;
uint8_t* ptr = reinterpret_cast<uint8_t*>(p);
*ptr = c.b[0];
*(ptr + 1) = c.b[1];
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
} }
} // namespace internal } // namespace internal
......
...@@ -30,13 +30,13 @@ void EmitUint8(byte** b, uint8_t x) { ...@@ -30,13 +30,13 @@ void EmitUint8(byte** b, uint8_t x) {
void EmitUint16(byte** b, uint16_t x) { void EmitUint16(byte** b, uint16_t x) {
Memory::uint16_at(*b) = x; WriteUnalignedUInt16(*b, x);
*b += 2; *b += 2;
} }
void EmitUint32(byte** b, uint32_t x) { void EmitUint32(byte** b, uint32_t x) {
Memory::uint32_at(*b) = x; WriteUnalignedUInt32(*b, x);
*b += 4; *b += 4;
} }
......
...@@ -196,7 +196,7 @@ class TestingModule : public ModuleEnv { ...@@ -196,7 +196,7 @@ class TestingModule : public ModuleEnv {
private: private:
WasmModuleInstance instance_; WasmModuleInstance instance_;
uint32_t global_offset; uint32_t global_offset;
byte global_data[kMaxGlobalsSize]; // preallocated global data. V8_ALIGNED(8) byte global_data[kMaxGlobalsSize]; // preallocated global data.
WasmGlobal* AddGlobal(MachineType mem_type) { WasmGlobal* AddGlobal(MachineType mem_type) {
AllocModule(); AllocModule();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment