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

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: Small fixes. Rebase to master 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
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/utils.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 const Operator* shiftLeftOpcode;
1000 const Operator* shiftRightOpcode;
1001 const Operator* andOpcode;
1002 const Operator* orOpcode;
1003 MachineOperatorBuilder* m = jsgraph()->machine();
1004 int valueSizeInBytes = 1 << ElementSizeLog2Of(memtype.representation());
1005 int valueSizeInBits = 8 * valueSizeInBytes;
1006 bool isFloat = false;
1007
1008 switch (memtype.representation()) {
1009 case MachineRepresentation::kFloat64:
1010 value = graph()->NewNode(m->BitcastFloat64ToInt64(), node);
1011 isFloat = true;
1012 case MachineRepresentation::kWord64:
1013 shiftLeftOpcode = m->Word64Shl();
1014 shiftRightOpcode = m->Word64Shr();
1015 andOpcode = m->Word64And();
1016 orOpcode = m->Word64Or();
1017 result = jsgraph()->Int64Constant(0);
1018 break;
1019 case MachineRepresentation::kFloat32:
1020 value = graph()->NewNode(m->BitcastFloat32ToInt32(), node);
1021 isFloat = true;
1022 case MachineRepresentation::kWord32:
1023 case MachineRepresentation::kWord16:
1024 shiftLeftOpcode = m->Word32Shl();
1025 shiftRightOpcode = m->Word32Shr();
1026 andOpcode = m->Word32And();
1027 orOpcode = m->Word32Or();
1028 result = jsgraph()->Int32Constant(0);
1029 break;
1030 case MachineRepresentation::kWord8:
1031 // No need to change endianness for byte size, return original node
1032 return node;
1033 break;
1034 default:
1035 UNREACHABLE();
1036 break;
1037 }
1038
1039 int i;
1040 uint32_t shiftCount;
1041
1042 for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2;
1043 i += 8, shiftCount -= 16) {
1044 DCHECK(shiftCount > 0);
1045 DCHECK((shiftCount + 8) % 16 == 0);
1046
1047 Node* shiftLower = graph()->NewNode(shiftLeftOpcode, value,
1048 jsgraph()->Int32Constant(shiftCount));
1049 Node* shiftHigher = graph()->NewNode(shiftRightOpcode, value,
1050 jsgraph()->Int32Constant(shiftCount));
1051
1052 Node* lowerByte;
1053 Node* higherByte;
1054
1055 if (valueSizeInBits > 32) {
1056 lowerByte = graph()->NewNode(
1057 andOpcode, shiftLower,
1058 jsgraph()->Int64Constant(0xFFl << (valueSizeInBits - 8 - i)));
1059 higherByte = graph()->NewNode(andOpcode, shiftHigher,
1060 jsgraph()->Int64Constant(0xFFl << i));
1061 } else {
1062 lowerByte = graph()->NewNode(
1063 andOpcode, shiftLower,
1064 jsgraph()->Int32Constant(0xFF << (valueSizeInBits - 8 - i)));
1065 higherByte = graph()->NewNode(andOpcode, shiftHigher,
1066 jsgraph()->Int32Constant(0xFF << i));
1067 }
1068
1069 result = graph()->NewNode(orOpcode, result, lowerByte);
1070 result = graph()->NewNode(orOpcode, result, higherByte);
1071 }
1072
1073 if (isFloat) {
1074 switch (memtype.representation()) {
1075 case MachineRepresentation::kFloat64:
1076 result = graph()->NewNode(m->BitcastInt64ToFloat64(), result);
1077 break;
1078 case MachineRepresentation::kFloat32:
1079 result = graph()->NewNode(m->BitcastInt32ToFloat32(), result);
1080 break;
1081 default:
1082 UNREACHABLE();
1083 break;
1084 }
1085 }
1086
1087 // We need to sign extend the value
1088 if (memtype.IsSigned()) {
1089 DCHECK(!isFloat);
1090 if (valueSizeInBits < 32) {
1091 Node* shiftBitCount;
1092 // Perform sign extension using following trick
1093 // result = (x << machine_width - type_width) >> (machine_width -
1094 // type_width)
1095 if (wasmtype == wasm::kAstI64) {
1096 shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits);
1097 result = graph()->NewNode(
1098 m->Word64Sar(),
1099 graph()->NewNode(m->Word64Shl(), result, shiftBitCount),
1100 shiftBitCount);
1101 } else if (wasmtype == wasm::kAstI32) {
1102 shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits);
1103 result = graph()->NewNode(
1104 m->Word32Sar(),
1105 graph()->NewNode(m->Word32Shl(), result, shiftBitCount),
1106 shiftBitCount);
1107 }
1108 }
1109 }
1110
1111 return result;
1112 }
1113
995 Node* WasmGraphBuilder::BuildF32Neg(Node* input) { 1114 Node* WasmGraphBuilder::BuildF32Neg(Node* input) {
996 Node* result = 1115 Node* result =
997 Unop(wasm::kExprF32ReinterpretI32, 1116 Unop(wasm::kExprF32ReinterpretI32,
998 Binop(wasm::kExprI32Xor, Unop(wasm::kExprI32ReinterpretF32, input), 1117 Binop(wasm::kExprI32Xor, Unop(wasm::kExprI32ReinterpretF32, input),
999 jsgraph()->Int32Constant(0x80000000))); 1118 jsgraph()->Int32Constant(0x80000000)));
1000 1119
1001 return result; 1120 return result;
1002 } 1121 }
1003 1122
1004 Node* WasmGraphBuilder::BuildF64Neg(Node* input) { 1123 Node* WasmGraphBuilder::BuildF64Neg(Node* input) {
(...skipping 1737 matching lines...) Expand 10 before | Expand all | Expand 10 after
2742 ElementSizeLog2Of(memtype.representation()); 2861 ElementSizeLog2Of(memtype.representation());
2743 2862
2744 if (aligned || 2863 if (aligned ||
2745 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) { 2864 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) {
2746 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), 2865 load = graph()->NewNode(jsgraph()->machine()->Load(memtype),
2747 MemBuffer(offset), index, *effect_, *control_); 2866 MemBuffer(offset), index, *effect_, *control_);
2748 *effect_ = load; 2867 *effect_ = load;
2749 } else { 2868 } else {
2750 load = BuildUnalignedLoad(type, memtype, index, offset, alignment); 2869 load = BuildUnalignedLoad(type, memtype, index, offset, alignment);
2751 } 2870 }
2871 #if defined(V8_TARGET_BIG_ENDIAN)
2872 // TODO(john.yan) Implement byte swap turbofan operator
2873 // and use it if available for better performance
2874 load = BuildChangeEndianness(load, memtype, type);
2875 #endif
2752 2876
2753 if (type == wasm::kAstI64 && 2877 if (type == wasm::kAstI64 &&
2754 ElementSizeLog2Of(memtype.representation()) < 3) { 2878 ElementSizeLog2Of(memtype.representation()) < 3) {
2755 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. 2879 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes.
2756 if (memtype.IsSigned()) { 2880 if (memtype.IsSigned()) {
2757 // sign extend 2881 // sign extend
2758 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); 2882 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load);
2759 } else { 2883 } else {
2760 // zero extend 2884 // zero extend
2761 load = 2885 load =
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2862 uint32_t offset, uint32_t alignment, Node* val, 2986 uint32_t offset, uint32_t alignment, Node* val,
2863 wasm::WasmCodePosition position) { 2987 wasm::WasmCodePosition position) {
2864 Node* store; 2988 Node* store;
2865 2989
2866 // WASM semantics throw on OOB. Introduce explicit bounds check. 2990 // WASM semantics throw on OOB. Introduce explicit bounds check.
2867 BoundsCheckMem(memtype, index, offset, position); 2991 BoundsCheckMem(memtype, index, offset, position);
2868 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 2992 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
2869 bool aligned = static_cast<int>(alignment) >= 2993 bool aligned = static_cast<int>(alignment) >=
2870 ElementSizeLog2Of(memtype.representation()); 2994 ElementSizeLog2Of(memtype.representation());
2871 2995
2996 #if defined(V8_TARGET_BIG_ENDIAN)
2997 // TODO(john.yan) Implement byte swap turbofan operator
2998 // and use it if available for better performance
2999 val = BuildChangeEndianness(val, memtype);
3000 #endif
3001
2872 if (aligned || 3002 if (aligned ||
2873 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) { 3003 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) {
2874 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 3004 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
2875 store = 3005 store =
2876 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), 3006 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset),
2877 index, val, *effect_, *control_); 3007 index, val, *effect_, *control_);
2878 *effect_ = store; 3008 *effect_ = store;
2879 } else { 3009 } else {
2880 store = BuildUnalignedStore(memtype, index, offset, alignment, val); 3010 store = BuildUnalignedStore(memtype, index, offset, alignment, val);
2881 } 3011 }
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
3287 function_->code_start_offset), 3417 function_->code_start_offset),
3288 compile_ms); 3418 compile_ms);
3289 } 3419 }
3290 3420
3291 return code; 3421 return code;
3292 } 3422 }
3293 3423
3294 } // namespace compiler 3424 } // namespace compiler
3295 } // namespace internal 3425 } // namespace internal
3296 } // namespace v8 3426 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698