Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1281)

Unified Diff: src/compiler/wasm-compiler.cc

Issue 2034093002: Implement WASM big-endian support (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add byte swapping TODO mark Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/utils.h » ('j') | src/utils.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/wasm-compiler.cc
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
index 7270ddd24848854d9e42a020404ed04bdcca7ed4..d3193e3b2443947f9e9b77d89c88d63bc38b11b0 100644
--- a/src/compiler/wasm-compiler.cc
+++ b/src/compiler/wasm-compiler.cc
@@ -992,6 +992,117 @@ Node* WasmGraphBuilder::MaskShiftCount64(Node* node) {
return node;
}
+Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype,
+ wasm::LocalType wasmtype) {
+ Node* result;
+ Node* value = node;
+ wasm::WasmOpcode shiftLeftOpcode;
+ wasm::WasmOpcode shiftRightOpcode;
+ wasm::WasmOpcode andOpcode, orOpcode;
+ int valueSizeInBytes = 1 << ElementSizeLog2Of(memtype.representation());
+ int valueSizeInBits = 8 * valueSizeInBytes;
+ bool isFloat = false;
+
+ switch (memtype.representation()) {
+ case MachineRepresentation::kFloat64:
+ value = Unop(wasm::kExprI64ReinterpretF64, node);
+ isFloat = true;
+ case MachineRepresentation::kWord64:
+ shiftLeftOpcode = wasm::kExprI64Shl;
+ shiftRightOpcode = wasm::kExprI64ShrU;
+ andOpcode = wasm::kExprI64And;
+ orOpcode = wasm::kExprI64Ior;
+ result = jsgraph()->Int64Constant(0);
+ break;
+ case MachineRepresentation::kFloat32:
+ value = Unop(wasm::kExprI32ReinterpretF32, node);
+ isFloat = true;
+ case MachineRepresentation::kWord32:
+ case MachineRepresentation::kWord16:
+ shiftLeftOpcode = wasm::kExprI32Shl;
+ shiftRightOpcode = wasm::kExprI32ShrU;
+ andOpcode = wasm::kExprI32And;
+ orOpcode = wasm::kExprI32Ior;
+ 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 =
+ Binop(shiftLeftOpcode, value, jsgraph()->Int32Constant(shiftCount));
titzer 2016/06/06 07:44:00 Reusing the Binop() routine is a little inefficien
+ Node* shiftHigher =
+ Binop(shiftRightOpcode, value, jsgraph()->Int32Constant(shiftCount));
+
+ Node* lowerByte;
+ Node* higherByte;
+
+ if (valueSizeInBits > 32) {
+ lowerByte =
+ Binop(andOpcode, shiftLower,
+ jsgraph()->Int64Constant(0xFFl << (valueSizeInBits - 8 - i)));
+ higherByte =
+ Binop(andOpcode, shiftHigher, jsgraph()->Int64Constant(0xFFl << i));
+ } else {
+ lowerByte =
+ Binop(andOpcode, shiftLower,
+ jsgraph()->Int32Constant(0xFF << (valueSizeInBits - 8 - i)));
+ higherByte =
+ Binop(andOpcode, shiftHigher, jsgraph()->Int32Constant(0xFF << i));
+ }
+
+ result = Binop(orOpcode, result, lowerByte);
+ result = Binop(orOpcode, result, higherByte);
+ }
+
+ if (isFloat) {
+ switch (memtype.representation()) {
+ case MachineRepresentation::kFloat64:
+ result = Unop(wasm::kExprF64ReinterpretI64, result);
+ break;
+ case MachineRepresentation::kFloat32:
+ result = Unop(wasm::kExprF32ReinterpretI32, result);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ // We need to sign extend the value
+ if (memtype.IsSigned()) {
+ DCHECK(!isFloat);
+ if ((wasmtype == wasm::kAstI64 || wasmtype == wasm::kAstI32) &&
+ valueSizeInBits < 32) {
+ uint32_t mask = 1 << (valueSizeInBits - 1);
+
+ Node* signBit =
+ Binop(wasm::kExprI32And, result, jsgraph()->Int32Constant(mask));
+ Diamond d(graph(), jsgraph()->common(), Unop(wasm::kExprI32Eqz, signBit));
titzer 2016/06/06 07:44:00 What about using (x << machine_width - width) >> (
+
+ result =
+ d.Phi(MachineRepresentation::kWord32, result,
+ Binop(wasm::kExprI32Ior, result,
+ jsgraph()->Int32Constant(0xFFFFFFFF << valueSizeInBits)));
+ }
+ }
+
+ return result;
+}
+
Node* WasmGraphBuilder::BuildF32Neg(Node* input) {
Node* result =
Unop(wasm::kExprF32ReinterpretI32,
@@ -2768,6 +2879,11 @@ Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype,
} else {
load = BuildUnalignedLoad(type, memtype, index, offset, alignment);
}
+#if defined(V8_TARGET_BIG_ENDIAN)
+ // TODO(mips-team) Implement byte swap turbofan operator
john.yan 2016/06/07 17:47:00 FYI: https://codereview.chromium.org/2045943002/
+ // and use it if available for better performance
+ load = BuildChangeEndianness(load, memtype, type);
+#endif
if (type == wasm::kAstI64 &&
ElementSizeLog2Of(memtype.representation()) < 3) {
@@ -2888,6 +3004,12 @@ Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index,
bool aligned = static_cast<int>(alignment) >=
ElementSizeLog2Of(memtype.representation());
+#if defined(V8_TARGET_BIG_ENDIAN)
+ // TODO(mips-team) 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);
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/utils.h » ('j') | src/utils.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698