Index: src/compiler/wasm-compiler.cc |
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc |
index 71f450f0743cc6ba6a2d6bdafb2d1e8cab77064d..d2ab271c183a68910e907c9a51ec17c4b5e823ff 100644 |
--- a/src/compiler/wasm-compiler.cc |
+++ b/src/compiler/wasm-compiler.cc |
@@ -1007,14 +1007,23 @@ 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; |
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; |
@@ -1025,10 +1034,6 @@ Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype, |
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: |
@@ -1036,10 +1041,6 @@ Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype, |
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: |
@@ -1054,44 +1055,64 @@ 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 2: |
+ result = |
+ graph()->NewNode(m->Word32ReverseBytes().op(), |
+ graph()->NewNode(m->Word32Shl(), 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(m->Word64Shl(), value, |
+ jsgraph()->Int64Constant(shiftCount)); |
+ shiftHigher = graph()->NewNode(m->Word64Shr(), value, |
+ jsgraph()->Int64Constant(shiftCount)); |
+ lowerByte = graph()->NewNode( |
+ m->Word64And(), shiftLower, |
+ jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) |
+ << (valueSizeInBits - 8 - i))); |
+ higherByte = graph()->NewNode( |
+ m->Word64And(), shiftHigher, |
+ jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i)); |
+ result = graph()->NewNode(m->Word64Or(), result, lowerByte); |
+ result = graph()->NewNode(m->Word64Or(), result, higherByte); |
+ } else { |
+ shiftLower = graph()->NewNode(m->Word32Shl(), value, |
+ jsgraph()->Int32Constant(shiftCount)); |
+ shiftHigher = graph()->NewNode(m->Word32Shr(), value, |
+ jsgraph()->Int32Constant(shiftCount)); |
+ lowerByte = graph()->NewNode( |
+ m->Word32And(), shiftLower, |
+ jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) |
+ << (valueSizeInBits - 8 - i))); |
+ higherByte = graph()->NewNode( |
+ m->Word32And(), shiftHigher, |
+ jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i)); |
+ result = graph()->NewNode(m->Word32Or(), result, lowerByte); |
+ result = graph()->NewNode(m->Word32Or(), result, higherByte); |
+ } |
} |
- |
- result = graph()->NewNode(orOpcode, result, lowerByte); |
- result = graph()->NewNode(orOpcode, result, higherByte); |
} |
if (isFloat) { |
@@ -1120,7 +1141,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); |
@@ -2983,8 +3006,6 @@ Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, |
*effect_ = load; |
#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 |
@@ -3013,12 +3034,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 |