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

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: Use ByteReverse in simulator Created 4 years, 5 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(memtype)) {
1057 i += 8, shiftCount -= 16) { 1057 switch (valueSizeInBytes) {
1058 Node* shiftLower; 1058 case 1:
1059 Node* shiftHigher; 1059 break;
1060 Node* lowerByte; 1060 case 2:
1061 Node* higherByte; 1061 result = graph()->NewNode(
1062 jsgraph()->machine()->Word16ReverseBytes().op(), value);
1063 break;
1064 case 4:
1065 result = graph()->NewNode(
1066 jsgraph()->machine()->Word32ReverseBytes().op(), value);
1067 break;
1068 case 8:
1069 result = graph()->NewNode(
1070 jsgraph()->machine()->Word64ReverseBytes().op(), value);
1071 break;
1072 default:
1073 UNREACHABLE();
1074 }
1075 } else {
1076 for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2;
1077 i += 8, shiftCount -= 16) {
1078 Node* shiftLower;
1079 Node* shiftHigher;
1080 Node* lowerByte;
1081 Node* higherByte;
1062 1082
1063 DCHECK(shiftCount > 0); 1083 DCHECK(shiftCount > 0);
1064 DCHECK((shiftCount + 8) % 16 == 0); 1084 DCHECK((shiftCount + 8) % 16 == 0);
1065 1085
1066 if (valueSizeInBits > 32) { 1086 if (valueSizeInBits > 32) {
1067 shiftLower = graph()->NewNode(shiftLeftOpcode, value, 1087 shiftLower = graph()->NewNode(shiftLeftOpcode, value,
1068 jsgraph()->Int64Constant(shiftCount)); 1088 jsgraph()->Int64Constant(shiftCount));
1069 shiftHigher = graph()->NewNode(shiftRightOpcode, value, 1089 shiftHigher = graph()->NewNode(shiftRightOpcode, value,
1070 jsgraph()->Int64Constant(shiftCount)); 1090 jsgraph()->Int64Constant(shiftCount));
1071 lowerByte = graph()->NewNode( 1091 lowerByte = graph()->NewNode(
1072 andOpcode, shiftLower, 1092 andOpcode, shiftLower,
1073 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) 1093 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF)
1074 << (valueSizeInBits - 8 - i))); 1094 << (valueSizeInBits - 8 - i)));
1075 higherByte = graph()->NewNode( 1095 higherByte = graph()->NewNode(
1076 andOpcode, shiftHigher, 1096 andOpcode, shiftHigher,
1077 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i)); 1097 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i));
1078 } else { 1098 } else {
1079 shiftLower = graph()->NewNode(shiftLeftOpcode, value, 1099 shiftLower = graph()->NewNode(shiftLeftOpcode, value,
1080 jsgraph()->Int32Constant(shiftCount)); 1100 jsgraph()->Int32Constant(shiftCount));
1081 shiftHigher = graph()->NewNode(shiftRightOpcode, value, 1101 shiftHigher = graph()->NewNode(shiftRightOpcode, value,
1082 jsgraph()->Int32Constant(shiftCount)); 1102 jsgraph()->Int32Constant(shiftCount));
1083 lowerByte = graph()->NewNode( 1103 lowerByte = graph()->NewNode(
1084 andOpcode, shiftLower, 1104 andOpcode, shiftLower,
1085 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) 1105 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF)
1086 << (valueSizeInBits - 8 - i))); 1106 << (valueSizeInBits - 8 - i)));
1087 higherByte = graph()->NewNode( 1107 higherByte = graph()->NewNode(
1088 andOpcode, shiftHigher, 1108 andOpcode, shiftHigher,
1089 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i)); 1109 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i));
1110 }
1111
1112 result = graph()->NewNode(orOpcode, result, lowerByte);
1113 result = graph()->NewNode(orOpcode, result, higherByte);
1090 } 1114 }
1091
1092 result = graph()->NewNode(orOpcode, result, lowerByte);
1093 result = graph()->NewNode(orOpcode, result, higherByte);
1094 } 1115 }
1095 1116
1096 if (isFloat) { 1117 if (isFloat) {
1097 switch (memtype.representation()) { 1118 switch (memtype.representation()) {
1098 case MachineRepresentation::kFloat64: 1119 case MachineRepresentation::kFloat64:
1099 result = graph()->NewNode(m->BitcastInt64ToFloat64(), result); 1120 result = graph()->NewNode(m->BitcastInt64ToFloat64(), result);
1100 break; 1121 break;
1101 case MachineRepresentation::kFloat32: 1122 case MachineRepresentation::kFloat32:
1102 result = graph()->NewNode(m->BitcastInt32ToFloat32(), result); 1123 result = graph()->NewNode(m->BitcastInt32ToFloat32(), result);
1103 break; 1124 break;
1104 default: 1125 default:
1105 UNREACHABLE(); 1126 UNREACHABLE();
1106 break; 1127 break;
1107 } 1128 }
1108 } 1129 }
1109 1130
1110 // We need to sign extend the value 1131 // We need to sign extend the value
1111 if (memtype.IsSigned()) { 1132 if (memtype.IsSigned()) {
1112 DCHECK(!isFloat); 1133 DCHECK(!isFloat);
1113 if (valueSizeInBits < 32) { 1134 if (valueSizeInBits < 32) {
1114 Node* shiftBitCount; 1135 Node* shiftBitCount;
1115 // Perform sign extension using following trick 1136 // Perform sign extension using following trick
1116 // result = (x << machine_width - type_width) >> (machine_width - 1137 // result = (x << machine_width - type_width) >> (machine_width -
1117 // type_width) 1138 // type_width)
1118 if (wasmtype == wasm::kAstI64) { 1139 if (wasmtype == wasm::kAstI64) {
1119 shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits); 1140 shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits);
1120 result = graph()->NewNode( 1141 result = graph()->NewNode(
1121 m->Word64Sar(), 1142 m->Word64Sar(),
1122 graph()->NewNode(m->Word64Shl(), result, shiftBitCount), 1143 graph()->NewNode(
1144 m->Word64Shl(),
1145 graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(),
1146 result),
1147 shiftBitCount),
1123 shiftBitCount); 1148 shiftBitCount);
1124 } else if (wasmtype == wasm::kAstI32) { 1149 } else if (wasmtype == wasm::kAstI32) {
1125 shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits); 1150 shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits);
1126 result = graph()->NewNode( 1151 result = graph()->NewNode(
1127 m->Word32Sar(), 1152 m->Word32Sar(),
1128 graph()->NewNode(m->Word32Shl(), result, shiftBitCount), 1153 graph()->NewNode(m->Word32Shl(), result, shiftBitCount),
1129 shiftBitCount); 1154 shiftBitCount);
1130 } 1155 }
1131 } 1156 }
1132 } 1157 }
(...skipping 1942 matching lines...) Expand 10 before | Expand all | Expand 10 after
3075 3100
3076 if (aligned || 3101 if (aligned ||
3077 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) { 3102 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) {
3078 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), 3103 load = graph()->NewNode(jsgraph()->machine()->Load(memtype),
3079 MemBuffer(offset), index, *effect_, *control_); 3104 MemBuffer(offset), index, *effect_, *control_);
3080 *effect_ = load; 3105 *effect_ = load;
3081 } else { 3106 } else {
3082 load = BuildUnalignedLoad(type, memtype, index, offset, alignment); 3107 load = BuildUnalignedLoad(type, memtype, index, offset, alignment);
3083 } 3108 }
3084 #if defined(V8_TARGET_BIG_ENDIAN) 3109 #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); 3110 load = BuildChangeEndianness(load, memtype, type);
3088 #endif 3111 #endif
3089 3112
3090 if (type == wasm::kAstI64 && 3113 if (type == wasm::kAstI64 &&
3091 ElementSizeLog2Of(memtype.representation()) < 3) { 3114 ElementSizeLog2Of(memtype.representation()) < 3) {
3092 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. 3115 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes.
3093 if (memtype.IsSigned()) { 3116 if (memtype.IsSigned()) {
3094 // sign extend 3117 // sign extend
3095 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); 3118 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load);
3096 } else { 3119 } else {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
3196 } 3219 }
3197 3220
3198 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, 3221 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index,
3199 uint32_t offset, uint32_t alignment, Node* val, 3222 uint32_t offset, uint32_t alignment, Node* val,
3200 wasm::WasmCodePosition position) { 3223 wasm::WasmCodePosition position) {
3201 Node* store; 3224 Node* store;
3202 3225
3203 // WASM semantics throw on OOB. Introduce explicit bounds check. 3226 // WASM semantics throw on OOB. Introduce explicit bounds check.
3204 BoundsCheckMem(memtype, index, offset, position); 3227 BoundsCheckMem(memtype, index, offset, position);
3205 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 3228 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
3229
3206 bool aligned = static_cast<int>(alignment) >= 3230 bool aligned = static_cast<int>(alignment) >=
3207 ElementSizeLog2Of(memtype.representation()); 3231 ElementSizeLog2Of(memtype.representation());
3208 3232
3209 #if defined(V8_TARGET_BIG_ENDIAN) 3233 #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); 3234 val = BuildChangeEndianness(val, memtype);
3213 #endif 3235 #endif
3214 3236
3215 if (aligned || 3237 if (aligned ||
3216 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) { 3238 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) {
3217 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); 3239 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
3218 store = 3240 store =
3219 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), 3241 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset),
3220 index, val, *effect_, *control_); 3242 index, val, *effect_, *control_);
3221 *effect_ = store; 3243 *effect_ = store;
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
3661 function_->code_start_offset), 3683 function_->code_start_offset),
3662 compile_ms); 3684 compile_ms);
3663 } 3685 }
3664 3686
3665 return code; 3687 return code;
3666 } 3688 }
3667 3689
3668 } // namespace compiler 3690 } // namespace compiler
3669 } // namespace internal 3691 } // namespace internal
3670 } // namespace v8 3692 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698