Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
Revert of Implement WASM big-endian support (patchset #5 id:80001 of h…
Browse files Browse the repository at this point in the history
…ttps://codereview.chromium.org/2034093002/ )

Reason for revert:
[Sheriff] Speculative revert for crashes on chrubuntu chromebooks:
https://build.chromium.org/p/client.v8.ports/builders/V8%20Arm/builds/320

Original issue's description:
> Implement WASM big-endian support.
>
> Implement WASM support on big-endian platforms. WASM has
> an implicit requirement that it is running on little-endian
> machine. We achieve WASM support on BE by keeping data
> in memory in little-endian order, and changing data
> endianness before storing to memory and after loading from
> memory.
>
> BUG=
>
> Committed: https://crrev.com/d3f3f6c8186b2a53f0c539f7bba0c3708c4d83f9
> Cr-Commit-Position: refs/heads/master@{#37065}

TBR=titzer@chromium.org,akos.palfi@imgtec.com,balazs.kilvady@imgtec.com,jyan@ca.ibm.com,ivica.bogosavljevic@imgtec.com
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=

Review-Url: https://codereview.chromium.org/2080153002
Cr-Commit-Position: refs/heads/master@{#37091}
  • Loading branch information
mi-ac authored and Commit bot committed Jun 20, 2016
1 parent 46c21b2 commit 093df3f
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 267 deletions.
130 changes: 0 additions & 130 deletions src/compiler/wasm-compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -992,125 +992,6 @@ Node* WasmGraphBuilder::MaskShiftCount64(Node* node) {
return node;
}

Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype,
wasm::LocalType wasmtype) {
Node* result;
Node* value = node;
const Operator* shiftLeftOpcode;
const Operator* shiftRightOpcode;
const Operator* andOpcode;
const Operator* orOpcode;
MachineOperatorBuilder* m = jsgraph()->machine();
int valueSizeInBytes = 1 << ElementSizeLog2Of(memtype.representation());
int valueSizeInBits = 8 * valueSizeInBytes;
bool isFloat = false;

switch (memtype.representation()) {
case MachineRepresentation::kFloat64:
value = graph()->NewNode(m->BitcastFloat64ToInt64(), node);
isFloat = true;
case MachineRepresentation::kWord64:
shiftLeftOpcode = m->Word64Shl();
shiftRightOpcode = m->Word64Shr();
andOpcode = m->Word64And();
orOpcode = m->Word64Or();
result = jsgraph()->Int64Constant(0);
break;
case MachineRepresentation::kFloat32:
value = graph()->NewNode(m->BitcastFloat32ToInt32(), node);
isFloat = true;
case MachineRepresentation::kWord32:
case MachineRepresentation::kWord16:
shiftLeftOpcode = m->Word32Shl();
shiftRightOpcode = m->Word32Shr();
andOpcode = m->Word32And();
orOpcode = m->Word32Or();
result = jsgraph()->Int32Constant(0);
break;
case MachineRepresentation::kWord8:
// No need to change endianness for byte size, return original node
return node;
break;
default:
UNREACHABLE();
break;
}

int i;
uint32_t shiftCount;

for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2;
i += 8, shiftCount -= 16) {
DCHECK(shiftCount > 0);
DCHECK((shiftCount + 8) % 16 == 0);

Node* shiftLower = graph()->NewNode(shiftLeftOpcode, value,
jsgraph()->Int32Constant(shiftCount));
Node* shiftHigher = graph()->NewNode(shiftRightOpcode, value,
jsgraph()->Int32Constant(shiftCount));

Node* lowerByte;
Node* higherByte;

if (valueSizeInBits > 32) {
lowerByte = graph()->NewNode(
andOpcode, shiftLower,
jsgraph()->Int64Constant(0xFFl << (valueSizeInBits - 8 - i)));
higherByte = graph()->NewNode(andOpcode, shiftHigher,
jsgraph()->Int64Constant(0xFFl << i));
} else {
lowerByte = graph()->NewNode(
andOpcode, shiftLower,
jsgraph()->Int32Constant(0xFF << (valueSizeInBits - 8 - i)));
higherByte = graph()->NewNode(andOpcode, shiftHigher,
jsgraph()->Int32Constant(0xFF << i));
}

result = graph()->NewNode(orOpcode, result, lowerByte);
result = graph()->NewNode(orOpcode, result, higherByte);
}

if (isFloat) {
switch (memtype.representation()) {
case MachineRepresentation::kFloat64:
result = graph()->NewNode(m->BitcastInt64ToFloat64(), result);
break;
case MachineRepresentation::kFloat32:
result = graph()->NewNode(m->BitcastInt32ToFloat32(), result);
break;
default:
UNREACHABLE();
break;
}
}

// We need to sign extend the value
if (memtype.IsSigned()) {
DCHECK(!isFloat);
if (valueSizeInBits < 32) {
Node* shiftBitCount;
// Perform sign extension using following trick
// result = (x << machine_width - type_width) >> (machine_width -
// type_width)
if (wasmtype == wasm::kAstI64) {
shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits);
result = graph()->NewNode(
m->Word64Sar(),
graph()->NewNode(m->Word64Shl(), result, shiftBitCount),
shiftBitCount);
} else if (wasmtype == wasm::kAstI32) {
shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits);
result = graph()->NewNode(
m->Word32Sar(),
graph()->NewNode(m->Word32Shl(), result, shiftBitCount),
shiftBitCount);
}
}
}

return result;
}

Node* WasmGraphBuilder::BuildF32Neg(Node* input) {
Node* result =
Unop(wasm::kExprF32ReinterpretI32,
Expand Down Expand Up @@ -2868,11 +2749,6 @@ Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype,
} else {
load = BuildUnalignedLoad(type, memtype, index, offset, alignment);
}
#if defined(V8_TARGET_BIG_ENDIAN)
// TODO(john.yan) Implement byte swap turbofan operator
// and use it if available for better performance
load = BuildChangeEndianness(load, memtype, type);
#endif

if (type == wasm::kAstI64 &&
ElementSizeLog2Of(memtype.representation()) < 3) {
Expand Down Expand Up @@ -2993,12 +2869,6 @@ Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index,
bool aligned = static_cast<int>(alignment) >=
ElementSizeLog2Of(memtype.representation());

#if defined(V8_TARGET_BIG_ENDIAN)
// TODO(john.yan) Implement byte swap turbofan operator
// and use it if available for better performance
val = BuildChangeEndianness(val, memtype);
#endif

if (aligned ||
jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) {
StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
Expand Down
3 changes: 0 additions & 3 deletions src/compiler/wasm-compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,6 @@ class WasmGraphBuilder {
Node* BuildUnalignedStore(MachineType memtype, Node* index, uint32_t offset,
uint32_t alignment, Node* val);

Node* BuildChangeEndianness(Node* node, MachineType type,
wasm::LocalType wasmtype = wasm::kAstStmt);

Node* MaskShiftCount32(Node* node);
Node* MaskShiftCount64(Node* node);

Expand Down
27 changes: 0 additions & 27 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -1552,33 +1552,6 @@ static inline void WriteUnalignedUInt32(void* p, uint32_t value) {
WriteUnalignedValue(p, value);
}

template <typename V>
static inline V ReadLittleEndianValue(const void* p) {
#if defined(V8_TARGET_LITTLE_ENDIAN)
return ReadUnalignedValue<V>(p);
#elif defined(V8_TARGET_BIG_ENDIAN)
V ret = 0;
const byte* src = reinterpret_cast<const byte*>(p);
byte* dst = reinterpret_cast<byte*>(&ret);
for (size_t i = 0; i < sizeof(V); i++) {
dst[i] = src[sizeof(V) - i - 1];
}
return ret;
#endif // V8_TARGET_LITTLE_ENDIAN
}

template <typename V>
static inline void WriteLittleEndianValue(void* p, V value) {
#if defined(V8_TARGET_LITTLE_ENDIAN)
WriteUnalignedValue<V>(p, value);
#elif defined(V8_TARGET_BIG_ENDIAN)
byte* src = reinterpret_cast<byte*>(&value);
byte* dst = reinterpret_cast<byte*>(p);
for (size_t i = 0; i < sizeof(V); i++) {
dst[i] = src[sizeof(V) - i - 1];
}
#endif // V8_TARGET_LITTLE_ENDIAN
}
} // namespace internal
} // namespace v8

Expand Down
40 changes: 37 additions & 3 deletions src/wasm/decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ namespace wasm {
#define TRACE(...)
#endif

#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM)
#define UNALIGNED_ACCESS_OK 1
#else
#define UNALIGNED_ACCESS_OK 0
#endif

// A helper utility to decode bytes, integers, fields, varints, etc, from
// a buffer of bytes.
class Decoder {
Expand Down Expand Up @@ -116,19 +122,47 @@ class Decoder {
// Reads a single 16-bit unsigned integer (little endian).
inline uint16_t read_u16(const byte* ptr) {
DCHECK(ptr >= start_ && (ptr + 2) <= end_);
return ReadLittleEndianValue<uint16_t>(ptr);
#if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK
return *reinterpret_cast<const uint16_t*>(ptr);
#else
uint16_t b0 = ptr[0];
uint16_t b1 = ptr[1];
return (b1 << 8) | b0;
#endif
}

// Reads a single 32-bit unsigned integer (little endian).
inline uint32_t read_u32(const byte* ptr) {
DCHECK(ptr >= start_ && (ptr + 4) <= end_);
return ReadLittleEndianValue<uint32_t>(ptr);
#if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK
return *reinterpret_cast<const uint32_t*>(ptr);
#else
uint32_t b0 = ptr[0];
uint32_t b1 = ptr[1];
uint32_t b2 = ptr[2];
uint32_t b3 = ptr[3];
return (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
#endif
}

// Reads a single 64-bit unsigned integer (little endian).
inline uint64_t read_u64(const byte* ptr) {
DCHECK(ptr >= start_ && (ptr + 8) <= end_);
return ReadLittleEndianValue<uint64_t>(ptr);
#if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK
return *reinterpret_cast<const uint64_t*>(ptr);
#else
uint32_t b0 = ptr[0];
uint32_t b1 = ptr[1];
uint32_t b2 = ptr[2];
uint32_t b3 = ptr[3];
uint32_t low = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
uint32_t b4 = ptr[4];
uint32_t b5 = ptr[5];
uint32_t b6 = ptr[6];
uint32_t b7 = ptr[7];
uint64_t high = (b7 << 24) | (b6 << 16) | (b5 << 8) | b4;
return (high << 32) | low;
#endif
}

// Reads a 8-bit unsigned integer (byte) and advances {pc_}.
Expand Down
16 changes: 14 additions & 2 deletions src/wasm/encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,25 @@ class ZoneBuffer : public ZoneObject {

void write_u16(uint16_t x) {
EnsureSpace(2);
WriteLittleEndianValue<uint16_t>(pos_, x);
#if V8_TARGET_LITTLE_ENDIAN
WriteUnalignedUInt16(pos_, x);
#else
pos_[0] = x & 0xff;
pos_[1] = (x >> 8) & 0xff;
#endif
pos_ += 2;
}

void write_u32(uint32_t x) {
EnsureSpace(4);
WriteLittleEndianValue<uint32_t>(pos_, x);
#if V8_TARGET_LITTLE_ENDIAN
WriteUnalignedUInt32(pos_, x);
#else
pos_[0] = x & 0xff;
pos_[1] = (x >> 8) & 0xff;
pos_[2] = (x >> 16) & 0xff;
pos_[3] = (x >> 24) & 0xff;
#endif
pos_ += 4;
}

Expand Down
58 changes: 29 additions & 29 deletions src/wasm/wasm-interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1437,20 +1437,20 @@ class ThreadImpl : public WasmInterpreter::Thread {
break;
}

#define LOAD_CASE(name, ctype, mtype) \
case kExpr##name: { \
MemoryAccessOperand operand(&decoder, code->at(pc)); \
uint32_t index = Pop().to<uint32_t>(); \
size_t effective_mem_size = instance()->mem_size - sizeof(mtype); \
if (operand.offset > effective_mem_size || \
index > (effective_mem_size - operand.offset)) { \
return DoTrap(kTrapMemOutOfBounds, pc); \
} \
byte* addr = instance()->mem_start + operand.offset + index; \
WasmVal result(static_cast<ctype>(ReadLittleEndianValue<mtype>(addr))); \
Push(pc, result); \
len = 1 + operand.length; \
break; \
#define LOAD_CASE(name, ctype, mtype) \
case kExpr##name: { \
MemoryAccessOperand operand(&decoder, code->at(pc)); \
uint32_t index = Pop().to<uint32_t>(); \
size_t effective_mem_size = instance()->mem_size - sizeof(mtype); \
if (operand.offset > effective_mem_size || \
index > (effective_mem_size - operand.offset)) { \
return DoTrap(kTrapMemOutOfBounds, pc); \
} \
byte* addr = instance()->mem_start + operand.offset + index; \
WasmVal result(static_cast<ctype>(ReadUnalignedValue<mtype>(addr))); \
Push(pc, result); \
len = 1 + operand.length; \
break; \
}

LOAD_CASE(I32LoadMem8S, int32_t, int8_t);
Expand All @@ -1469,21 +1469,21 @@ class ThreadImpl : public WasmInterpreter::Thread {
LOAD_CASE(F64LoadMem, double, double);
#undef LOAD_CASE

#define STORE_CASE(name, ctype, mtype) \
case kExpr##name: { \
MemoryAccessOperand operand(&decoder, code->at(pc)); \
WasmVal val = Pop(); \
uint32_t index = Pop().to<uint32_t>(); \
size_t effective_mem_size = instance()->mem_size - sizeof(mtype); \
if (operand.offset > effective_mem_size || \
index > (effective_mem_size - operand.offset)) { \
return DoTrap(kTrapMemOutOfBounds, pc); \
} \
byte* addr = instance()->mem_start + operand.offset + index; \
WriteLittleEndianValue<mtype>(addr, static_cast<mtype>(val.to<ctype>())); \
Push(pc, val); \
len = 1 + operand.length; \
break; \
#define STORE_CASE(name, ctype, mtype) \
case kExpr##name: { \
MemoryAccessOperand operand(&decoder, code->at(pc)); \
WasmVal val = Pop(); \
uint32_t index = Pop().to<uint32_t>(); \
size_t effective_mem_size = instance()->mem_size - sizeof(mtype); \
if (operand.offset > effective_mem_size || \
index > (effective_mem_size - operand.offset)) { \
return DoTrap(kTrapMemOutOfBounds, pc); \
} \
byte* addr = instance()->mem_start + operand.offset + index; \
WriteUnalignedValue<mtype>(addr, static_cast<mtype>(val.to<ctype>())); \
Push(pc, val); \
len = 1 + operand.length; \
break; \
}

STORE_CASE(I32StoreMem8, int32_t, int8_t);
Expand Down
19 changes: 19 additions & 0 deletions test/cctest/cctest.status
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,25 @@
'test-cpu-profiler/JsNative1JsNative2JsSample': [SKIP],
}], # 'system == windows'

##############################################################################
['byteorder == big', {
# TODO(mips-team): Fix Wasm for big-endian.
'test-run-wasm-module/Run_WasmModule_CallAdd': [SKIP],
'test-run-wasm-module/Run_WasmModule_CallMain_recursive': [SKIP],
'test-run-wasm-module/Run_WasmModule_ReadLoadedDataSegment': [SKIP],
'test-run-wasm-module/Run_WasmModule_Return114': [SKIP],
'test-run-wasm-module/Run_WasmModule_CheckMemoryIsZero': [SKIP],
'test-run-wasm-module/Run_WasmModule_Global': [SKIP],
'test-run-wasm/RunWasmCompiled_Int32LoadInt16_signext': [SKIP],
'test-run-wasm/RunWasmCompiled_Int32LoadInt16_zeroext': [SKIP],
'test-run-wasm/RunWasmCompiled_MixedGlobals': [SKIP],
'test-run-wasm-64/RunWasmCompiled_I64*': [SKIP],
'test-run-wasm-64/RunWasmCompiled_LoadStoreI64_sx': [SKIP],
'test-run-wasm-64/Run_TestI64WasmRunner': [SKIP],
'test-run-wasm-64/RunWasmCompiled_Call_Int64Sub': [SKIP],
'test-run-wasm-64/RunWasmCompiled_MemI64_Sum': [SKIP],
}], # 'byteorder == big'

##############################################################################
['arch == arm', {

Expand Down
Loading

0 comments on commit 093df3f

Please sign in to comment.