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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/wasm-compiler.h" 5 #include "src/compiler/wasm-compiler.h"
6 6
7 #include "src/isolate-inl.h" 7 #include "src/isolate-inl.h"
8 8
9 #include "src/base/platform/elapsed-timer.h" 9 #include "src/base/platform/elapsed-timer.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 int64_t masked = (match.Value() & kMask64); 985 int64_t masked = (match.Value() & kMask64);
986 if (match.Value() != masked) node = jsgraph()->Int64Constant(masked); 986 if (match.Value() != masked) node = jsgraph()->Int64Constant(masked);
987 } else { 987 } else {
988 node = graph()->NewNode(jsgraph()->machine()->Word64And(), node, 988 node = graph()->NewNode(jsgraph()->machine()->Word64And(), node,
989 jsgraph()->Int64Constant(kMask64)); 989 jsgraph()->Int64Constant(kMask64));
990 } 990 }
991 } 991 }
992 return node; 992 return node;
993 } 993 }
994 994
995 Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype,
996 wasm::LocalType wasmtype) {
997 Node* result;
998 Node* value = node;
999 wasm::WasmOpcode shiftLeftOpcode;
1000 wasm::WasmOpcode shiftRightOpcode;
1001 wasm::WasmOpcode andOpcode, orOpcode;
1002 int valueSizeInBytes = 1 << ElementSizeLog2Of(memtype.representation());
1003 int valueSizeInBits = 8 * valueSizeInBytes;
1004 bool isFloat = false;
1005
1006 switch (memtype.representation()) {
1007 case MachineRepresentation::kFloat64:
1008 value = Unop(wasm::kExprI64ReinterpretF64, node);
1009 isFloat = true;
1010 case MachineRepresentation::kWord64:
1011 shiftLeftOpcode = wasm::kExprI64Shl;
1012 shiftRightOpcode = wasm::kExprI64ShrU;
1013 andOpcode = wasm::kExprI64And;
1014 orOpcode = wasm::kExprI64Ior;
1015 result = jsgraph()->Int64Constant(0);
1016 break;
1017 case MachineRepresentation::kFloat32:
1018 value = Unop(wasm::kExprI32ReinterpretF32, node);
1019 isFloat = true;
1020 case MachineRepresentation::kWord32:
1021 case MachineRepresentation::kWord16:
1022 shiftLeftOpcode = wasm::kExprI32Shl;
1023 shiftRightOpcode = wasm::kExprI32ShrU;
1024 andOpcode = wasm::kExprI32And;
1025 orOpcode = wasm::kExprI32Ior;
1026 result = jsgraph()->Int32Constant(0);
1027 break;
1028 case MachineRepresentation::kWord8:
1029 // No need to change endianness for byte size, return original node
1030 return node;
1031 break;
1032 default:
1033 UNREACHABLE();
1034 break;
1035 }
1036
1037 int i;
1038 uint32_t shiftCount;
1039
1040 for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2;
1041 i += 8, shiftCount -= 16) {
1042 DCHECK(shiftCount > 0);
1043 DCHECK((shiftCount + 8) % 16 == 0);
1044
1045 Node* shiftLower =
1046 Binop(shiftLeftOpcode, value, jsgraph()->Int32Constant(shiftCount));
titzer 2016/06/06 07:44:00 Reusing the Binop() routine is a little inefficien
1047 Node* shiftHigher =
1048 Binop(shiftRightOpcode, value, jsgraph()->Int32Constant(shiftCount));
1049
1050 Node* lowerByte;
1051 Node* higherByte;
1052
1053 if (valueSizeInBits > 32) {
1054 lowerByte =
1055 Binop(andOpcode, shiftLower,
1056 jsgraph()->Int64Constant(0xFFl << (valueSizeInBits - 8 - i)));
1057 higherByte =
1058 Binop(andOpcode, shiftHigher, jsgraph()->Int64Constant(0xFFl << i));
1059 } else {
1060 lowerByte =
1061 Binop(andOpcode, shiftLower,
1062 jsgraph()->Int32Constant(0xFF << (valueSizeInBits - 8 - i)));
1063 higherByte =
1064 Binop(andOpcode, shiftHigher, jsgraph()->Int32Constant(0xFF << i));
1065 }
1066
1067 result = Binop(orOpcode, result, lowerByte);
1068 result = Binop(orOpcode, result, higherByte);
1069 }
1070
1071 if (isFloat) {
1072 switch (memtype.representation()) {
1073 case MachineRepresentation::kFloat64:
1074 result = Unop(wasm::kExprF64ReinterpretI64, result);
1075 break;
1076 case MachineRepresentation::kFloat32:
1077 result = Unop(wasm::kExprF32ReinterpretI32, result);
1078 break;
1079 default:
1080 UNREACHABLE();
1081 break;
1082 }
1083 }
1084
1085 // We need to sign extend the value
1086 if (memtype.IsSigned()) {
1087 DCHECK(!isFloat);
1088 if ((wasmtype == wasm::kAstI64 || wasmtype == wasm::kAstI32) &&
1089 valueSizeInBits < 32) {
1090 uint32_t mask = 1 << (valueSizeInBits - 1);
1091
1092 Node* signBit =
1093 Binop(wasm::kExprI32And, result, jsgraph()->Int32Constant(mask));
1094 Diamond d(graph(), jsgraph()->common(), Unop(wasm::kExprI32Eqz, signBit));
titzer 2016/06/06 07:44:00 What about using (x << machine_width - width) >> (
1095
1096 result =
1097 d.Phi(MachineRepresentation::kWord32, result,
1098 Binop(wasm::kExprI32Ior, result,
1099 jsgraph()->Int32Constant(0xFFFFFFFF << valueSizeInBits)));
1100 }
1101 }
1102
1103 return result;
1104 }
1105
995 Node* WasmGraphBuilder::BuildF32Neg(Node* input) { 1106 Node* WasmGraphBuilder::BuildF32Neg(Node* input) {
996 Node* result = 1107 Node* result =
997 Unop(wasm::kExprF32ReinterpretI32, 1108 Unop(wasm::kExprF32ReinterpretI32,
998 Binop(wasm::kExprI32Xor, Unop(wasm::kExprI32ReinterpretF32, input), 1109 Binop(wasm::kExprI32Xor, Unop(wasm::kExprI32ReinterpretF32, input),
999 jsgraph()->Int32Constant(0x80000000))); 1110 jsgraph()->Int32Constant(0x80000000)));
1000 1111
1001 return result; 1112 return result;
1002 } 1113 }
1003 1114
1004 Node* WasmGraphBuilder::BuildF64Neg(Node* input) { 1115 Node* WasmGraphBuilder::BuildF64Neg(Node* input) {
(...skipping 1756 matching lines...) Expand 10 before | Expand all | Expand 10 after
2761 ElementSizeLog2Of(memtype.representation()); 2872 ElementSizeLog2Of(memtype.representation());
2762 2873
2763 if (aligned || 2874 if (aligned ||
2764 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) { 2875 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) {
2765 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), 2876 load = graph()->NewNode(jsgraph()->machine()->Load(memtype),
2766 MemBuffer(offset), index, *effect_, *control_); 2877 MemBuffer(offset), index, *effect_, *control_);
2767 *effect_ = load; 2878 *effect_ = load;
2768 } else { 2879 } else {
2769 load = BuildUnalignedLoad(type, memtype, index, offset, alignment); 2880 load = BuildUnalignedLoad(type, memtype, index, offset, alignment);
2770 } 2881 }
2882 #if defined(V8_TARGET_BIG_ENDIAN)
2883 // TODO(mips-team) Implement byte swap turbofan operator
john.yan 2016/06/07 17:47:00 FYI: https://codereview.chromium.org/2045943002/
2884 // and use it if available for better performance
2885 load = BuildChangeEndianness(load, memtype, type);
2886 #endif
2771 2887
2772 if (type == wasm::kAstI64 && 2888 if (type == wasm::kAstI64 &&
2773 ElementSizeLog2Of(memtype.representation()) < 3) { 2889 ElementSizeLog2Of(memtype.representation()) < 3) {
2774 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. 2890 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes.
2775 if (memtype.IsSigned()) { 2891 if (memtype.IsSigned()) {
2776 // sign extend 2892 // sign extend
2777 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); 2893 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load);
2778 } else { 2894 } else {
2779 // zero extend 2895 // zero extend
2780 load = 2896 load =
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2881 uint32_t offset, uint32_t alignment, Node* val, 2997 uint32_t offset, uint32_t alignment, Node* val,
2882 wasm::WasmCodePosition position) { 2998 wasm::WasmCodePosition position) {
2883 Node* store; 2999 Node* store;
2884 3000
2885 // WASM semantics throw on OOB. Introduce explicit bounds check. 3001 // WASM semantics throw on OOB. Introduce explicit bounds check.
2886 BoundsCheckMem(memtype, index, offset, position); 3002 BoundsCheckMem(memtype, index, offset, position);
2887 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 3003 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
2888 bool aligned = static_cast<int>(alignment) >= 3004 bool aligned = static_cast<int>(alignment) >=
2889 ElementSizeLog2Of(memtype.representation()); 3005 ElementSizeLog2Of(memtype.representation());
2890 3006
3007 #if defined(V8_TARGET_BIG_ENDIAN)
3008 // TODO(mips-team) Implement byte swap turbofan operator
3009 // and use it if available for better performance
3010 val = BuildChangeEndianness(val, memtype);
3011 #endif
3012
2891 if (aligned || 3013 if (aligned ||
2892 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) { 3014 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) {
2893 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 3015 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
2894 store = 3016 store =
2895 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), 3017 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset),
2896 index, val, *effect_, *control_); 3018 index, val, *effect_, *control_);
2897 *effect_ = store; 3019 *effect_ = store;
2898 } else { 3020 } else {
2899 store = BuildUnalignedStore(memtype, index, offset, alignment, val); 3021 store = BuildUnalignedStore(memtype, index, offset, alignment, val);
2900 } 3022 }
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
3305 function_->code_start_offset), 3427 function_->code_start_offset),
3306 compile_ms); 3428 compile_ms);
3307 } 3429 }
3308 3430
3309 return code; 3431 return code;
3310 } 3432 }
3311 3433
3312 } // namespace compiler 3434 } // namespace compiler
3313 } // namespace internal 3435 } // namespace internal
3314 } // namespace v8 3436 } // namespace v8
OLDNEW
« 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