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

Side by Side Diff: src/compiler/wasm-compiler.cc

Issue 2045943002: [compiler] [wasm] Introduce Word32/64ReverseBytes as TF Optional Opcode (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: implement machops tests Created 4 years, 4 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 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 return node; 1046 return node;
1047 break; 1047 break;
1048 default: 1048 default:
1049 UNREACHABLE(); 1049 UNREACHABLE();
1050 break; 1050 break;
1051 } 1051 }
1052 1052
1053 int i; 1053 int i;
1054 uint32_t shiftCount; 1054 uint32_t shiftCount;
1055 1055
1056 for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2; 1056 if (jsgraph()->machine()->ReverseBytesSupported(
1057 i += 8, shiftCount -= 16) { 1057 valueSizeInBytes < 4 ? 4 : valueSizeInBytes)) {
1058 Node* shiftLower; 1058 switch (valueSizeInBytes) {
1059 Node* shiftHigher; 1059 case 1:
1060 Node* lowerByte; 1060 break;
1061 Node* higherByte; 1061 case 2:
1062 result =
1063 graph()->NewNode(m->Word32ReverseBytes().op(),
ahaas 2016/07/28 14:12:59 Why do you sometimes use jsgraph()->machine()->...
john.yan 2016/07/28 18:03:50 Acknowledged.
1064 graph()->NewNode(shiftLeftOpcode, value,
1065 jsgraph()->Int32Constant(16)));
1066 break;
1067 case 4:
1068 result = graph()->NewNode(
1069 jsgraph()->machine()->Word32ReverseBytes().op(), value);
1070 break;
1071 case 8:
1072 result = graph()->NewNode(
1073 jsgraph()->machine()->Word64ReverseBytes().op(), value);
1074 break;
1075 default:
1076 UNREACHABLE();
1077 }
1078 } else {
1079 for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2;
1080 i += 8, shiftCount -= 16) {
1081 Node* shiftLower;
1082 Node* shiftHigher;
1083 Node* lowerByte;
1084 Node* higherByte;
1062 1085
1063 DCHECK(shiftCount > 0); 1086 DCHECK(shiftCount > 0);
1064 DCHECK((shiftCount + 8) % 16 == 0); 1087 DCHECK((shiftCount + 8) % 16 == 0);
1065 1088
1066 if (valueSizeInBits > 32) { 1089 if (valueSizeInBits > 32) {
1067 shiftLower = graph()->NewNode(shiftLeftOpcode, value, 1090 shiftLower = graph()->NewNode(shiftLeftOpcode, value,
1068 jsgraph()->Int64Constant(shiftCount)); 1091 jsgraph()->Int64Constant(shiftCount));
1069 shiftHigher = graph()->NewNode(shiftRightOpcode, value, 1092 shiftHigher = graph()->NewNode(shiftRightOpcode, value,
1070 jsgraph()->Int64Constant(shiftCount)); 1093 jsgraph()->Int64Constant(shiftCount));
1071 lowerByte = graph()->NewNode( 1094 lowerByte = graph()->NewNode(
1072 andOpcode, shiftLower, 1095 andOpcode, shiftLower,
1073 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) 1096 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF)
1074 << (valueSizeInBits - 8 - i))); 1097 << (valueSizeInBits - 8 - i)));
1075 higherByte = graph()->NewNode( 1098 higherByte = graph()->NewNode(
1076 andOpcode, shiftHigher, 1099 andOpcode, shiftHigher,
1077 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i)); 1100 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i));
1078 } else { 1101 } else {
1079 shiftLower = graph()->NewNode(shiftLeftOpcode, value, 1102 shiftLower = graph()->NewNode(shiftLeftOpcode, value,
1080 jsgraph()->Int32Constant(shiftCount)); 1103 jsgraph()->Int32Constant(shiftCount));
1081 shiftHigher = graph()->NewNode(shiftRightOpcode, value, 1104 shiftHigher = graph()->NewNode(shiftRightOpcode, value,
1082 jsgraph()->Int32Constant(shiftCount)); 1105 jsgraph()->Int32Constant(shiftCount));
1083 lowerByte = graph()->NewNode( 1106 lowerByte = graph()->NewNode(
1084 andOpcode, shiftLower, 1107 andOpcode, shiftLower,
1085 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) 1108 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF)
1086 << (valueSizeInBits - 8 - i))); 1109 << (valueSizeInBits - 8 - i)));
1087 higherByte = graph()->NewNode( 1110 higherByte = graph()->NewNode(
1088 andOpcode, shiftHigher, 1111 andOpcode, shiftHigher,
1089 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i)); 1112 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i));
1113 }
1114
1115 result = graph()->NewNode(orOpcode, result, lowerByte);
1116 result = graph()->NewNode(orOpcode, result, higherByte);
1090 } 1117 }
1091
1092 result = graph()->NewNode(orOpcode, result, lowerByte);
1093 result = graph()->NewNode(orOpcode, result, higherByte);
1094 } 1118 }
1095 1119
1096 if (isFloat) { 1120 if (isFloat) {
1097 switch (memtype.representation()) { 1121 switch (memtype.representation()) {
1098 case MachineRepresentation::kFloat64: 1122 case MachineRepresentation::kFloat64:
1099 result = graph()->NewNode(m->BitcastInt64ToFloat64(), result); 1123 result = graph()->NewNode(m->BitcastInt64ToFloat64(), result);
1100 break; 1124 break;
1101 case MachineRepresentation::kFloat32: 1125 case MachineRepresentation::kFloat32:
1102 result = graph()->NewNode(m->BitcastInt32ToFloat32(), result); 1126 result = graph()->NewNode(m->BitcastInt32ToFloat32(), result);
1103 break; 1127 break;
1104 default: 1128 default:
1105 UNREACHABLE(); 1129 UNREACHABLE();
1106 break; 1130 break;
1107 } 1131 }
1108 } 1132 }
1109 1133
1110 // We need to sign extend the value 1134 // We need to sign extend the value
1111 if (memtype.IsSigned()) { 1135 if (memtype.IsSigned()) {
1112 DCHECK(!isFloat); 1136 DCHECK(!isFloat);
1113 if (valueSizeInBits < 32) { 1137 if (valueSizeInBits < 32) {
1114 Node* shiftBitCount; 1138 Node* shiftBitCount;
1115 // Perform sign extension using following trick 1139 // Perform sign extension using following trick
1116 // result = (x << machine_width - type_width) >> (machine_width - 1140 // result = (x << machine_width - type_width) >> (machine_width -
1117 // type_width) 1141 // type_width)
1118 if (wasmtype == wasm::kAstI64) { 1142 if (wasmtype == wasm::kAstI64) {
1119 shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits); 1143 shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits);
1120 result = graph()->NewNode( 1144 result = graph()->NewNode(
1121 m->Word64Sar(), 1145 m->Word64Sar(),
1122 graph()->NewNode(m->Word64Shl(), result, shiftBitCount), 1146 graph()->NewNode(
1147 m->Word64Shl(),
1148 graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(),
1149 result),
1150 shiftBitCount),
1123 shiftBitCount); 1151 shiftBitCount);
1124 } else if (wasmtype == wasm::kAstI32) { 1152 } else if (wasmtype == wasm::kAstI32) {
1125 shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits); 1153 shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits);
1126 result = graph()->NewNode( 1154 result = graph()->NewNode(
1127 m->Word32Sar(), 1155 m->Word32Sar(),
1128 graph()->NewNode(m->Word32Shl(), result, shiftBitCount), 1156 graph()->NewNode(m->Word32Shl(), result, shiftBitCount),
1129 shiftBitCount); 1157 shiftBitCount);
1130 } 1158 }
1131 } 1159 }
1132 } 1160 }
(...skipping 1942 matching lines...) Expand 10 before | Expand all | Expand 10 after
3075 3103
3076 if (aligned || 3104 if (aligned ||
3077 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) { 3105 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) {
3078 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), 3106 load = graph()->NewNode(jsgraph()->machine()->Load(memtype),
3079 MemBuffer(offset), index, *effect_, *control_); 3107 MemBuffer(offset), index, *effect_, *control_);
3080 *effect_ = load; 3108 *effect_ = load;
3081 } else { 3109 } else {
3082 load = BuildUnalignedLoad(type, memtype, index, offset, alignment); 3110 load = BuildUnalignedLoad(type, memtype, index, offset, alignment);
3083 } 3111 }
3084 #if defined(V8_TARGET_BIG_ENDIAN) 3112 #if defined(V8_TARGET_BIG_ENDIAN)
3085 // TODO(john.yan) Implement byte swap turbofan operator
3086 // and use it if available for better performance
3087 load = BuildChangeEndianness(load, memtype, type); 3113 load = BuildChangeEndianness(load, memtype, type);
3088 #endif 3114 #endif
3089 3115
3090 if (type == wasm::kAstI64 && 3116 if (type == wasm::kAstI64 &&
3091 ElementSizeLog2Of(memtype.representation()) < 3) { 3117 ElementSizeLog2Of(memtype.representation()) < 3) {
3092 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. 3118 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes.
3093 if (memtype.IsSigned()) { 3119 if (memtype.IsSigned()) {
3094 // sign extend 3120 // sign extend
3095 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); 3121 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load);
3096 } else { 3122 } else {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
3196 } 3222 }
3197 3223
3198 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, 3224 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index,
3199 uint32_t offset, uint32_t alignment, Node* val, 3225 uint32_t offset, uint32_t alignment, Node* val,
3200 wasm::WasmCodePosition position) { 3226 wasm::WasmCodePosition position) {
3201 Node* store; 3227 Node* store;
3202 3228
3203 // WASM semantics throw on OOB. Introduce explicit bounds check. 3229 // WASM semantics throw on OOB. Introduce explicit bounds check.
3204 BoundsCheckMem(memtype, index, offset, position); 3230 BoundsCheckMem(memtype, index, offset, position);
3205 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 3231 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
3232
3206 bool aligned = static_cast<int>(alignment) >= 3233 bool aligned = static_cast<int>(alignment) >=
3207 ElementSizeLog2Of(memtype.representation()); 3234 ElementSizeLog2Of(memtype.representation());
3208 3235
3209 #if defined(V8_TARGET_BIG_ENDIAN) 3236 #if defined(V8_TARGET_BIG_ENDIAN)
3210 // TODO(john.yan) Implement byte swap turbofan operator
3211 // and use it if available for better performance
3212 val = BuildChangeEndianness(val, memtype); 3237 val = BuildChangeEndianness(val, memtype);
3213 #endif 3238 #endif
3214 3239
3215 if (aligned || 3240 if (aligned ||
3216 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) { 3241 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) {
3217 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 3242 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
3218 store = 3243 store =
3219 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), 3244 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset),
3220 index, val, *effect_, *control_); 3245 index, val, *effect_, *control_);
3221 *effect_ = store; 3246 *effect_ = store;
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
3661 function_->code_start_offset), 3686 function_->code_start_offset),
3662 compile_ms); 3687 compile_ms);
3663 } 3688 }
3664 3689
3665 return code; 3690 return code;
3666 } 3691 }
3667 3692
3668 } // namespace compiler 3693 } // namespace compiler
3669 } // namespace internal 3694 } // namespace internal
3670 } // namespace v8 3695 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698