Chromium Code Reviews| Index: src/compiler/wasm-compiler.cc |
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc |
| index 6b7c99327b17dd7552cba36b5cab84ac8be5ce60..b55a24f1fffb23d45e8ebbdeaddb3f81ac3f0f38 100644 |
| --- a/src/compiler/wasm-compiler.cc |
| +++ b/src/compiler/wasm-compiler.cc |
| @@ -1006,6 +1006,19 @@ Node* WasmGraphBuilder::MaskShiftCount64(Node* node) { |
| return node; |
| } |
| +static bool ReverseBytesSupported(MachineOperatorBuilder* m, |
| + size_t size_in_bytes) { |
| + switch (size_in_bytes) { |
| + case 4: |
| + return m->Word32ReverseBytes().IsSupported(); |
| + case 8: |
| + return m->Word64ReverseBytes().IsSupported(); |
| + default: |
| + break; |
| + } |
| + return false; |
| +} |
| + |
| Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype, |
| wasm::LocalType wasmtype) { |
| Node* result; |
| @@ -1053,44 +1066,65 @@ Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype, |
| int i; |
| uint32_t shiftCount; |
| - for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2; |
| - i += 8, shiftCount -= 16) { |
| - Node* shiftLower; |
| - Node* shiftHigher; |
| - Node* lowerByte; |
| - Node* higherByte; |
| - |
| - DCHECK(shiftCount > 0); |
| - DCHECK((shiftCount + 8) % 16 == 0); |
| - |
| - if (valueSizeInBits > 32) { |
| - shiftLower = graph()->NewNode(shiftLeftOpcode, value, |
| - jsgraph()->Int64Constant(shiftCount)); |
| - shiftHigher = graph()->NewNode(shiftRightOpcode, value, |
| - jsgraph()->Int64Constant(shiftCount)); |
| - lowerByte = graph()->NewNode( |
| - andOpcode, shiftLower, |
| - jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) |
| - << (valueSizeInBits - 8 - i))); |
| - higherByte = graph()->NewNode( |
| - andOpcode, shiftHigher, |
| - jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i)); |
| - } else { |
| - shiftLower = graph()->NewNode(shiftLeftOpcode, value, |
| - jsgraph()->Int32Constant(shiftCount)); |
| - shiftHigher = graph()->NewNode(shiftRightOpcode, value, |
| - jsgraph()->Int32Constant(shiftCount)); |
| - lowerByte = graph()->NewNode( |
| - andOpcode, shiftLower, |
| - jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) |
| - << (valueSizeInBits - 8 - i))); |
| - higherByte = graph()->NewNode( |
| - andOpcode, shiftHigher, |
| - jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i)); |
| + if (ReverseBytesSupported(m, valueSizeInBytes < 4 ? 4 : valueSizeInBytes)) { |
| + switch (valueSizeInBytes) { |
| + case 1: |
|
ahaas
2016/07/29 04:15:18
nit: you could remove this case, it should be unre
john.yan
2016/07/29 17:12:03
Done.
|
| + break; |
| + case 2: |
| + result = |
| + graph()->NewNode(m->Word32ReverseBytes().op(), |
| + graph()->NewNode(shiftLeftOpcode, value, |
| + jsgraph()->Int32Constant(16))); |
| + break; |
| + case 4: |
| + result = graph()->NewNode(m->Word32ReverseBytes().op(), value); |
| + break; |
| + case 8: |
| + result = graph()->NewNode(m->Word64ReverseBytes().op(), value); |
| + break; |
| + default: |
| + UNREACHABLE(); |
| } |
| + } else { |
| + for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2; |
| + i += 8, shiftCount -= 16) { |
| + Node* shiftLower; |
| + Node* shiftHigher; |
| + Node* lowerByte; |
| + Node* higherByte; |
| + |
| + DCHECK(shiftCount > 0); |
| + DCHECK((shiftCount + 8) % 16 == 0); |
| + |
| + if (valueSizeInBits > 32) { |
| + shiftLower = graph()->NewNode(shiftLeftOpcode, value, |
| + jsgraph()->Int64Constant(shiftCount)); |
| + shiftHigher = graph()->NewNode(shiftRightOpcode, value, |
| + jsgraph()->Int64Constant(shiftCount)); |
| + lowerByte = graph()->NewNode( |
| + andOpcode, shiftLower, |
| + jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) |
| + << (valueSizeInBits - 8 - i))); |
| + higherByte = graph()->NewNode( |
| + andOpcode, shiftHigher, |
| + jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i)); |
| + } else { |
| + shiftLower = graph()->NewNode(shiftLeftOpcode, value, |
| + jsgraph()->Int32Constant(shiftCount)); |
| + shiftHigher = graph()->NewNode(shiftRightOpcode, value, |
| + jsgraph()->Int32Constant(shiftCount)); |
| + lowerByte = graph()->NewNode( |
| + andOpcode, shiftLower, |
| + jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) |
| + << (valueSizeInBits - 8 - i))); |
| + higherByte = graph()->NewNode( |
| + andOpcode, shiftHigher, |
| + jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i)); |
| + } |
| - result = graph()->NewNode(orOpcode, result, lowerByte); |
| - result = graph()->NewNode(orOpcode, result, higherByte); |
| + result = graph()->NewNode(orOpcode, result, lowerByte); |
| + result = graph()->NewNode(orOpcode, result, higherByte); |
| + } |
| } |
| if (isFloat) { |
| @@ -1119,7 +1153,9 @@ Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype, |
| shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits); |
| result = graph()->NewNode( |
| m->Word64Sar(), |
| - graph()->NewNode(m->Word64Shl(), result, shiftBitCount), |
| + graph()->NewNode(m->Word64Shl(), |
| + graph()->NewNode(m->ChangeInt32ToInt64(), result), |
| + shiftBitCount), |
| shiftBitCount); |
| } else if (wasmtype == wasm::kAstI32) { |
| shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits); |
| @@ -3082,8 +3118,6 @@ Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, |
| 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 |
| @@ -3203,12 +3237,11 @@ Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, |
| // WASM semantics throw on OOB. Introduce explicit bounds check. |
| BoundsCheckMem(memtype, index, offset, position); |
| StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); |
| + |
| 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 |