1// Copyright 2014 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/compiler/machine-operator.h" 6 7#include "src/base/lazy-instance.h" 8#include "src/compiler/opcodes.h" 9#include "src/compiler/operator.h" 10 11namespace v8 { 12namespace internal { 13namespace compiler { 14 15bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) { 16 return lhs.representation() == rhs.representation() && 17 lhs.write_barrier_kind() == rhs.write_barrier_kind(); 18} 19 20 21bool operator!=(StoreRepresentation lhs, StoreRepresentation rhs) { 22 return !(lhs == rhs); 23} 24 25 26size_t hash_value(StoreRepresentation rep) { 27 return base::hash_combine(rep.representation(), rep.write_barrier_kind()); 28} 29 30 31std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) { 32 return os << rep.representation() << ", " << rep.write_barrier_kind(); 33} 34 35bool operator==(AtomicStoreParameters lhs, AtomicStoreParameters rhs) { 36 return lhs.store_representation() == rhs.store_representation() && 37 lhs.order() == rhs.order(); 38} 39 40bool operator!=(AtomicStoreParameters lhs, AtomicStoreParameters rhs) { 41 return !(lhs == rhs); 42} 43 44size_t hash_value(AtomicStoreParameters params) { 45 return base::hash_combine(hash_value(params.store_representation()), 46 params.order()); 47} 48 49std::ostream& operator<<(std::ostream& os, AtomicStoreParameters params) { 50 return os << params.store_representation() << ", " << params.order(); 51} 52 53bool operator==(AtomicLoadParameters lhs, AtomicLoadParameters rhs) { 54 return lhs.representation() == rhs.representation() && 55 lhs.order() == rhs.order(); 56} 57 58bool operator!=(AtomicLoadParameters lhs, AtomicLoadParameters rhs) { 59 return !(lhs == rhs); 60} 61 62size_t hash_value(AtomicLoadParameters params) { 63 return base::hash_combine(params.representation(), params.order()); 64} 65 66std::ostream& operator<<(std::ostream& os, AtomicLoadParameters params) { 67 return os << params.representation() << ", " << params.order(); 68} 69 70size_t hash_value(MemoryAccessKind kind) { return static_cast<size_t>(kind); } 71 72std::ostream& operator<<(std::ostream& os, MemoryAccessKind kind) { 73 switch (kind) { 74 case MemoryAccessKind::kNormal: 75 return os << "kNormal"; 76 case MemoryAccessKind::kUnaligned: 77 return os << "kUnaligned"; 78 case MemoryAccessKind::kProtected: 79 return os << "kProtected"; 80 } 81 UNREACHABLE(); 82} 83 84size_t hash_value(LoadTransformation rep) { return static_cast<size_t>(rep); } 85 86std::ostream& operator<<(std::ostream& os, LoadTransformation rep) { 87 switch (rep) { 88 case LoadTransformation::kS128Load8Splat: 89 return os << "kS128Load8Splat"; 90 case LoadTransformation::kS128Load16Splat: 91 return os << "kS128Load16Splat"; 92 case LoadTransformation::kS128Load32Splat: 93 return os << "kS128Load32Splat"; 94 case LoadTransformation::kS128Load64Splat: 95 return os << "kS128Load64Splat"; 96 case LoadTransformation::kS128Load8x8S: 97 return os << "kS128Load8x8S"; 98 case LoadTransformation::kS128Load8x8U: 99 return os << "kS128Load8x8U"; 100 case LoadTransformation::kS128Load16x4S: 101 return os << "kS128Load16x4S"; 102 case LoadTransformation::kS128Load16x4U: 103 return os << "kS128Load16x4U"; 104 case LoadTransformation::kS128Load32x2S: 105 return os << "kS128Load32x2S"; 106 case LoadTransformation::kS128Load32x2U: 107 return os << "kS128Load32x2U"; 108 case LoadTransformation::kS128Load32Zero: 109 return os << "kS128Load32Zero"; 110 case LoadTransformation::kS128Load64Zero: 111 return os << "kS128Load64Zero"; 112 } 113 UNREACHABLE(); 114} 115 116size_t hash_value(LoadTransformParameters params) { 117 return base::hash_combine(params.kind, params.transformation); 118} 119 120std::ostream& operator<<(std::ostream& os, LoadTransformParameters params) { 121 return os << "(" << params.kind << " " << params.transformation << ")"; 122} 123 124LoadTransformParameters const& LoadTransformParametersOf(Operator const* op) { 125 DCHECK_EQ(IrOpcode::kLoadTransform, op->opcode()); 126 return OpParameter<LoadTransformParameters>(op); 127} 128 129bool operator==(LoadTransformParameters lhs, LoadTransformParameters rhs) { 130 return lhs.transformation == rhs.transformation && lhs.kind == rhs.kind; 131} 132 133bool operator!=(LoadTransformParameters lhs, LoadTransformParameters rhs) { 134 return !(lhs == rhs); 135} 136 137size_t hash_value(LoadLaneParameters params) { 138 return base::hash_combine(params.kind, params.rep, params.laneidx); 139} 140 141std::ostream& operator<<(std::ostream& os, LoadLaneParameters params) { 142 return os << "(" << params.kind << " " << params.rep << " " << params.laneidx 143 << ")"; 144} 145 146LoadLaneParameters const& LoadLaneParametersOf(Operator const* op) { 147 DCHECK_EQ(IrOpcode::kLoadLane, op->opcode()); 148 return OpParameter<LoadLaneParameters>(op); 149} 150 151bool operator==(LoadLaneParameters lhs, LoadLaneParameters rhs) { 152 return lhs.kind == rhs.kind && lhs.rep == rhs.rep && 153 lhs.laneidx == rhs.laneidx; 154} 155 156LoadRepresentation LoadRepresentationOf(Operator const* op) { 157 DCHECK(IrOpcode::kLoad == op->opcode() || 158 IrOpcode::kProtectedLoad == op->opcode() || 159 IrOpcode::kUnalignedLoad == op->opcode() || 160 IrOpcode::kLoadImmutable == op->opcode()); 161 return OpParameter<LoadRepresentation>(op); 162} 163 164AtomicLoadParameters AtomicLoadParametersOf(Operator const* op) { 165 DCHECK(IrOpcode::kWord32AtomicLoad == op->opcode() || 166 IrOpcode::kWord64AtomicLoad == op->opcode()); 167 return OpParameter<AtomicLoadParameters>(op); 168} 169 170StoreRepresentation const& StoreRepresentationOf(Operator const* op) { 171 DCHECK(IrOpcode::kStore == op->opcode() || 172 IrOpcode::kProtectedStore == op->opcode()); 173 return OpParameter<StoreRepresentation>(op); 174} 175 176AtomicStoreParameters const& AtomicStoreParametersOf(Operator const* op) { 177 DCHECK(IrOpcode::kWord32AtomicStore == op->opcode() || 178 IrOpcode::kWord64AtomicStore == op->opcode()); 179 return OpParameter<AtomicStoreParameters>(op); 180} 181 182UnalignedStoreRepresentation const& UnalignedStoreRepresentationOf( 183 Operator const* op) { 184 DCHECK_EQ(IrOpcode::kUnalignedStore, op->opcode()); 185 return OpParameter<UnalignedStoreRepresentation>(op); 186} 187 188size_t hash_value(StoreLaneParameters params) { 189 return base::hash_combine(params.kind, params.rep, params.laneidx); 190} 191 192std::ostream& operator<<(std::ostream& os, StoreLaneParameters params) { 193 return os << "(" << params.kind << " " << params.rep << " " 194 << static_cast<unsigned int>(params.laneidx) << ")"; 195} 196 197StoreLaneParameters const& StoreLaneParametersOf(Operator const* op) { 198 DCHECK_EQ(IrOpcode::kStoreLane, op->opcode()); 199 return OpParameter<StoreLaneParameters>(op); 200} 201 202bool operator==(StoreLaneParameters lhs, StoreLaneParameters rhs) { 203 return lhs.kind == rhs.kind && lhs.rep == rhs.rep && 204 lhs.laneidx == rhs.laneidx; 205} 206 207bool operator==(StackSlotRepresentation lhs, StackSlotRepresentation rhs) { 208 return lhs.size() == rhs.size() && lhs.alignment() == rhs.alignment(); 209} 210 211bool operator!=(StackSlotRepresentation lhs, StackSlotRepresentation rhs) { 212 return !(lhs == rhs); 213} 214 215size_t hash_value(StackSlotRepresentation rep) { 216 return base::hash_combine(rep.size(), rep.alignment()); 217} 218 219std::ostream& operator<<(std::ostream& os, StackSlotRepresentation rep) { 220 return os << rep.size() << ", " << rep.alignment(); 221} 222 223StackSlotRepresentation const& StackSlotRepresentationOf(Operator const* op) { 224 DCHECK_EQ(IrOpcode::kStackSlot, op->opcode()); 225 return OpParameter<StackSlotRepresentation>(op); 226} 227 228MachineType AtomicOpType(Operator const* op) { 229 return OpParameter<MachineType>(op); 230} 231 232size_t hash_value(ShiftKind kind) { return static_cast<size_t>(kind); } 233V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, ShiftKind kind) { 234 switch (kind) { 235 case ShiftKind::kNormal: 236 return os << "Normal"; 237 case ShiftKind::kShiftOutZeros: 238 return os << "ShiftOutZeros"; 239 } 240} 241 242ShiftKind ShiftKindOf(Operator const* op) { 243 DCHECK(IrOpcode::kWord32Sar == op->opcode() || 244 IrOpcode::kWord64Sar == op->opcode()); 245 return OpParameter<ShiftKind>(op); 246} 247 248size_t hash_value(TruncateKind kind) { return static_cast<size_t>(kind); } 249 250std::ostream& operator<<(std::ostream& os, TruncateKind kind) { 251 switch (kind) { 252 case TruncateKind::kArchitectureDefault: 253 return os << "kArchitectureDefault"; 254 case TruncateKind::kSetOverflowToMin: 255 return os << "kSetOverflowToMin"; 256 } 257} 258 259// The format is: 260// V(Name, properties, value_input_count, control_input_count, output_count) 261#define PURE_BINARY_OP_LIST_32(V) \ 262 V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 263 V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 264 V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 265 V(Word32Shl, Operator::kNoProperties, 2, 0, 1) \ 266 V(Word32Shr, Operator::kNoProperties, 2, 0, 1) \ 267 V(Word32Ror, Operator::kNoProperties, 2, 0, 1) \ 268 V(Word32Equal, Operator::kCommutative, 2, 0, 1) \ 269 V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 270 V(Int32Sub, Operator::kNoProperties, 2, 0, 1) \ 271 V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 272 V(Int32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 273 V(Int32Div, Operator::kNoProperties, 2, 1, 1) \ 274 V(Int32Mod, Operator::kNoProperties, 2, 1, 1) \ 275 V(Int32LessThan, Operator::kNoProperties, 2, 0, 1) \ 276 V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \ 277 V(Uint32Div, Operator::kNoProperties, 2, 1, 1) \ 278 V(Uint32LessThan, Operator::kNoProperties, 2, 0, 1) \ 279 V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \ 280 V(Uint32Mod, Operator::kNoProperties, 2, 1, 1) \ 281 V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) 282 283// The format is: 284// V(Name, properties, value_input_count, control_input_count, output_count) 285#define PURE_BINARY_OP_LIST_64(V) \ 286 V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 287 V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 288 V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 289 V(Word64Shl, Operator::kNoProperties, 2, 0, 1) \ 290 V(Word64Shr, Operator::kNoProperties, 2, 0, 1) \ 291 V(Word64Ror, Operator::kNoProperties, 2, 0, 1) \ 292 V(Word64RorLowerable, Operator::kNoProperties, 2, 1, 1) \ 293 V(Word64Equal, Operator::kCommutative, 2, 0, 1) \ 294 V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 295 V(Int64Sub, Operator::kNoProperties, 2, 0, 1) \ 296 V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 297 V(Int64Div, Operator::kNoProperties, 2, 1, 1) \ 298 V(Int64Mod, Operator::kNoProperties, 2, 1, 1) \ 299 V(Int64LessThan, Operator::kNoProperties, 2, 0, 1) \ 300 V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \ 301 V(Uint64Div, Operator::kNoProperties, 2, 1, 1) \ 302 V(Uint64Mod, Operator::kNoProperties, 2, 1, 1) \ 303 V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1) \ 304 V(Uint64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) 305 306// The format is: 307// V(Name, properties, value_input_count, control_input_count, output_count) 308#define MACHINE_PURE_OP_LIST(V) \ 309 PURE_BINARY_OP_LIST_32(V) \ 310 PURE_BINARY_OP_LIST_64(V) \ 311 V(Word32Clz, Operator::kNoProperties, 1, 0, 1) \ 312 V(Word64Clz, Operator::kNoProperties, 1, 0, 1) \ 313 V(Word64ClzLowerable, Operator::kNoProperties, 1, 1, 1) \ 314 V(Word32ReverseBytes, Operator::kNoProperties, 1, 0, 1) \ 315 V(Word64ReverseBytes, Operator::kNoProperties, 1, 0, 1) \ 316 V(Simd128ReverseBytes, Operator::kNoProperties, 1, 0, 1) \ 317 V(BitcastTaggedToWordForTagAndSmiBits, Operator::kNoProperties, 1, 0, 1) \ 318 V(BitcastWordToTaggedSigned, Operator::kNoProperties, 1, 0, 1) \ 319 V(TruncateFloat64ToWord32, Operator::kNoProperties, 1, 0, 1) \ 320 V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1) \ 321 V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \ 322 V(ChangeFloat64ToInt64, Operator::kNoProperties, 1, 0, 1) \ 323 V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \ 324 V(ChangeFloat64ToUint64, Operator::kNoProperties, 1, 0, 1) \ 325 V(TruncateFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \ 326 V(TryTruncateFloat32ToInt64, Operator::kNoProperties, 1, 0, 2) \ 327 V(TryTruncateFloat64ToInt64, Operator::kNoProperties, 1, 0, 2) \ 328 V(TryTruncateFloat32ToUint64, Operator::kNoProperties, 1, 0, 2) \ 329 V(TryTruncateFloat64ToUint64, Operator::kNoProperties, 1, 0, 2) \ 330 V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1) \ 331 V(ChangeInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \ 332 V(Float64SilenceNaN, Operator::kNoProperties, 1, 0, 1) \ 333 V(RoundFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \ 334 V(RoundInt32ToFloat32, Operator::kNoProperties, 1, 0, 1) \ 335 V(RoundInt64ToFloat32, Operator::kNoProperties, 1, 0, 1) \ 336 V(RoundInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \ 337 V(RoundUint32ToFloat32, Operator::kNoProperties, 1, 0, 1) \ 338 V(RoundUint64ToFloat32, Operator::kNoProperties, 1, 0, 1) \ 339 V(RoundUint64ToFloat64, Operator::kNoProperties, 1, 0, 1) \ 340 V(BitcastWord32ToWord64, Operator::kNoProperties, 1, 0, 1) \ 341 V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \ 342 V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \ 343 V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1) \ 344 V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \ 345 V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \ 346 V(BitcastFloat32ToInt32, Operator::kNoProperties, 1, 0, 1) \ 347 V(BitcastFloat64ToInt64, Operator::kNoProperties, 1, 0, 1) \ 348 V(BitcastInt32ToFloat32, Operator::kNoProperties, 1, 0, 1) \ 349 V(BitcastInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \ 350 V(SignExtendWord8ToInt32, Operator::kNoProperties, 1, 0, 1) \ 351 V(SignExtendWord16ToInt32, Operator::kNoProperties, 1, 0, 1) \ 352 V(SignExtendWord8ToInt64, Operator::kNoProperties, 1, 0, 1) \ 353 V(SignExtendWord16ToInt64, Operator::kNoProperties, 1, 0, 1) \ 354 V(SignExtendWord32ToInt64, Operator::kNoProperties, 1, 0, 1) \ 355 V(Float32Abs, Operator::kNoProperties, 1, 0, 1) \ 356 V(Float32Add, Operator::kCommutative, 2, 0, 1) \ 357 V(Float32Sub, Operator::kNoProperties, 2, 0, 1) \ 358 V(Float32Mul, Operator::kCommutative, 2, 0, 1) \ 359 V(Float32Div, Operator::kNoProperties, 2, 0, 1) \ 360 V(Float32Neg, Operator::kNoProperties, 1, 0, 1) \ 361 V(Float32Sqrt, Operator::kNoProperties, 1, 0, 1) \ 362 V(Float32Max, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 363 V(Float32Min, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 364 V(Float64Abs, Operator::kNoProperties, 1, 0, 1) \ 365 V(Float64Acos, Operator::kNoProperties, 1, 0, 1) \ 366 V(Float64Acosh, Operator::kNoProperties, 1, 0, 1) \ 367 V(Float64Asin, Operator::kNoProperties, 1, 0, 1) \ 368 V(Float64Asinh, Operator::kNoProperties, 1, 0, 1) \ 369 V(Float64Atan, Operator::kNoProperties, 1, 0, 1) \ 370 V(Float64Atan2, Operator::kNoProperties, 2, 0, 1) \ 371 V(Float64Atanh, Operator::kNoProperties, 1, 0, 1) \ 372 V(Float64Cbrt, Operator::kNoProperties, 1, 0, 1) \ 373 V(Float64Cos, Operator::kNoProperties, 1, 0, 1) \ 374 V(Float64Cosh, Operator::kNoProperties, 1, 0, 1) \ 375 V(Float64Exp, Operator::kNoProperties, 1, 0, 1) \ 376 V(Float64Expm1, Operator::kNoProperties, 1, 0, 1) \ 377 V(Float64Log, Operator::kNoProperties, 1, 0, 1) \ 378 V(Float64Log1p, Operator::kNoProperties, 1, 0, 1) \ 379 V(Float64Log2, Operator::kNoProperties, 1, 0, 1) \ 380 V(Float64Log10, Operator::kNoProperties, 1, 0, 1) \ 381 V(Float64Max, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 382 V(Float64Min, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 383 V(Float64Neg, Operator::kNoProperties, 1, 0, 1) \ 384 V(Float64Add, Operator::kCommutative, 2, 0, 1) \ 385 V(Float64Sub, Operator::kNoProperties, 2, 0, 1) \ 386 V(Float64Mul, Operator::kCommutative, 2, 0, 1) \ 387 V(Float64Div, Operator::kNoProperties, 2, 0, 1) \ 388 V(Float64Mod, Operator::kNoProperties, 2, 0, 1) \ 389 V(Float64Pow, Operator::kNoProperties, 2, 0, 1) \ 390 V(Float64Sin, Operator::kNoProperties, 1, 0, 1) \ 391 V(Float64Sinh, Operator::kNoProperties, 1, 0, 1) \ 392 V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1) \ 393 V(Float64Tan, Operator::kNoProperties, 1, 0, 1) \ 394 V(Float64Tanh, Operator::kNoProperties, 1, 0, 1) \ 395 V(Float32Equal, Operator::kCommutative, 2, 0, 1) \ 396 V(Float32LessThan, Operator::kNoProperties, 2, 0, 1) \ 397 V(Float32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \ 398 V(Float64Equal, Operator::kCommutative, 2, 0, 1) \ 399 V(Float64LessThan, Operator::kNoProperties, 2, 0, 1) \ 400 V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \ 401 V(Float64ExtractLowWord32, Operator::kNoProperties, 1, 0, 1) \ 402 V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1) \ 403 V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1) \ 404 V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1) \ 405 V(LoadStackCheckOffset, Operator::kNoProperties, 0, 0, 1) \ 406 V(LoadFramePointer, Operator::kNoProperties, 0, 0, 1) \ 407 V(LoadParentFramePointer, Operator::kNoProperties, 0, 0, 1) \ 408 V(Int32PairAdd, Operator::kNoProperties, 4, 0, 2) \ 409 V(Int32PairSub, Operator::kNoProperties, 4, 0, 2) \ 410 V(Int32PairMul, Operator::kNoProperties, 4, 0, 2) \ 411 V(Word32PairShl, Operator::kNoProperties, 3, 0, 2) \ 412 V(Word32PairShr, Operator::kNoProperties, 3, 0, 2) \ 413 V(Word32PairSar, Operator::kNoProperties, 3, 0, 2) \ 414 V(F64x2Splat, Operator::kNoProperties, 1, 0, 1) \ 415 V(F64x2Abs, Operator::kNoProperties, 1, 0, 1) \ 416 V(F64x2Neg, Operator::kNoProperties, 1, 0, 1) \ 417 V(F64x2Sqrt, Operator::kNoProperties, 1, 0, 1) \ 418 V(F64x2Add, Operator::kCommutative, 2, 0, 1) \ 419 V(F64x2Sub, Operator::kNoProperties, 2, 0, 1) \ 420 V(F64x2Mul, Operator::kCommutative, 2, 0, 1) \ 421 V(F64x2Div, Operator::kNoProperties, 2, 0, 1) \ 422 V(F64x2Min, Operator::kCommutative, 2, 0, 1) \ 423 V(F64x2Max, Operator::kCommutative, 2, 0, 1) \ 424 V(F64x2Eq, Operator::kCommutative, 2, 0, 1) \ 425 V(F64x2Ne, Operator::kCommutative, 2, 0, 1) \ 426 V(F64x2Lt, Operator::kNoProperties, 2, 0, 1) \ 427 V(F64x2Le, Operator::kNoProperties, 2, 0, 1) \ 428 V(F64x2Qfma, Operator::kNoProperties, 3, 0, 1) \ 429 V(F64x2Qfms, Operator::kNoProperties, 3, 0, 1) \ 430 V(F64x2Pmin, Operator::kNoProperties, 2, 0, 1) \ 431 V(F64x2Pmax, Operator::kNoProperties, 2, 0, 1) \ 432 V(F64x2Ceil, Operator::kNoProperties, 1, 0, 1) \ 433 V(F64x2Floor, Operator::kNoProperties, 1, 0, 1) \ 434 V(F64x2Trunc, Operator::kNoProperties, 1, 0, 1) \ 435 V(F64x2NearestInt, Operator::kNoProperties, 1, 0, 1) \ 436 V(F64x2ConvertLowI32x4S, Operator::kNoProperties, 1, 0, 1) \ 437 V(F64x2ConvertLowI32x4U, Operator::kNoProperties, 1, 0, 1) \ 438 V(F64x2PromoteLowF32x4, Operator::kNoProperties, 1, 0, 1) \ 439 V(F32x4Splat, Operator::kNoProperties, 1, 0, 1) \ 440 V(F32x4SConvertI32x4, Operator::kNoProperties, 1, 0, 1) \ 441 V(F32x4UConvertI32x4, Operator::kNoProperties, 1, 0, 1) \ 442 V(F32x4Abs, Operator::kNoProperties, 1, 0, 1) \ 443 V(F32x4Neg, Operator::kNoProperties, 1, 0, 1) \ 444 V(F32x4Sqrt, Operator::kNoProperties, 1, 0, 1) \ 445 V(F32x4RecipApprox, Operator::kNoProperties, 1, 0, 1) \ 446 V(F32x4RecipSqrtApprox, Operator::kNoProperties, 1, 0, 1) \ 447 V(F32x4Add, Operator::kCommutative, 2, 0, 1) \ 448 V(F32x4Sub, Operator::kNoProperties, 2, 0, 1) \ 449 V(F32x4Mul, Operator::kCommutative, 2, 0, 1) \ 450 V(F32x4Div, Operator::kNoProperties, 2, 0, 1) \ 451 V(F32x4Min, Operator::kCommutative, 2, 0, 1) \ 452 V(F32x4Max, Operator::kCommutative, 2, 0, 1) \ 453 V(F32x4Eq, Operator::kCommutative, 2, 0, 1) \ 454 V(F32x4Ne, Operator::kCommutative, 2, 0, 1) \ 455 V(F32x4Lt, Operator::kNoProperties, 2, 0, 1) \ 456 V(F32x4Le, Operator::kNoProperties, 2, 0, 1) \ 457 V(F32x4Qfma, Operator::kNoProperties, 3, 0, 1) \ 458 V(F32x4Qfms, Operator::kNoProperties, 3, 0, 1) \ 459 V(F32x4Pmin, Operator::kNoProperties, 2, 0, 1) \ 460 V(F32x4Pmax, Operator::kNoProperties, 2, 0, 1) \ 461 V(F32x4Ceil, Operator::kNoProperties, 1, 0, 1) \ 462 V(F32x4Floor, Operator::kNoProperties, 1, 0, 1) \ 463 V(F32x4Trunc, Operator::kNoProperties, 1, 0, 1) \ 464 V(F32x4NearestInt, Operator::kNoProperties, 1, 0, 1) \ 465 V(F32x4DemoteF64x2Zero, Operator::kNoProperties, 1, 0, 1) \ 466 V(I64x2Splat, Operator::kNoProperties, 1, 0, 1) \ 467 V(I64x2SplatI32Pair, Operator::kNoProperties, 2, 0, 1) \ 468 V(I64x2Abs, Operator::kNoProperties, 1, 0, 1) \ 469 V(I64x2Neg, Operator::kNoProperties, 1, 0, 1) \ 470 V(I64x2SConvertI32x4Low, Operator::kNoProperties, 1, 0, 1) \ 471 V(I64x2SConvertI32x4High, Operator::kNoProperties, 1, 0, 1) \ 472 V(I64x2UConvertI32x4Low, Operator::kNoProperties, 1, 0, 1) \ 473 V(I64x2UConvertI32x4High, Operator::kNoProperties, 1, 0, 1) \ 474 V(I64x2BitMask, Operator::kNoProperties, 1, 0, 1) \ 475 V(I64x2Shl, Operator::kNoProperties, 2, 0, 1) \ 476 V(I64x2ShrS, Operator::kNoProperties, 2, 0, 1) \ 477 V(I64x2Add, Operator::kCommutative, 2, 0, 1) \ 478 V(I64x2Sub, Operator::kNoProperties, 2, 0, 1) \ 479 V(I64x2Mul, Operator::kCommutative, 2, 0, 1) \ 480 V(I64x2Eq, Operator::kCommutative, 2, 0, 1) \ 481 V(I64x2Ne, Operator::kCommutative, 2, 0, 1) \ 482 V(I64x2GtS, Operator::kNoProperties, 2, 0, 1) \ 483 V(I64x2GeS, Operator::kNoProperties, 2, 0, 1) \ 484 V(I64x2ShrU, Operator::kNoProperties, 2, 0, 1) \ 485 V(I64x2ExtMulLowI32x4S, Operator::kCommutative, 2, 0, 1) \ 486 V(I64x2ExtMulHighI32x4S, Operator::kCommutative, 2, 0, 1) \ 487 V(I64x2ExtMulLowI32x4U, Operator::kCommutative, 2, 0, 1) \ 488 V(I64x2ExtMulHighI32x4U, Operator::kCommutative, 2, 0, 1) \ 489 V(I32x4Splat, Operator::kNoProperties, 1, 0, 1) \ 490 V(I32x4SConvertF32x4, Operator::kNoProperties, 1, 0, 1) \ 491 V(I32x4SConvertI16x8Low, Operator::kNoProperties, 1, 0, 1) \ 492 V(I32x4SConvertI16x8High, Operator::kNoProperties, 1, 0, 1) \ 493 V(I32x4Neg, Operator::kNoProperties, 1, 0, 1) \ 494 V(I32x4Shl, Operator::kNoProperties, 2, 0, 1) \ 495 V(I32x4ShrS, Operator::kNoProperties, 2, 0, 1) \ 496 V(I32x4Add, Operator::kCommutative, 2, 0, 1) \ 497 V(I32x4Sub, Operator::kNoProperties, 2, 0, 1) \ 498 V(I32x4Mul, Operator::kCommutative, 2, 0, 1) \ 499 V(I32x4MinS, Operator::kCommutative, 2, 0, 1) \ 500 V(I32x4MaxS, Operator::kCommutative, 2, 0, 1) \ 501 V(I32x4Eq, Operator::kCommutative, 2, 0, 1) \ 502 V(I32x4Ne, Operator::kCommutative, 2, 0, 1) \ 503 V(I32x4GtS, Operator::kNoProperties, 2, 0, 1) \ 504 V(I32x4GeS, Operator::kNoProperties, 2, 0, 1) \ 505 V(I32x4UConvertF32x4, Operator::kNoProperties, 1, 0, 1) \ 506 V(I32x4UConvertI16x8Low, Operator::kNoProperties, 1, 0, 1) \ 507 V(I32x4UConvertI16x8High, Operator::kNoProperties, 1, 0, 1) \ 508 V(I32x4ShrU, Operator::kNoProperties, 2, 0, 1) \ 509 V(I32x4MinU, Operator::kCommutative, 2, 0, 1) \ 510 V(I32x4MaxU, Operator::kCommutative, 2, 0, 1) \ 511 V(I32x4GtU, Operator::kNoProperties, 2, 0, 1) \ 512 V(I32x4GeU, Operator::kNoProperties, 2, 0, 1) \ 513 V(I32x4Abs, Operator::kNoProperties, 1, 0, 1) \ 514 V(I32x4BitMask, Operator::kNoProperties, 1, 0, 1) \ 515 V(I32x4DotI16x8S, Operator::kCommutative, 2, 0, 1) \ 516 V(I32x4ExtMulLowI16x8S, Operator::kCommutative, 2, 0, 1) \ 517 V(I32x4ExtMulHighI16x8S, Operator::kCommutative, 2, 0, 1) \ 518 V(I32x4ExtMulLowI16x8U, Operator::kCommutative, 2, 0, 1) \ 519 V(I32x4ExtMulHighI16x8U, Operator::kCommutative, 2, 0, 1) \ 520 V(I32x4ExtAddPairwiseI16x8S, Operator::kNoProperties, 1, 0, 1) \ 521 V(I32x4ExtAddPairwiseI16x8U, Operator::kNoProperties, 1, 0, 1) \ 522 V(I32x4TruncSatF64x2SZero, Operator::kNoProperties, 1, 0, 1) \ 523 V(I32x4TruncSatF64x2UZero, Operator::kNoProperties, 1, 0, 1) \ 524 V(I16x8Splat, Operator::kNoProperties, 1, 0, 1) \ 525 V(I16x8SConvertI8x16Low, Operator::kNoProperties, 1, 0, 1) \ 526 V(I16x8SConvertI8x16High, Operator::kNoProperties, 1, 0, 1) \ 527 V(I16x8Neg, Operator::kNoProperties, 1, 0, 1) \ 528 V(I16x8Shl, Operator::kNoProperties, 2, 0, 1) \ 529 V(I16x8ShrS, Operator::kNoProperties, 2, 0, 1) \ 530 V(I16x8SConvertI32x4, Operator::kNoProperties, 2, 0, 1) \ 531 V(I16x8Add, Operator::kCommutative, 2, 0, 1) \ 532 V(I16x8AddSatS, Operator::kCommutative, 2, 0, 1) \ 533 V(I16x8Sub, Operator::kNoProperties, 2, 0, 1) \ 534 V(I16x8SubSatS, Operator::kNoProperties, 2, 0, 1) \ 535 V(I16x8Mul, Operator::kCommutative, 2, 0, 1) \ 536 V(I16x8MinS, Operator::kCommutative, 2, 0, 1) \ 537 V(I16x8MaxS, Operator::kCommutative, 2, 0, 1) \ 538 V(I16x8Eq, Operator::kCommutative, 2, 0, 1) \ 539 V(I16x8Ne, Operator::kCommutative, 2, 0, 1) \ 540 V(I16x8GtS, Operator::kNoProperties, 2, 0, 1) \ 541 V(I16x8GeS, Operator::kNoProperties, 2, 0, 1) \ 542 V(I16x8UConvertI8x16Low, Operator::kNoProperties, 1, 0, 1) \ 543 V(I16x8UConvertI8x16High, Operator::kNoProperties, 1, 0, 1) \ 544 V(I16x8ShrU, Operator::kNoProperties, 2, 0, 1) \ 545 V(I16x8UConvertI32x4, Operator::kNoProperties, 2, 0, 1) \ 546 V(I16x8AddSatU, Operator::kCommutative, 2, 0, 1) \ 547 V(I16x8SubSatU, Operator::kNoProperties, 2, 0, 1) \ 548 V(I16x8MinU, Operator::kCommutative, 2, 0, 1) \ 549 V(I16x8MaxU, Operator::kCommutative, 2, 0, 1) \ 550 V(I16x8GtU, Operator::kNoProperties, 2, 0, 1) \ 551 V(I16x8GeU, Operator::kNoProperties, 2, 0, 1) \ 552 V(I16x8RoundingAverageU, Operator::kCommutative, 2, 0, 1) \ 553 V(I16x8Q15MulRSatS, Operator::kCommutative, 2, 0, 1) \ 554 V(I16x8Abs, Operator::kNoProperties, 1, 0, 1) \ 555 V(I16x8BitMask, Operator::kNoProperties, 1, 0, 1) \ 556 V(I16x8ExtMulLowI8x16S, Operator::kCommutative, 2, 0, 1) \ 557 V(I16x8ExtMulHighI8x16S, Operator::kCommutative, 2, 0, 1) \ 558 V(I16x8ExtMulLowI8x16U, Operator::kCommutative, 2, 0, 1) \ 559 V(I16x8ExtMulHighI8x16U, Operator::kCommutative, 2, 0, 1) \ 560 V(I16x8ExtAddPairwiseI8x16S, Operator::kNoProperties, 1, 0, 1) \ 561 V(I16x8ExtAddPairwiseI8x16U, Operator::kNoProperties, 1, 0, 1) \ 562 V(I8x16Splat, Operator::kNoProperties, 1, 0, 1) \ 563 V(I8x16Neg, Operator::kNoProperties, 1, 0, 1) \ 564 V(I8x16Shl, Operator::kNoProperties, 2, 0, 1) \ 565 V(I8x16ShrS, Operator::kNoProperties, 2, 0, 1) \ 566 V(I8x16SConvertI16x8, Operator::kNoProperties, 2, 0, 1) \ 567 V(I8x16Add, Operator::kCommutative, 2, 0, 1) \ 568 V(I8x16AddSatS, Operator::kCommutative, 2, 0, 1) \ 569 V(I8x16Sub, Operator::kNoProperties, 2, 0, 1) \ 570 V(I8x16SubSatS, Operator::kNoProperties, 2, 0, 1) \ 571 V(I8x16MinS, Operator::kCommutative, 2, 0, 1) \ 572 V(I8x16MaxS, Operator::kCommutative, 2, 0, 1) \ 573 V(I8x16Eq, Operator::kCommutative, 2, 0, 1) \ 574 V(I8x16Ne, Operator::kCommutative, 2, 0, 1) \ 575 V(I8x16GtS, Operator::kNoProperties, 2, 0, 1) \ 576 V(I8x16GeS, Operator::kNoProperties, 2, 0, 1) \ 577 V(I8x16ShrU, Operator::kNoProperties, 2, 0, 1) \ 578 V(I8x16UConvertI16x8, Operator::kNoProperties, 2, 0, 1) \ 579 V(I8x16AddSatU, Operator::kCommutative, 2, 0, 1) \ 580 V(I8x16SubSatU, Operator::kNoProperties, 2, 0, 1) \ 581 V(I8x16MinU, Operator::kCommutative, 2, 0, 1) \ 582 V(I8x16MaxU, Operator::kCommutative, 2, 0, 1) \ 583 V(I8x16GtU, Operator::kNoProperties, 2, 0, 1) \ 584 V(I8x16GeU, Operator::kNoProperties, 2, 0, 1) \ 585 V(I8x16RoundingAverageU, Operator::kCommutative, 2, 0, 1) \ 586 V(I8x16Popcnt, Operator::kNoProperties, 1, 0, 1) \ 587 V(I8x16Abs, Operator::kNoProperties, 1, 0, 1) \ 588 V(I8x16BitMask, Operator::kNoProperties, 1, 0, 1) \ 589 V(S128Zero, Operator::kNoProperties, 0, 0, 1) \ 590 V(S128And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 591 V(S128Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 592 V(S128Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \ 593 V(S128Not, Operator::kNoProperties, 1, 0, 1) \ 594 V(S128Select, Operator::kNoProperties, 3, 0, 1) \ 595 V(S128AndNot, Operator::kNoProperties, 2, 0, 1) \ 596 V(V128AnyTrue, Operator::kNoProperties, 1, 0, 1) \ 597 V(I64x2AllTrue, Operator::kNoProperties, 1, 0, 1) \ 598 V(I32x4AllTrue, Operator::kNoProperties, 1, 0, 1) \ 599 V(I16x8AllTrue, Operator::kNoProperties, 1, 0, 1) \ 600 V(I8x16AllTrue, Operator::kNoProperties, 1, 0, 1) \ 601 V(I8x16RelaxedLaneSelect, Operator::kNoProperties, 3, 0, 1) \ 602 V(I16x8RelaxedLaneSelect, Operator::kNoProperties, 3, 0, 1) \ 603 V(I32x4RelaxedLaneSelect, Operator::kNoProperties, 3, 0, 1) \ 604 V(I64x2RelaxedLaneSelect, Operator::kNoProperties, 3, 0, 1) \ 605 V(F32x4RelaxedMin, Operator::kNoProperties, 2, 0, 1) \ 606 V(F32x4RelaxedMax, Operator::kNoProperties, 2, 0, 1) \ 607 V(F64x2RelaxedMin, Operator::kNoProperties, 2, 0, 1) \ 608 V(F64x2RelaxedMax, Operator::kNoProperties, 2, 0, 1) \ 609 V(I32x4RelaxedTruncF32x4S, Operator::kNoProperties, 1, 0, 1) \ 610 V(I32x4RelaxedTruncF32x4U, Operator::kNoProperties, 1, 0, 1) \ 611 V(I32x4RelaxedTruncF64x2SZero, Operator::kNoProperties, 1, 0, 1) \ 612 V(I32x4RelaxedTruncF64x2UZero, Operator::kNoProperties, 1, 0, 1) 613 614// The format is: 615// V(Name, properties, value_input_count, control_input_count, output_count) 616#define PURE_OPTIONAL_OP_LIST(V) \ 617 V(Word32Ctz, Operator::kNoProperties, 1, 0, 1) \ 618 V(Word64Ctz, Operator::kNoProperties, 1, 0, 1) \ 619 V(Word64CtzLowerable, Operator::kNoProperties, 1, 1, 1) \ 620 V(Word32Rol, Operator::kNoProperties, 2, 0, 1) \ 621 V(Word64Rol, Operator::kNoProperties, 2, 0, 1) \ 622 V(Word64RolLowerable, Operator::kNoProperties, 2, 1, 1) \ 623 V(Word32ReverseBits, Operator::kNoProperties, 1, 0, 1) \ 624 V(Word64ReverseBits, Operator::kNoProperties, 1, 0, 1) \ 625 V(Int32AbsWithOverflow, Operator::kNoProperties, 1, 0, 2) \ 626 V(Int64AbsWithOverflow, Operator::kNoProperties, 1, 0, 2) \ 627 V(Word32Popcnt, Operator::kNoProperties, 1, 0, 1) \ 628 V(Word64Popcnt, Operator::kNoProperties, 1, 0, 1) \ 629 V(Float32RoundDown, Operator::kNoProperties, 1, 0, 1) \ 630 V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1) \ 631 V(Float32RoundUp, Operator::kNoProperties, 1, 0, 1) \ 632 V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1) \ 633 V(Float32RoundTruncate, Operator::kNoProperties, 1, 0, 1) \ 634 V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \ 635 V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \ 636 V(Float32RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \ 637 V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \ 638 V(Word32Select, Operator::kNoProperties, 3, 0, 1) \ 639 V(Word64Select, Operator::kNoProperties, 3, 0, 1) \ 640 V(Float32Select, Operator::kNoProperties, 3, 0, 1) \ 641 V(Float64Select, Operator::kNoProperties, 3, 0, 1) 642 643// The format is: 644// V(Name, properties, value_input_count, control_input_count, output_count) 645#define OVERFLOW_OP_LIST(V) \ 646 V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \ 647 V(Int32SubWithOverflow, Operator::kNoProperties) \ 648 V(Int32MulWithOverflow, Operator::kAssociative | Operator::kCommutative) \ 649 V(Int64AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \ 650 V(Int64SubWithOverflow, Operator::kNoProperties) 651 652#define MACHINE_TYPE_LIST(V) \ 653 V(Float32) \ 654 V(Float64) \ 655 V(Simd128) \ 656 V(Int8) \ 657 V(Uint8) \ 658 V(Int16) \ 659 V(Uint16) \ 660 V(Int32) \ 661 V(Uint32) \ 662 V(Int64) \ 663 V(Uint64) \ 664 V(Pointer) \ 665 V(TaggedSigned) \ 666 V(TaggedPointer) \ 667 V(MapInHeader) \ 668 V(AnyTagged) \ 669 V(CompressedPointer) \ 670 V(SandboxedPointer) \ 671 V(AnyCompressed) 672 673#define MACHINE_REPRESENTATION_LIST(V) \ 674 V(kFloat32) \ 675 V(kFloat64) \ 676 V(kSimd128) \ 677 V(kWord8) \ 678 V(kWord16) \ 679 V(kWord32) \ 680 V(kWord64) \ 681 V(kMapWord) \ 682 V(kTaggedSigned) \ 683 V(kTaggedPointer) \ 684 V(kTagged) \ 685 V(kCompressedPointer) \ 686 V(kSandboxedPointer) \ 687 V(kCompressed) 688 689#define LOAD_TRANSFORM_LIST(V) \ 690 V(S128Load8Splat) \ 691 V(S128Load16Splat) \ 692 V(S128Load32Splat) \ 693 V(S128Load64Splat) \ 694 V(S128Load8x8S) \ 695 V(S128Load8x8U) \ 696 V(S128Load16x4S) \ 697 V(S128Load16x4U) \ 698 V(S128Load32x2S) \ 699 V(S128Load32x2U) \ 700 V(S128Load32Zero) \ 701 V(S128Load64Zero) 702 703#if TAGGED_SIZE_8_BYTES 704 705#define ATOMIC_TAGGED_TYPE_LIST(V) 706 707#define ATOMIC64_TAGGED_TYPE_LIST(V) \ 708 V(TaggedSigned) \ 709 V(TaggedPointer) \ 710 V(AnyTagged) \ 711 V(CompressedPointer) \ 712 V(AnyCompressed) 713 714#else 715 716#define ATOMIC_TAGGED_TYPE_LIST(V) \ 717 V(TaggedSigned) \ 718 V(TaggedPointer) \ 719 V(AnyTagged) \ 720 V(CompressedPointer) \ 721 V(AnyCompressed) 722 723#define ATOMIC64_TAGGED_TYPE_LIST(V) 724 725#endif // TAGGED_SIZE_8_BYTES 726 727#define ATOMIC_U32_TYPE_LIST(V) \ 728 V(Uint8) \ 729 V(Uint16) \ 730 V(Uint32) 731 732#define ATOMIC_TYPE_LIST(V) \ 733 ATOMIC_U32_TYPE_LIST(V) \ 734 V(Int8) \ 735 V(Int16) \ 736 V(Int32) 737 738#define ATOMIC_U64_TYPE_LIST(V) \ 739 ATOMIC_U32_TYPE_LIST(V) \ 740 V(Uint64) 741 742#if TAGGED_SIZE_8_BYTES 743 744#define ATOMIC_TAGGED_REPRESENTATION_LIST(V) 745 746#define ATOMIC64_TAGGED_REPRESENTATION_LIST(V) \ 747 V(kTaggedSigned) \ 748 V(kTaggedPointer) \ 749 V(kTagged) 750 751#else 752 753#define ATOMIC_TAGGED_REPRESENTATION_LIST(V) \ 754 V(kTaggedSigned) \ 755 V(kTaggedPointer) \ 756 V(kTagged) \ 757 V(kCompressedPointer) \ 758 V(kCompressed) 759 760#define ATOMIC64_TAGGED_REPRESENTATION_LIST(V) 761 762#endif // TAGGED_SIZE_8_BYTES 763 764#define ATOMIC_REPRESENTATION_LIST(V) \ 765 V(kWord8) \ 766 V(kWord16) \ 767 V(kWord32) 768 769#define ATOMIC64_REPRESENTATION_LIST(V) \ 770 ATOMIC_REPRESENTATION_LIST(V) \ 771 V(kWord64) 772 773#define ATOMIC_PAIR_BINOP_LIST(V) \ 774 V(Add) \ 775 V(Sub) \ 776 V(And) \ 777 V(Or) \ 778 V(Xor) \ 779 V(Exchange) 780 781#define SIMD_LANE_OP_LIST(V) \ 782 V(F64x2, 2) \ 783 V(F32x4, 4) \ 784 V(I64x2, 2) \ 785 V(I32x4, 4) \ 786 V(I16x8, 8) \ 787 V(I8x16, 16) 788 789#define SIMD_I64x2_LANES(V) V(0) V(1) 790 791#define SIMD_I32x4_LANES(V) SIMD_I64x2_LANES(V) V(2) V(3) 792 793#define SIMD_I16x8_LANES(V) SIMD_I32x4_LANES(V) V(4) V(5) V(6) V(7) 794 795#define SIMD_I8x16_LANES(V) \ 796 SIMD_I16x8_LANES(V) V(8) V(9) V(10) V(11) V(12) V(13) V(14) V(15) 797 798#define STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(V) \ 799 V(4, 0) V(8, 0) V(16, 0) V(4, 4) V(8, 8) V(16, 16) 800 801struct StackSlotOperator : public Operator1<StackSlotRepresentation> { 802 explicit StackSlotOperator(int size, int alignment) 803 : Operator1<StackSlotRepresentation>( 804 IrOpcode::kStackSlot, Operator::kNoDeopt | Operator::kNoThrow, 805 "StackSlot", 0, 0, 0, 1, 0, 0, 806 StackSlotRepresentation(size, alignment)) {} 807}; 808 809struct MachineOperatorGlobalCache { 810#define PURE(Name, properties, value_input_count, control_input_count, \ 811 output_count) \ 812 struct Name##Operator final : public Operator { \ 813 Name##Operator() \ 814 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ 815 value_input_count, 0, control_input_count, output_count, 0, \ 816 0) {} \ 817 }; \ 818 Name##Operator k##Name; 819 MACHINE_PURE_OP_LIST(PURE) 820 struct NormalWord32SarOperator final : public Operator1<ShiftKind> { 821 NormalWord32SarOperator() 822 : Operator1<ShiftKind>(IrOpcode::kWord32Sar, Operator::kPure, 823 "Word32Sar", 2, 0, 0, 1, 0, 0, 824 ShiftKind::kNormal) {} 825 }; 826 NormalWord32SarOperator kNormalWord32Sar; 827 struct ShiftOutZerosWord32SarOperator final : public Operator1<ShiftKind> { 828 ShiftOutZerosWord32SarOperator() 829 : Operator1<ShiftKind>(IrOpcode::kWord32Sar, Operator::kPure, 830 "Word32Sar", 2, 0, 0, 1, 0, 0, 831 ShiftKind::kShiftOutZeros) {} 832 }; 833 ShiftOutZerosWord32SarOperator kShiftOutZerosWord32Sar; 834 struct NormalWord64SarOperator final : public Operator1<ShiftKind> { 835 NormalWord64SarOperator() 836 : Operator1<ShiftKind>(IrOpcode::kWord64Sar, Operator::kPure, 837 "Word64Sar", 2, 0, 0, 1, 0, 0, 838 ShiftKind::kNormal) {} 839 }; 840 NormalWord64SarOperator kNormalWord64Sar; 841 struct ShiftOutZerosWord64SarOperator final : public Operator1<ShiftKind> { 842 ShiftOutZerosWord64SarOperator() 843 : Operator1<ShiftKind>(IrOpcode::kWord64Sar, Operator::kPure, 844 "Word64Sar", 2, 0, 0, 1, 0, 0, 845 ShiftKind::kShiftOutZeros) {} 846 }; 847 ShiftOutZerosWord64SarOperator kShiftOutZerosWord64Sar; 848 849 struct ArchitectureDefaultTruncateFloat32ToUint32Operator final 850 : public Operator1<TruncateKind> { 851 ArchitectureDefaultTruncateFloat32ToUint32Operator() 852 : Operator1<TruncateKind>(IrOpcode::kTruncateFloat32ToUint32, 853 Operator::kPure, "TruncateFloat32ToUint32", 1, 854 0, 0, 1, 0, 0, 855 TruncateKind::kArchitectureDefault) {} 856 }; 857 ArchitectureDefaultTruncateFloat32ToUint32Operator 858 kArchitectureDefaultTruncateFloat32ToUint32; 859 struct SetOverflowToMinTruncateFloat32ToUint32Operator final 860 : public Operator1<TruncateKind> { 861 SetOverflowToMinTruncateFloat32ToUint32Operator() 862 : Operator1<TruncateKind>(IrOpcode::kTruncateFloat32ToUint32, 863 Operator::kPure, "TruncateFloat32ToUint32", 1, 864 0, 0, 1, 0, 0, 865 TruncateKind::kSetOverflowToMin) {} 866 }; 867 SetOverflowToMinTruncateFloat32ToUint32Operator 868 kSetOverflowToMinTruncateFloat32ToUint32; 869 870 struct ArchitectureDefaultTruncateFloat32ToInt32Operator final 871 : public Operator1<TruncateKind> { 872 ArchitectureDefaultTruncateFloat32ToInt32Operator() 873 : Operator1<TruncateKind>(IrOpcode::kTruncateFloat32ToInt32, 874 Operator::kPure, "TruncateFloat32ToInt32", 1, 875 0, 0, 1, 0, 0, 876 TruncateKind::kArchitectureDefault) {} 877 }; 878 ArchitectureDefaultTruncateFloat32ToInt32Operator 879 kArchitectureDefaultTruncateFloat32ToInt32; 880 struct SetOverflowToMinTruncateFloat32ToInt32Operator final 881 : public Operator1<TruncateKind> { 882 SetOverflowToMinTruncateFloat32ToInt32Operator() 883 : Operator1<TruncateKind>(IrOpcode::kTruncateFloat32ToInt32, 884 Operator::kPure, "TruncateFloat32ToInt32", 1, 885 0, 0, 1, 0, 0, 886 TruncateKind::kSetOverflowToMin) {} 887 }; 888 SetOverflowToMinTruncateFloat32ToInt32Operator 889 kSetOverflowToMinTruncateFloat32ToInt32; 890 891 struct ArchitectureDefaultTruncateFloat64ToInt64Operator final 892 : public Operator1<TruncateKind> { 893 ArchitectureDefaultTruncateFloat64ToInt64Operator() 894 : Operator1(IrOpcode::kTruncateFloat64ToInt64, Operator::kPure, 895 "TruncateFloat64ToInt64", 1, 0, 0, 1, 0, 0, 896 TruncateKind::kArchitectureDefault) {} 897 }; 898 ArchitectureDefaultTruncateFloat64ToInt64Operator 899 kArchitectureDefaultTruncateFloat64ToInt64; 900 struct SetOverflowToMinTruncateFloat64ToInt64Operator final 901 : public Operator1<TruncateKind> { 902 SetOverflowToMinTruncateFloat64ToInt64Operator() 903 : Operator1(IrOpcode::kTruncateFloat64ToInt64, Operator::kPure, 904 "TruncateFloat64ToInt64", 1, 0, 0, 1, 0, 0, 905 TruncateKind::kSetOverflowToMin) {} 906 }; 907 SetOverflowToMinTruncateFloat64ToInt64Operator 908 kSetOverflowToMinTruncateFloat64ToInt64; 909 PURE_OPTIONAL_OP_LIST(PURE) 910#undef PURE 911 912#define OVERFLOW_OP(Name, properties) \ 913 struct Name##Operator final : public Operator { \ 914 Name##Operator() \ 915 : Operator(IrOpcode::k##Name, \ 916 Operator::kEliminatable | Operator::kNoRead | properties, \ 917 #Name, 2, 0, 1, 2, 0, 0) {} \ 918 }; \ 919 Name##Operator k##Name; 920 OVERFLOW_OP_LIST(OVERFLOW_OP) 921#undef OVERFLOW_OP 922 923#define LOAD(Type) \ 924 struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \ 925 Load##Type##Operator() \ 926 : Operator1<LoadRepresentation>(IrOpcode::kLoad, \ 927 Operator::kEliminatable, "Load", 2, 1, \ 928 1, 1, 1, 0, MachineType::Type()) {} \ 929 }; \ 930 struct UnalignedLoad##Type##Operator final \ 931 : public Operator1<LoadRepresentation> { \ 932 UnalignedLoad##Type##Operator() \ 933 : Operator1<LoadRepresentation>( \ 934 IrOpcode::kUnalignedLoad, Operator::kEliminatable, \ 935 "UnalignedLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \ 936 }; \ 937 struct ProtectedLoad##Type##Operator final \ 938 : public Operator1<LoadRepresentation> { \ 939 ProtectedLoad##Type##Operator() \ 940 : Operator1<LoadRepresentation>( \ 941 IrOpcode::kProtectedLoad, \ 942 Operator::kNoDeopt | Operator::kNoThrow, "ProtectedLoad", 2, 1, \ 943 1, 1, 1, 0, MachineType::Type()) {} \ 944 }; \ 945 struct LoadImmutable##Type##Operator final \ 946 : public Operator1<LoadRepresentation> { \ 947 LoadImmutable##Type##Operator() \ 948 : Operator1<LoadRepresentation>(IrOpcode::kLoadImmutable, \ 949 Operator::kPure, "LoadImmutable", 2, \ 950 0, 0, 1, 0, 0, MachineType::Type()) {} \ 951 }; \ 952 Load##Type##Operator kLoad##Type; \ 953 UnalignedLoad##Type##Operator kUnalignedLoad##Type; \ 954 ProtectedLoad##Type##Operator kProtectedLoad##Type; \ 955 LoadImmutable##Type##Operator kLoadImmutable##Type; 956 MACHINE_TYPE_LIST(LOAD) 957#undef LOAD 958 959#define LOAD_TRANSFORM_KIND(TYPE, KIND) \ 960 struct KIND##LoadTransform##TYPE##Operator final \ 961 : public Operator1<LoadTransformParameters> { \ 962 KIND##LoadTransform##TYPE##Operator() \ 963 : Operator1<LoadTransformParameters>( \ 964 IrOpcode::kLoadTransform, \ 965 MemoryAccessKind::k##KIND == MemoryAccessKind::kProtected \ 966 ? Operator::kNoDeopt | Operator::kNoThrow \ 967 : Operator::kEliminatable, \ 968 #KIND "LoadTransform", 2, 1, 1, 1, 1, 0, \ 969 LoadTransformParameters{MemoryAccessKind::k##KIND, \ 970 LoadTransformation::k##TYPE}) {} \ 971 }; \ 972 KIND##LoadTransform##TYPE##Operator k##KIND##LoadTransform##TYPE; 973 974#define LOAD_TRANSFORM(TYPE) \ 975 LOAD_TRANSFORM_KIND(TYPE, Normal) \ 976 LOAD_TRANSFORM_KIND(TYPE, Unaligned) \ 977 LOAD_TRANSFORM_KIND(TYPE, Protected) 978 979 LOAD_TRANSFORM_LIST(LOAD_TRANSFORM) 980#undef LOAD_TRANSFORM 981#undef LOAD_TRANSFORM_KIND 982 983#define STACKSLOT(Size, Alignment) \ 984 struct StackSlotOfSize##Size##OfAlignment##Alignment##Operator final \ 985 : public StackSlotOperator { \ 986 StackSlotOfSize##Size##OfAlignment##Alignment##Operator() \ 987 : StackSlotOperator(Size, Alignment) {} \ 988 }; \ 989 StackSlotOfSize##Size##OfAlignment##Alignment##Operator \ 990 kStackSlotOfSize##Size##OfAlignment##Alignment; 991 STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(STACKSLOT) 992#undef STACKSLOT 993 994#define STORE(Type) \ 995 struct Store##Type##Operator : public Operator1<StoreRepresentation> { \ 996 explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \ 997 : Operator1<StoreRepresentation>( \ 998 IrOpcode::kStore, \ 999 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \ 1000 "Store", 3, 1, 1, 0, 1, 0, \ 1001 StoreRepresentation(MachineRepresentation::Type, \ 1002 write_barrier_kind)) {} \ 1003 }; \ 1004 struct Store##Type##NoWriteBarrier##Operator final \ 1005 : public Store##Type##Operator { \ 1006 Store##Type##NoWriteBarrier##Operator() \ 1007 : Store##Type##Operator(kNoWriteBarrier) {} \ 1008 }; \ 1009 struct Store##Type##AssertNoWriteBarrier##Operator final \ 1010 : public Store##Type##Operator { \ 1011 Store##Type##AssertNoWriteBarrier##Operator() \ 1012 : Store##Type##Operator(kAssertNoWriteBarrier) {} \ 1013 }; \ 1014 struct Store##Type##MapWriteBarrier##Operator final \ 1015 : public Store##Type##Operator { \ 1016 Store##Type##MapWriteBarrier##Operator() \ 1017 : Store##Type##Operator(kMapWriteBarrier) {} \ 1018 }; \ 1019 struct Store##Type##PointerWriteBarrier##Operator final \ 1020 : public Store##Type##Operator { \ 1021 Store##Type##PointerWriteBarrier##Operator() \ 1022 : Store##Type##Operator(kPointerWriteBarrier) {} \ 1023 }; \ 1024 struct Store##Type##EphemeronKeyWriteBarrier##Operator final \ 1025 : public Store##Type##Operator { \ 1026 Store##Type##EphemeronKeyWriteBarrier##Operator() \ 1027 : Store##Type##Operator(kEphemeronKeyWriteBarrier) {} \ 1028 }; \ 1029 struct Store##Type##FullWriteBarrier##Operator final \ 1030 : public Store##Type##Operator { \ 1031 Store##Type##FullWriteBarrier##Operator() \ 1032 : Store##Type##Operator(kFullWriteBarrier) {} \ 1033 }; \ 1034 struct UnalignedStore##Type##Operator final \ 1035 : public Operator1<UnalignedStoreRepresentation> { \ 1036 UnalignedStore##Type##Operator() \ 1037 : Operator1<UnalignedStoreRepresentation>( \ 1038 IrOpcode::kUnalignedStore, \ 1039 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \ 1040 "UnalignedStore", 3, 1, 1, 0, 1, 0, \ 1041 MachineRepresentation::Type) {} \ 1042 }; \ 1043 struct ProtectedStore##Type##Operator \ 1044 : public Operator1<StoreRepresentation> { \ 1045 explicit ProtectedStore##Type##Operator() \ 1046 : Operator1<StoreRepresentation>( \ 1047 IrOpcode::kProtectedStore, \ 1048 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \ 1049 "ProtectedStore", 3, 1, 1, 0, 1, 0, \ 1050 StoreRepresentation(MachineRepresentation::Type, \ 1051 kNoWriteBarrier)) {} \ 1052 }; \ 1053 Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier; \ 1054 Store##Type##AssertNoWriteBarrier##Operator \ 1055 kStore##Type##AssertNoWriteBarrier; \ 1056 Store##Type##MapWriteBarrier##Operator kStore##Type##MapWriteBarrier; \ 1057 Store##Type##PointerWriteBarrier##Operator \ 1058 kStore##Type##PointerWriteBarrier; \ 1059 Store##Type##EphemeronKeyWriteBarrier##Operator \ 1060 kStore##Type##EphemeronKeyWriteBarrier; \ 1061 Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier; \ 1062 UnalignedStore##Type##Operator kUnalignedStore##Type; \ 1063 ProtectedStore##Type##Operator kProtectedStore##Type; 1064 MACHINE_REPRESENTATION_LIST(STORE) 1065#undef STORE 1066 1067#define ATOMIC_LOAD(Type) \ 1068 struct Word32SeqCstLoad##Type##Operator \ 1069 : public Operator1<AtomicLoadParameters> { \ 1070 Word32SeqCstLoad##Type##Operator() \ 1071 : Operator1<AtomicLoadParameters>( \ 1072 IrOpcode::kWord32AtomicLoad, Operator::kEliminatable, \ 1073 "Word32AtomicLoad", 2, 1, 1, 1, 1, 0, \ 1074 AtomicLoadParameters(MachineType::Type(), \ 1075 AtomicMemoryOrder::kSeqCst)) {} \ 1076 }; \ 1077 Word32SeqCstLoad##Type##Operator kWord32SeqCstLoad##Type; 1078 ATOMIC_TYPE_LIST(ATOMIC_LOAD) 1079#undef ATOMIC_LOAD 1080 1081#define ATOMIC_LOAD(Type) \ 1082 struct Word64SeqCstLoad##Type##Operator \ 1083 : public Operator1<AtomicLoadParameters> { \ 1084 Word64SeqCstLoad##Type##Operator() \ 1085 : Operator1<AtomicLoadParameters>( \ 1086 IrOpcode::kWord64AtomicLoad, Operator::kEliminatable, \ 1087 "Word64AtomicLoad", 2, 1, 1, 1, 1, 0, \ 1088 AtomicLoadParameters(MachineType::Type(), \ 1089 AtomicMemoryOrder::kSeqCst)) {} \ 1090 }; \ 1091 Word64SeqCstLoad##Type##Operator kWord64SeqCstLoad##Type; 1092 ATOMIC_U64_TYPE_LIST(ATOMIC_LOAD) 1093#undef ATOMIC_LOAD 1094 1095#define ATOMIC_STORE(Type) \ 1096 struct Word32SeqCstStore##Type##Operator \ 1097 : public Operator1<AtomicStoreParameters> { \ 1098 Word32SeqCstStore##Type##Operator() \ 1099 : Operator1<AtomicStoreParameters>( \ 1100 IrOpcode::kWord32AtomicStore, \ 1101 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \ 1102 "Word32AtomicStore", 3, 1, 1, 0, 1, 0, \ 1103 AtomicStoreParameters(MachineRepresentation::Type, \ 1104 kNoWriteBarrier, \ 1105 AtomicMemoryOrder::kSeqCst)) {} \ 1106 }; \ 1107 Word32SeqCstStore##Type##Operator kWord32SeqCstStore##Type; 1108 ATOMIC_REPRESENTATION_LIST(ATOMIC_STORE) 1109#undef ATOMIC_STORE 1110 1111#define ATOMIC_STORE(Type) \ 1112 struct Word64SeqCstStore##Type##Operator \ 1113 : public Operator1<AtomicStoreParameters> { \ 1114 Word64SeqCstStore##Type##Operator() \ 1115 : Operator1<AtomicStoreParameters>( \ 1116 IrOpcode::kWord64AtomicStore, \ 1117 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \ 1118 "Word64AtomicStore", 3, 1, 1, 0, 1, 0, \ 1119 AtomicStoreParameters(MachineRepresentation::Type, \ 1120 kNoWriteBarrier, \ 1121 AtomicMemoryOrder::kSeqCst)) {} \ 1122 }; \ 1123 Word64SeqCstStore##Type##Operator kWord64SeqCstStore##Type; 1124 ATOMIC64_REPRESENTATION_LIST(ATOMIC_STORE) 1125#undef ATOMIC_STORE 1126 1127#define ATOMIC_OP(op, type) \ 1128 struct op##type##Operator : public Operator1<MachineType> { \ 1129 op##type##Operator() \ 1130 : Operator1<MachineType>(IrOpcode::k##op, \ 1131 Operator::kNoDeopt | Operator::kNoThrow, #op, \ 1132 3, 1, 1, 1, 1, 0, MachineType::type()) {} \ 1133 }; \ 1134 op##type##Operator k##op##type; 1135#define ATOMIC_OP_LIST(type) \ 1136 ATOMIC_OP(Word32AtomicAdd, type) \ 1137 ATOMIC_OP(Word32AtomicSub, type) \ 1138 ATOMIC_OP(Word32AtomicAnd, type) \ 1139 ATOMIC_OP(Word32AtomicOr, type) \ 1140 ATOMIC_OP(Word32AtomicXor, type) \ 1141 ATOMIC_OP(Word32AtomicExchange, type) 1142 ATOMIC_TYPE_LIST(ATOMIC_OP_LIST) 1143#undef ATOMIC_OP_LIST 1144#define ATOMIC64_OP_LIST(type) \ 1145 ATOMIC_OP(Word64AtomicAdd, type) \ 1146 ATOMIC_OP(Word64AtomicSub, type) \ 1147 ATOMIC_OP(Word64AtomicAnd, type) \ 1148 ATOMIC_OP(Word64AtomicOr, type) \ 1149 ATOMIC_OP(Word64AtomicXor, type) \ 1150 ATOMIC_OP(Word64AtomicExchange, type) 1151 ATOMIC_U64_TYPE_LIST(ATOMIC64_OP_LIST) 1152#undef ATOMIC64_OP_LIST 1153#undef ATOMIC_OP 1154 1155#define ATOMIC_COMPARE_EXCHANGE(Type) \ 1156 struct Word32AtomicCompareExchange##Type##Operator \ 1157 : public Operator1<MachineType> { \ 1158 Word32AtomicCompareExchange##Type##Operator() \ 1159 : Operator1<MachineType>(IrOpcode::kWord32AtomicCompareExchange, \ 1160 Operator::kNoDeopt | Operator::kNoThrow, \ 1161 "Word32AtomicCompareExchange", 4, 1, 1, 1, 1, \ 1162 0, MachineType::Type()) {} \ 1163 }; \ 1164 Word32AtomicCompareExchange##Type##Operator \ 1165 kWord32AtomicCompareExchange##Type; 1166 ATOMIC_TYPE_LIST(ATOMIC_COMPARE_EXCHANGE) 1167#undef ATOMIC_COMPARE_EXCHANGE 1168 1169#define ATOMIC_COMPARE_EXCHANGE(Type) \ 1170 struct Word64AtomicCompareExchange##Type##Operator \ 1171 : public Operator1<MachineType> { \ 1172 Word64AtomicCompareExchange##Type##Operator() \ 1173 : Operator1<MachineType>(IrOpcode::kWord64AtomicCompareExchange, \ 1174 Operator::kNoDeopt | Operator::kNoThrow, \ 1175 "Word64AtomicCompareExchange", 4, 1, 1, 1, 1, \ 1176 0, MachineType::Type()) {} \ 1177 }; \ 1178 Word64AtomicCompareExchange##Type##Operator \ 1179 kWord64AtomicCompareExchange##Type; 1180 ATOMIC_U64_TYPE_LIST(ATOMIC_COMPARE_EXCHANGE) 1181#undef ATOMIC_COMPARE_EXCHANGE 1182 1183 struct Word32SeqCstPairLoadOperator : public Operator1<AtomicMemoryOrder> { 1184 Word32SeqCstPairLoadOperator() 1185 : Operator1<AtomicMemoryOrder>(IrOpcode::kWord32AtomicPairLoad, 1186 Operator::kNoDeopt | Operator::kNoThrow, 1187 "Word32AtomicPairLoad", 2, 1, 1, 2, 1, 0, 1188 AtomicMemoryOrder::kSeqCst) {} 1189 }; 1190 Word32SeqCstPairLoadOperator kWord32SeqCstPairLoad; 1191 1192 struct Word32SeqCstPairStoreOperator : public Operator1<AtomicMemoryOrder> { 1193 Word32SeqCstPairStoreOperator() 1194 : Operator1<AtomicMemoryOrder>(IrOpcode::kWord32AtomicPairStore, 1195 Operator::kNoDeopt | Operator::kNoThrow, 1196 "Word32AtomicPairStore", 4, 1, 1, 0, 1, 1197 0, AtomicMemoryOrder::kSeqCst) {} 1198 }; 1199 Word32SeqCstPairStoreOperator kWord32SeqCstPairStore; 1200 1201#define ATOMIC_PAIR_OP(op) \ 1202 struct Word32AtomicPair##op##Operator : public Operator { \ 1203 Word32AtomicPair##op##Operator() \ 1204 : Operator(IrOpcode::kWord32AtomicPair##op, \ 1205 Operator::kNoDeopt | Operator::kNoThrow, \ 1206 "Word32AtomicPair##op", 4, 1, 1, 2, 1, 0) {} \ 1207 }; \ 1208 Word32AtomicPair##op##Operator kWord32AtomicPair##op; 1209 ATOMIC_PAIR_BINOP_LIST(ATOMIC_PAIR_OP) 1210#undef ATOMIC_PAIR_OP 1211#undef ATOMIC_PAIR_BINOP_LIST 1212 1213 struct Word32AtomicPairCompareExchangeOperator : public Operator { 1214 Word32AtomicPairCompareExchangeOperator() 1215 : Operator(IrOpcode::kWord32AtomicPairCompareExchange, 1216 Operator::kNoDeopt | Operator::kNoThrow, 1217 "Word32AtomicPairCompareExchange", 6, 1, 1, 2, 1, 0) {} 1218 }; 1219 Word32AtomicPairCompareExchangeOperator kWord32AtomicPairCompareExchange; 1220 1221 struct MemoryBarrierOperator : public Operator { 1222 MemoryBarrierOperator() 1223 : Operator(IrOpcode::kMemoryBarrier, 1224 Operator::kNoDeopt | Operator::kNoThrow, "MemoryBarrier", 0, 1225 1, 1, 0, 1, 0) {} 1226 }; 1227 MemoryBarrierOperator kMemoryBarrier; 1228 1229 // The {BitcastWordToTagged} operator must not be marked as pure (especially 1230 // not idempotent), because otherwise the splitting logic in the Scheduler 1231 // might decide to split these operators, thus potentially creating live 1232 // ranges of allocation top across calls or other things that might allocate. 1233 // See https://bugs.chromium.org/p/v8/issues/detail?id=6059 for more details. 1234 struct BitcastWordToTaggedOperator : public Operator { 1235 BitcastWordToTaggedOperator() 1236 : Operator(IrOpcode::kBitcastWordToTagged, 1237 Operator::kEliminatable | Operator::kNoWrite, 1238 "BitcastWordToTagged", 1, 1, 1, 1, 1, 0) {} 1239 }; 1240 BitcastWordToTaggedOperator kBitcastWordToTagged; 1241 1242 struct BitcastTaggedToWordOperator : public Operator { 1243 BitcastTaggedToWordOperator() 1244 : Operator(IrOpcode::kBitcastTaggedToWord, 1245 Operator::kEliminatable | Operator::kNoWrite, 1246 "BitcastTaggedToWord", 1, 1, 1, 1, 1, 0) {} 1247 }; 1248 BitcastTaggedToWordOperator kBitcastTaggedToWord; 1249 1250 struct BitcastMaybeObjectToWordOperator : public Operator { 1251 BitcastMaybeObjectToWordOperator() 1252 : Operator(IrOpcode::kBitcastTaggedToWord, 1253 Operator::kEliminatable | Operator::kNoWrite, 1254 "BitcastMaybeObjectToWord", 1, 1, 1, 1, 1, 0) {} 1255 }; 1256 BitcastMaybeObjectToWordOperator kBitcastMaybeObjectToWord; 1257 1258 struct AbortCSADcheckOperator : public Operator { 1259 AbortCSADcheckOperator() 1260 : Operator(IrOpcode::kAbortCSADcheck, Operator::kNoThrow, 1261 "AbortCSADcheck", 1, 1, 1, 0, 1, 0) {} 1262 }; 1263 AbortCSADcheckOperator kAbortCSADcheck; 1264 1265 struct DebugBreakOperator : public Operator { 1266 DebugBreakOperator() 1267 : Operator(IrOpcode::kDebugBreak, Operator::kNoThrow, "DebugBreak", 0, 1268 1, 1, 0, 1, 0) {} 1269 }; 1270 DebugBreakOperator kDebugBreak; 1271 1272 struct UnsafePointerAddOperator final : public Operator { 1273 UnsafePointerAddOperator() 1274 : Operator(IrOpcode::kUnsafePointerAdd, Operator::kKontrol, 1275 "UnsafePointerAdd", 2, 1, 1, 1, 1, 0) {} 1276 }; 1277 UnsafePointerAddOperator kUnsafePointerAdd; 1278 1279 struct StackPointerGreaterThanOperator : public Operator1<StackCheckKind> { 1280 explicit StackPointerGreaterThanOperator(StackCheckKind kind) 1281 : Operator1<StackCheckKind>( 1282 IrOpcode::kStackPointerGreaterThan, Operator::kEliminatable, 1283 "StackPointerGreaterThan", 1, 1, 0, 1, 1, 0, kind) {} 1284 }; 1285#define STACK_POINTER_GREATER_THAN(Kind) \ 1286 struct StackPointerGreaterThan##Kind##Operator final \ 1287 : public StackPointerGreaterThanOperator { \ 1288 StackPointerGreaterThan##Kind##Operator() \ 1289 : StackPointerGreaterThanOperator(StackCheckKind::k##Kind) {} \ 1290 }; \ 1291 StackPointerGreaterThan##Kind##Operator kStackPointerGreaterThan##Kind; 1292 1293 STACK_POINTER_GREATER_THAN(JSFunctionEntry) 1294 STACK_POINTER_GREATER_THAN(JSIterationBody) 1295 STACK_POINTER_GREATER_THAN(CodeStubAssembler) 1296 STACK_POINTER_GREATER_THAN(Wasm) 1297#undef STACK_POINTER_GREATER_THAN 1298 1299 struct I8x16SwizzleOperator final : public Operator1<bool> { 1300 I8x16SwizzleOperator() 1301 : Operator1<bool>(IrOpcode::kI8x16Swizzle, Operator::kPure, 1302 "I8x16Swizzle", 2, 0, 0, 1, 0, 0, false) {} 1303 }; 1304 I8x16SwizzleOperator kI8x16Swizzle; 1305 struct I8x16RelaxedSwizzleOperator final : public Operator1<bool> { 1306 I8x16RelaxedSwizzleOperator() 1307 : Operator1<bool>(IrOpcode::kI8x16Swizzle, Operator::kPure, 1308 "I8x16RelaxedSwizzle", 2, 0, 0, 1, 0, 0, true) {} 1309 }; 1310 I8x16RelaxedSwizzleOperator kI8x16RelaxedSwizzle; 1311}; 1312 1313struct CommentOperator : public Operator1<const char*> { 1314 explicit CommentOperator(const char* msg) 1315 : Operator1<const char*>(IrOpcode::kComment, 1316 Operator::kNoThrow | Operator::kNoWrite, 1317 "Comment", 0, 1, 1, 0, 1, 0, msg) {} 1318}; 1319 1320namespace { 1321DEFINE_LAZY_LEAKY_OBJECT_GETTER(MachineOperatorGlobalCache, 1322 GetMachineOperatorGlobalCache) 1323} 1324 1325MachineOperatorBuilder::MachineOperatorBuilder( 1326 Zone* zone, MachineRepresentation word, Flags flags, 1327 AlignmentRequirements alignmentRequirements) 1328 : zone_(zone), 1329 cache_(*GetMachineOperatorGlobalCache()), 1330 word_(word), 1331 flags_(flags), 1332 alignment_requirements_(alignmentRequirements) { 1333 DCHECK(word == MachineRepresentation::kWord32 || 1334 word == MachineRepresentation::kWord64); 1335} 1336 1337const Operator* MachineOperatorBuilder::UnalignedLoad(LoadRepresentation rep) { 1338#define LOAD(Type) \ 1339 if (rep == MachineType::Type()) { \ 1340 return &cache_.kUnalignedLoad##Type; \ 1341 } 1342 MACHINE_TYPE_LIST(LOAD) 1343#undef LOAD 1344 UNREACHABLE(); 1345} 1346 1347const Operator* MachineOperatorBuilder::UnalignedStore( 1348 UnalignedStoreRepresentation rep) { 1349 switch (rep) { 1350#define STORE(kRep) \ 1351 case MachineRepresentation::kRep: \ 1352 return &cache_.kUnalignedStore##kRep; 1353 MACHINE_REPRESENTATION_LIST(STORE) 1354#undef STORE 1355 case MachineRepresentation::kBit: 1356 case MachineRepresentation::kNone: 1357 break; 1358 } 1359 UNREACHABLE(); 1360} 1361 1362#define PURE(Name, properties, value_input_count, control_input_count, \ 1363 output_count) \ 1364 const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; } 1365MACHINE_PURE_OP_LIST(PURE) 1366#undef PURE 1367 1368const Operator* MachineOperatorBuilder::Word32Sar(ShiftKind kind) { 1369 switch (kind) { 1370 case ShiftKind::kNormal: 1371 return &cache_.kNormalWord32Sar; 1372 case ShiftKind::kShiftOutZeros: 1373 return &cache_.kShiftOutZerosWord32Sar; 1374 } 1375} 1376 1377const Operator* MachineOperatorBuilder::Word64Sar(ShiftKind kind) { 1378 switch (kind) { 1379 case ShiftKind::kNormal: 1380 return &cache_.kNormalWord64Sar; 1381 case ShiftKind::kShiftOutZeros: 1382 return &cache_.kShiftOutZerosWord64Sar; 1383 } 1384} 1385 1386const Operator* MachineOperatorBuilder::TruncateFloat32ToUint32( 1387 TruncateKind kind) { 1388 switch (kind) { 1389 case TruncateKind::kArchitectureDefault: 1390 return &cache_.kArchitectureDefaultTruncateFloat32ToUint32; 1391 case TruncateKind::kSetOverflowToMin: 1392 return &cache_.kSetOverflowToMinTruncateFloat32ToUint32; 1393 } 1394} 1395 1396const Operator* MachineOperatorBuilder::TruncateFloat64ToInt64( 1397 TruncateKind kind) { 1398 switch (kind) { 1399 case TruncateKind::kArchitectureDefault: 1400 return &cache_.kArchitectureDefaultTruncateFloat64ToInt64; 1401 case TruncateKind::kSetOverflowToMin: 1402 return &cache_.kSetOverflowToMinTruncateFloat64ToInt64; 1403 } 1404} 1405 1406const Operator* MachineOperatorBuilder::TruncateFloat32ToInt32( 1407 TruncateKind kind) { 1408 switch (kind) { 1409 case TruncateKind::kArchitectureDefault: 1410 return &cache_.kArchitectureDefaultTruncateFloat32ToInt32; 1411 case TruncateKind::kSetOverflowToMin: 1412 return &cache_.kSetOverflowToMinTruncateFloat32ToInt32; 1413 } 1414} 1415 1416#define PURE(Name, properties, value_input_count, control_input_count, \ 1417 output_count) \ 1418 const OptionalOperator MachineOperatorBuilder::Name() { \ 1419 return OptionalOperator(flags_ & k##Name, &cache_.k##Name); \ 1420 } 1421PURE_OPTIONAL_OP_LIST(PURE) 1422#undef PURE 1423 1424#define OVERFLOW_OP(Name, properties) \ 1425 const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; } 1426OVERFLOW_OP_LIST(OVERFLOW_OP) 1427#undef OVERFLOW_OP 1428 1429const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) { 1430 DCHECK(!rep.IsMapWord()); 1431#define LOAD(Type) \ 1432 if (rep == MachineType::Type()) { \ 1433 return &cache_.kLoad##Type; \ 1434 } 1435 MACHINE_TYPE_LIST(LOAD) 1436#undef LOAD 1437 UNREACHABLE(); 1438} 1439 1440// Represents a load from a position in memory that is known to be immutable, 1441// e.g. an immutable IsolateRoot or an immutable field of a WasmInstanceObject. 1442// Because the returned value cannot change through the execution of a function, 1443// LoadImmutable is a pure operator and does not have effect or control edges. 1444// Requires that the memory in question has been initialized at function start 1445// even through inlining. 1446const Operator* MachineOperatorBuilder::LoadImmutable(LoadRepresentation rep) { 1447#define LOAD(Type) \ 1448 if (rep == MachineType::Type()) { \ 1449 return &cache_.kLoadImmutable##Type; \ 1450 } 1451 MACHINE_TYPE_LIST(LOAD) 1452#undef LOAD 1453 UNREACHABLE(); 1454} 1455 1456const Operator* MachineOperatorBuilder::ProtectedLoad(LoadRepresentation rep) { 1457#define LOAD(Type) \ 1458 if (rep == MachineType::Type()) { \ 1459 return &cache_.kProtectedLoad##Type; \ 1460 } 1461 MACHINE_TYPE_LIST(LOAD) 1462#undef LOAD 1463 UNREACHABLE(); 1464} 1465 1466const Operator* MachineOperatorBuilder::LoadTransform( 1467 MemoryAccessKind kind, LoadTransformation transform) { 1468#define LOAD_TRANSFORM_KIND(TYPE, KIND) \ 1469 if (kind == MemoryAccessKind::k##KIND && \ 1470 transform == LoadTransformation::k##TYPE) { \ 1471 return &cache_.k##KIND##LoadTransform##TYPE; \ 1472 } 1473#define LOAD_TRANSFORM(TYPE) \ 1474 LOAD_TRANSFORM_KIND(TYPE, Normal) \ 1475 LOAD_TRANSFORM_KIND(TYPE, Unaligned) \ 1476 LOAD_TRANSFORM_KIND(TYPE, Protected) 1477 1478 LOAD_TRANSFORM_LIST(LOAD_TRANSFORM) 1479#undef LOAD_TRANSFORM 1480#undef LOAD_TRANSFORM_KIND 1481 UNREACHABLE(); 1482} 1483 1484const Operator* MachineOperatorBuilder::LoadLane(MemoryAccessKind kind, 1485 LoadRepresentation rep, 1486 uint8_t laneidx) { 1487#define LOAD_LANE_KIND(TYPE, KIND, LANEIDX) \ 1488 if (kind == MemoryAccessKind::k##KIND && rep == MachineType::TYPE() && \ 1489 laneidx == LANEIDX) { \ 1490 return zone_->New<Operator1<LoadLaneParameters>>( \ 1491 IrOpcode::kLoadLane, \ 1492 MemoryAccessKind::k##KIND == MemoryAccessKind::kProtected \ 1493 ? Operator::kNoDeopt | Operator::kNoThrow \ 1494 : Operator::kEliminatable, \ 1495 "LoadLane", 3, 1, 1, 1, 1, 0, \ 1496 LoadLaneParameters{MemoryAccessKind::k##KIND, \ 1497 LoadRepresentation::TYPE(), LANEIDX}); \ 1498 } 1499 1500#define LOAD_LANE_T(T, LANE) \ 1501 LOAD_LANE_KIND(T, Normal, LANE) \ 1502 LOAD_LANE_KIND(T, Unaligned, LANE) \ 1503 LOAD_LANE_KIND(T, Protected, LANE) 1504 1505#define LOAD_LANE_INT8(LANE) LOAD_LANE_T(Int8, LANE) 1506#define LOAD_LANE_INT16(LANE) LOAD_LANE_T(Int16, LANE) 1507#define LOAD_LANE_INT32(LANE) LOAD_LANE_T(Int32, LANE) 1508#define LOAD_LANE_INT64(LANE) LOAD_LANE_T(Int64, LANE) 1509 1510 // Semicolons unnecessary, but helps formatting. 1511 SIMD_I8x16_LANES(LOAD_LANE_INT8); 1512 SIMD_I16x8_LANES(LOAD_LANE_INT16); 1513 SIMD_I32x4_LANES(LOAD_LANE_INT32); 1514 SIMD_I64x2_LANES(LOAD_LANE_INT64); 1515#undef LOAD_LANE_INT8 1516#undef LOAD_LANE_INT16 1517#undef LOAD_LANE_INT32 1518#undef LOAD_LANE_INT64 1519#undef LOAD_LANE_KIND 1520 UNREACHABLE(); 1521} 1522 1523const Operator* MachineOperatorBuilder::StoreLane(MemoryAccessKind kind, 1524 MachineRepresentation rep, 1525 uint8_t laneidx) { 1526#define STORE_LANE_KIND(REP, KIND, LANEIDX) \ 1527 if (kind == MemoryAccessKind::k##KIND && \ 1528 rep == MachineRepresentation::REP && laneidx == LANEIDX) { \ 1529 return zone_->New<Operator1<StoreLaneParameters>>( \ 1530 IrOpcode::kStoreLane, \ 1531 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \ 1532 "StoreLane", 3, 1, 1, 0, 1, 0, \ 1533 StoreLaneParameters{MemoryAccessKind::k##KIND, \ 1534 MachineRepresentation::REP, LANEIDX}); \ 1535 } 1536 1537#define STORE_LANE_T(T, LANE) \ 1538 STORE_LANE_KIND(T, Normal, LANE) \ 1539 STORE_LANE_KIND(T, Unaligned, LANE) \ 1540 STORE_LANE_KIND(T, Protected, LANE) 1541 1542#define STORE_LANE_WORD8(LANE) STORE_LANE_T(kWord8, LANE) 1543#define STORE_LANE_WORD16(LANE) STORE_LANE_T(kWord16, LANE) 1544#define STORE_LANE_WORD32(LANE) STORE_LANE_T(kWord32, LANE) 1545#define STORE_LANE_WORD64(LANE) STORE_LANE_T(kWord64, LANE) 1546 1547 // Semicolons unnecessary, but helps formatting. 1548 SIMD_I8x16_LANES(STORE_LANE_WORD8); 1549 SIMD_I16x8_LANES(STORE_LANE_WORD16); 1550 SIMD_I32x4_LANES(STORE_LANE_WORD32); 1551 SIMD_I64x2_LANES(STORE_LANE_WORD64); 1552#undef STORE_LANE_WORD8 1553#undef STORE_LANE_WORD16 1554#undef STORE_LANE_WORD32 1555#undef STORE_LANE_WORD64 1556#undef STORE_LANE_KIND 1557 UNREACHABLE(); 1558} 1559 1560const Operator* MachineOperatorBuilder::StackSlot(int size, int alignment) { 1561 DCHECK_LE(0, size); 1562 DCHECK(alignment == 0 || alignment == 4 || alignment == 8 || alignment == 16); 1563#define CASE_CACHED_SIZE(Size, Alignment) \ 1564 if (size == Size && alignment == Alignment) { \ 1565 return &cache_.kStackSlotOfSize##Size##OfAlignment##Alignment; \ 1566 } 1567 1568 STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(CASE_CACHED_SIZE) 1569 1570#undef CASE_CACHED_SIZE 1571 return zone_->New<StackSlotOperator>(size, alignment); 1572} 1573 1574const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep, 1575 int alignment) { 1576 return StackSlot(1 << ElementSizeLog2Of(rep), alignment); 1577} 1578 1579const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) { 1580 DCHECK_NE(store_rep.representation(), MachineRepresentation::kMapWord); 1581 switch (store_rep.representation()) { 1582#define STORE(kRep) \ 1583 case MachineRepresentation::kRep: \ 1584 switch (store_rep.write_barrier_kind()) { \ 1585 case kNoWriteBarrier: \ 1586 return &cache_.k##Store##kRep##NoWriteBarrier; \ 1587 case kAssertNoWriteBarrier: \ 1588 return &cache_.k##Store##kRep##AssertNoWriteBarrier; \ 1589 case kMapWriteBarrier: \ 1590 return &cache_.k##Store##kRep##MapWriteBarrier; \ 1591 case kPointerWriteBarrier: \ 1592 return &cache_.k##Store##kRep##PointerWriteBarrier; \ 1593 case kEphemeronKeyWriteBarrier: \ 1594 return &cache_.k##Store##kRep##EphemeronKeyWriteBarrier; \ 1595 case kFullWriteBarrier: \ 1596 return &cache_.k##Store##kRep##FullWriteBarrier; \ 1597 } \ 1598 break; 1599 MACHINE_REPRESENTATION_LIST(STORE) 1600#undef STORE 1601 case MachineRepresentation::kBit: 1602 case MachineRepresentation::kNone: 1603 break; 1604 } 1605 UNREACHABLE(); 1606} 1607 1608const Operator* MachineOperatorBuilder::ProtectedStore( 1609 MachineRepresentation rep) { 1610 switch (rep) { 1611#define STORE(kRep) \ 1612 case MachineRepresentation::kRep: \ 1613 return &cache_.kProtectedStore##kRep; \ 1614 break; 1615 MACHINE_REPRESENTATION_LIST(STORE) 1616#undef STORE 1617 case MachineRepresentation::kBit: 1618 case MachineRepresentation::kNone: 1619 break; 1620 } 1621 UNREACHABLE(); 1622} 1623 1624const Operator* MachineOperatorBuilder::UnsafePointerAdd() { 1625 return &cache_.kUnsafePointerAdd; 1626} 1627 1628const Operator* MachineOperatorBuilder::StackPointerGreaterThan( 1629 StackCheckKind kind) { 1630 switch (kind) { 1631 case StackCheckKind::kJSFunctionEntry: 1632 return &cache_.kStackPointerGreaterThanJSFunctionEntry; 1633 case StackCheckKind::kJSIterationBody: 1634 return &cache_.kStackPointerGreaterThanJSIterationBody; 1635 case StackCheckKind::kCodeStubAssembler: 1636 return &cache_.kStackPointerGreaterThanCodeStubAssembler; 1637 case StackCheckKind::kWasm: 1638 return &cache_.kStackPointerGreaterThanWasm; 1639 } 1640 UNREACHABLE(); 1641} 1642 1643const Operator* MachineOperatorBuilder::BitcastWordToTagged() { 1644 return &cache_.kBitcastWordToTagged; 1645} 1646 1647const Operator* MachineOperatorBuilder::BitcastTaggedToWord() { 1648 return &cache_.kBitcastTaggedToWord; 1649} 1650 1651const Operator* MachineOperatorBuilder::BitcastMaybeObjectToWord() { 1652 return &cache_.kBitcastMaybeObjectToWord; 1653} 1654 1655const Operator* MachineOperatorBuilder::AbortCSADcheck() { 1656 return &cache_.kAbortCSADcheck; 1657} 1658 1659const Operator* MachineOperatorBuilder::DebugBreak() { 1660 return &cache_.kDebugBreak; 1661} 1662 1663const Operator* MachineOperatorBuilder::Comment(const char* msg) { 1664 return zone_->New<CommentOperator>(msg); 1665} 1666 1667const Operator* MachineOperatorBuilder::MemBarrier() { 1668 return &cache_.kMemoryBarrier; 1669} 1670 1671const Operator* MachineOperatorBuilder::Word32AtomicLoad( 1672 AtomicLoadParameters params) { 1673#define CACHED_LOAD(Type) \ 1674 if (params.representation() == MachineType::Type() && \ 1675 params.order() == AtomicMemoryOrder::kSeqCst) { \ 1676 return &cache_.kWord32SeqCstLoad##Type; \ 1677 } 1678 ATOMIC_TYPE_LIST(CACHED_LOAD) 1679#undef CACHED_LOAD 1680 1681#define LOAD(Type) \ 1682 if (params.representation() == MachineType::Type()) { \ 1683 return zone_->New<Operator1<AtomicLoadParameters>>( \ 1684 IrOpcode::kWord32AtomicLoad, Operator::kEliminatable, \ 1685 "Word32AtomicLoad", 2, 1, 1, 1, 1, 0, params); \ 1686 } 1687 ATOMIC_TYPE_LIST(LOAD) 1688 ATOMIC_TAGGED_TYPE_LIST(LOAD) 1689#undef LOAD 1690 1691 UNREACHABLE(); 1692} 1693 1694const Operator* MachineOperatorBuilder::Word32AtomicStore( 1695 AtomicStoreParameters params) { 1696#define CACHED_STORE(kRep) \ 1697 if (params.representation() == MachineRepresentation::kRep && \ 1698 params.order() == AtomicMemoryOrder::kSeqCst) { \ 1699 return &cache_.kWord32SeqCstStore##kRep; \ 1700 } 1701 ATOMIC_REPRESENTATION_LIST(CACHED_STORE) 1702#undef CACHED_STORE 1703 1704#define STORE(kRep) \ 1705 if (params.representation() == MachineRepresentation::kRep) { \ 1706 return zone_->New<Operator1<AtomicStoreParameters>>( \ 1707 IrOpcode::kWord32AtomicStore, \ 1708 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \ 1709 "Word32AtomicStore", 3, 1, 1, 0, 1, 0, params); \ 1710 } 1711 ATOMIC_REPRESENTATION_LIST(STORE) 1712 ATOMIC_TAGGED_REPRESENTATION_LIST(STORE) 1713#undef STORE 1714 UNREACHABLE(); 1715} 1716 1717const Operator* MachineOperatorBuilder::Word32AtomicExchange(MachineType type) { 1718#define EXCHANGE(kType) \ 1719 if (type == MachineType::kType()) { \ 1720 return &cache_.kWord32AtomicExchange##kType; \ 1721 } 1722 ATOMIC_TYPE_LIST(EXCHANGE) 1723#undef EXCHANGE 1724 UNREACHABLE(); 1725} 1726 1727const Operator* MachineOperatorBuilder::Word32AtomicCompareExchange( 1728 MachineType type) { 1729#define COMPARE_EXCHANGE(kType) \ 1730 if (type == MachineType::kType()) { \ 1731 return &cache_.kWord32AtomicCompareExchange##kType; \ 1732 } 1733 ATOMIC_TYPE_LIST(COMPARE_EXCHANGE) 1734#undef COMPARE_EXCHANGE 1735 UNREACHABLE(); 1736} 1737 1738const Operator* MachineOperatorBuilder::Word32AtomicAdd(MachineType type) { 1739#define ADD(kType) \ 1740 if (type == MachineType::kType()) { \ 1741 return &cache_.kWord32AtomicAdd##kType; \ 1742 } 1743 ATOMIC_TYPE_LIST(ADD) 1744#undef ADD 1745 UNREACHABLE(); 1746} 1747 1748const Operator* MachineOperatorBuilder::Word32AtomicSub(MachineType type) { 1749#define SUB(kType) \ 1750 if (type == MachineType::kType()) { \ 1751 return &cache_.kWord32AtomicSub##kType; \ 1752 } 1753 ATOMIC_TYPE_LIST(SUB) 1754#undef SUB 1755 UNREACHABLE(); 1756} 1757 1758const Operator* MachineOperatorBuilder::Word32AtomicAnd(MachineType type) { 1759#define AND(kType) \ 1760 if (type == MachineType::kType()) { \ 1761 return &cache_.kWord32AtomicAnd##kType; \ 1762 } 1763 ATOMIC_TYPE_LIST(AND) 1764#undef AND 1765 UNREACHABLE(); 1766} 1767 1768const Operator* MachineOperatorBuilder::Word32AtomicOr(MachineType type) { 1769#define OR(kType) \ 1770 if (type == MachineType::kType()) { \ 1771 return &cache_.kWord32AtomicOr##kType; \ 1772 } 1773 ATOMIC_TYPE_LIST(OR) 1774#undef OR 1775 UNREACHABLE(); 1776} 1777 1778const Operator* MachineOperatorBuilder::Word32AtomicXor(MachineType type) { 1779#define XOR(kType) \ 1780 if (type == MachineType::kType()) { \ 1781 return &cache_.kWord32AtomicXor##kType; \ 1782 } 1783 ATOMIC_TYPE_LIST(XOR) 1784#undef XOR 1785 UNREACHABLE(); 1786} 1787 1788const Operator* MachineOperatorBuilder::Word64AtomicLoad( 1789 AtomicLoadParameters params) { 1790#define CACHED_LOAD(Type) \ 1791 if (params.representation() == MachineType::Type() && \ 1792 params.order() == AtomicMemoryOrder::kSeqCst) { \ 1793 return &cache_.kWord64SeqCstLoad##Type; \ 1794 } 1795 ATOMIC_U64_TYPE_LIST(CACHED_LOAD) 1796#undef CACHED_LOAD 1797 1798#define LOAD(Type) \ 1799 if (params.representation() == MachineType::Type()) { \ 1800 return zone_->New<Operator1<AtomicLoadParameters>>( \ 1801 IrOpcode::kWord64AtomicLoad, Operator::kEliminatable, \ 1802 "Word64AtomicLoad", 2, 1, 1, 1, 1, 0, params); \ 1803 } 1804 ATOMIC_U64_TYPE_LIST(LOAD) 1805 ATOMIC64_TAGGED_TYPE_LIST(LOAD) 1806#undef LOAD 1807 1808 UNREACHABLE(); 1809} 1810 1811const Operator* MachineOperatorBuilder::Word64AtomicStore( 1812 AtomicStoreParameters params) { 1813#define CACHED_STORE(kRep) \ 1814 if (params.representation() == MachineRepresentation::kRep && \ 1815 params.order() == AtomicMemoryOrder::kSeqCst) { \ 1816 return &cache_.kWord64SeqCstStore##kRep; \ 1817 } 1818 ATOMIC64_REPRESENTATION_LIST(CACHED_STORE) 1819#undef CACHED_STORE 1820 1821#define STORE(kRep) \ 1822 if (params.representation() == MachineRepresentation::kRep) { \ 1823 return zone_->New<Operator1<AtomicStoreParameters>>( \ 1824 IrOpcode::kWord64AtomicStore, \ 1825 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \ 1826 "Word64AtomicStore", 3, 1, 1, 0, 1, 0, params); \ 1827 } 1828 ATOMIC64_REPRESENTATION_LIST(STORE) 1829 ATOMIC64_TAGGED_REPRESENTATION_LIST(STORE) 1830#undef STORE 1831 1832 UNREACHABLE(); 1833} 1834 1835const Operator* MachineOperatorBuilder::Word64AtomicAdd(MachineType type) { 1836#define ADD(kType) \ 1837 if (type == MachineType::kType()) { \ 1838 return &cache_.kWord64AtomicAdd##kType; \ 1839 } 1840 ATOMIC_U64_TYPE_LIST(ADD) 1841#undef ADD 1842 UNREACHABLE(); 1843} 1844 1845const Operator* MachineOperatorBuilder::Word64AtomicSub(MachineType type) { 1846#define SUB(kType) \ 1847 if (type == MachineType::kType()) { \ 1848 return &cache_.kWord64AtomicSub##kType; \ 1849 } 1850 ATOMIC_U64_TYPE_LIST(SUB) 1851#undef SUB 1852 UNREACHABLE(); 1853} 1854 1855const Operator* MachineOperatorBuilder::Word64AtomicAnd(MachineType type) { 1856#define AND(kType) \ 1857 if (type == MachineType::kType()) { \ 1858 return &cache_.kWord64AtomicAnd##kType; \ 1859 } 1860 ATOMIC_U64_TYPE_LIST(AND) 1861#undef AND 1862 UNREACHABLE(); 1863} 1864 1865const Operator* MachineOperatorBuilder::Word64AtomicOr(MachineType type) { 1866#define OR(kType) \ 1867 if (type == MachineType::kType()) { \ 1868 return &cache_.kWord64AtomicOr##kType; \ 1869 } 1870 ATOMIC_U64_TYPE_LIST(OR) 1871#undef OR 1872 UNREACHABLE(); 1873} 1874 1875const Operator* MachineOperatorBuilder::Word64AtomicXor(MachineType type) { 1876#define XOR(kType) \ 1877 if (type == MachineType::kType()) { \ 1878 return &cache_.kWord64AtomicXor##kType; \ 1879 } 1880 ATOMIC_U64_TYPE_LIST(XOR) 1881#undef XOR 1882 UNREACHABLE(); 1883} 1884 1885const Operator* MachineOperatorBuilder::Word64AtomicExchange(MachineType type) { 1886#define EXCHANGE(kType) \ 1887 if (type == MachineType::kType()) { \ 1888 return &cache_.kWord64AtomicExchange##kType; \ 1889 } 1890 ATOMIC_U64_TYPE_LIST(EXCHANGE) 1891#undef EXCHANGE 1892 UNREACHABLE(); 1893} 1894 1895const Operator* MachineOperatorBuilder::Word64AtomicCompareExchange( 1896 MachineType type) { 1897#define COMPARE_EXCHANGE(kType) \ 1898 if (type == MachineType::kType()) { \ 1899 return &cache_.kWord64AtomicCompareExchange##kType; \ 1900 } 1901 ATOMIC_U64_TYPE_LIST(COMPARE_EXCHANGE) 1902#undef COMPARE_EXCHANGE 1903 UNREACHABLE(); 1904} 1905 1906const Operator* MachineOperatorBuilder::Word32AtomicPairLoad( 1907 AtomicMemoryOrder order) { 1908 if (order == AtomicMemoryOrder::kSeqCst) { 1909 return &cache_.kWord32SeqCstPairLoad; 1910 } 1911 return zone_->New<Operator1<AtomicMemoryOrder>>( 1912 IrOpcode::kWord32AtomicPairLoad, Operator::kNoDeopt | Operator::kNoThrow, 1913 "Word32AtomicPairLoad", 2, 1, 1, 2, 1, 0, order); 1914} 1915 1916const Operator* MachineOperatorBuilder::Word32AtomicPairStore( 1917 AtomicMemoryOrder order) { 1918 if (order == AtomicMemoryOrder::kSeqCst) { 1919 return &cache_.kWord32SeqCstPairStore; 1920 } 1921 return zone_->New<Operator1<AtomicMemoryOrder>>( 1922 IrOpcode::kWord32AtomicPairStore, Operator::kNoDeopt | Operator::kNoThrow, 1923 "Word32AtomicPairStore", 4, 1, 1, 0, 1, 0, order); 1924} 1925 1926const Operator* MachineOperatorBuilder::Word32AtomicPairAdd() { 1927 return &cache_.kWord32AtomicPairAdd; 1928} 1929 1930const Operator* MachineOperatorBuilder::Word32AtomicPairSub() { 1931 return &cache_.kWord32AtomicPairSub; 1932} 1933 1934const Operator* MachineOperatorBuilder::Word32AtomicPairAnd() { 1935 return &cache_.kWord32AtomicPairAnd; 1936} 1937 1938const Operator* MachineOperatorBuilder::Word32AtomicPairOr() { 1939 return &cache_.kWord32AtomicPairOr; 1940} 1941 1942const Operator* MachineOperatorBuilder::Word32AtomicPairXor() { 1943 return &cache_.kWord32AtomicPairXor; 1944} 1945 1946const Operator* MachineOperatorBuilder::Word32AtomicPairExchange() { 1947 return &cache_.kWord32AtomicPairExchange; 1948} 1949 1950const Operator* MachineOperatorBuilder::Word32AtomicPairCompareExchange() { 1951 return &cache_.kWord32AtomicPairCompareExchange; 1952} 1953 1954#define EXTRACT_LANE_OP(Type, Sign, lane_count) \ 1955 const Operator* MachineOperatorBuilder::Type##ExtractLane##Sign( \ 1956 int32_t lane_index) { \ 1957 DCHECK(0 <= lane_index && lane_index < lane_count); \ 1958 return zone_->New<Operator1<int32_t>>( \ 1959 IrOpcode::k##Type##ExtractLane##Sign, Operator::kPure, \ 1960 "" #Type "ExtractLane" #Sign, 1, 0, 0, 1, 0, 0, lane_index); \ 1961 } 1962EXTRACT_LANE_OP(F64x2, , 2) 1963EXTRACT_LANE_OP(F32x4, , 4) 1964EXTRACT_LANE_OP(I64x2, , 2) 1965EXTRACT_LANE_OP(I32x4, , 4) 1966EXTRACT_LANE_OP(I16x8, U, 8) 1967EXTRACT_LANE_OP(I16x8, S, 8) 1968EXTRACT_LANE_OP(I8x16, U, 16) 1969EXTRACT_LANE_OP(I8x16, S, 16) 1970#undef EXTRACT_LANE_OP 1971 1972#define REPLACE_LANE_OP(Type, lane_count) \ 1973 const Operator* MachineOperatorBuilder::Type##ReplaceLane( \ 1974 int32_t lane_index) { \ 1975 DCHECK(0 <= lane_index && lane_index < lane_count); \ 1976 return zone_->New<Operator1<int32_t>>(IrOpcode::k##Type##ReplaceLane, \ 1977 Operator::kPure, "Replace lane", 2, \ 1978 0, 0, 1, 0, 0, lane_index); \ 1979 } 1980SIMD_LANE_OP_LIST(REPLACE_LANE_OP) 1981#undef REPLACE_LANE_OP 1982 1983const Operator* MachineOperatorBuilder::I64x2ReplaceLaneI32Pair( 1984 int32_t lane_index) { 1985 DCHECK(0 <= lane_index && lane_index < 2); 1986 return zone_->New<Operator1<int32_t>>(IrOpcode::kI64x2ReplaceLaneI32Pair, 1987 Operator::kPure, "Replace lane", 3, 0, 1988 0, 1, 0, 0, lane_index); 1989} 1990 1991bool operator==(S128ImmediateParameter const& lhs, 1992 S128ImmediateParameter const& rhs) { 1993 return (lhs.immediate() == rhs.immediate()); 1994} 1995 1996bool operator!=(S128ImmediateParameter const& lhs, 1997 S128ImmediateParameter const& rhs) { 1998 return !(lhs == rhs); 1999} 2000 2001size_t hash_value(S128ImmediateParameter const& p) { 2002 return base::hash_range(p.immediate().begin(), p.immediate().end()); 2003} 2004 2005std::ostream& operator<<(std::ostream& os, S128ImmediateParameter const& p) { 2006 for (int i = 0; i < 16; i++) { 2007 const char* separator = (i < 15) ? "," : ""; 2008 os << static_cast<uint32_t>(p[i]) << separator; 2009 } 2010 return os; 2011} 2012 2013S128ImmediateParameter const& S128ImmediateParameterOf(Operator const* op) { 2014 DCHECK(IrOpcode::kI8x16Shuffle == op->opcode() || 2015 IrOpcode::kS128Const == op->opcode()); 2016 return OpParameter<S128ImmediateParameter>(op); 2017} 2018 2019const Operator* MachineOperatorBuilder::S128Const(const uint8_t value[16]) { 2020 return zone_->New<Operator1<S128ImmediateParameter>>( 2021 IrOpcode::kS128Const, Operator::kPure, "Immediate", 0, 0, 0, 1, 0, 0, 2022 S128ImmediateParameter(value)); 2023} 2024 2025const Operator* MachineOperatorBuilder::I8x16Shuffle( 2026 const uint8_t shuffle[16]) { 2027 return zone_->New<Operator1<S128ImmediateParameter>>( 2028 IrOpcode::kI8x16Shuffle, Operator::kPure, "Shuffle", 2, 0, 0, 1, 0, 0, 2029 S128ImmediateParameter(shuffle)); 2030} 2031 2032const Operator* MachineOperatorBuilder::I8x16Swizzle(bool relaxed) { 2033 if (relaxed) { 2034 return &cache_.kI8x16RelaxedSwizzle; 2035 } else { 2036 return &cache_.kI8x16Swizzle; 2037 } 2038} 2039 2040StackCheckKind StackCheckKindOf(Operator const* op) { 2041 DCHECK_EQ(IrOpcode::kStackPointerGreaterThan, op->opcode()); 2042 return OpParameter<StackCheckKind>(op); 2043} 2044 2045#undef PURE_BINARY_OP_LIST_32 2046#undef PURE_BINARY_OP_LIST_64 2047#undef MACHINE_PURE_OP_LIST 2048#undef PURE_OPTIONAL_OP_LIST 2049#undef OVERFLOW_OP_LIST 2050#undef MACHINE_TYPE_LIST 2051#undef MACHINE_REPRESENTATION_LIST 2052#undef ATOMIC_TYPE_LIST 2053#undef ATOMIC_U64_TYPE_LIST 2054#undef ATOMIC_U32_TYPE_LIST 2055#undef ATOMIC_TAGGED_TYPE_LIST 2056#undef ATOMIC64_TAGGED_TYPE_LIST 2057#undef ATOMIC_REPRESENTATION_LIST 2058#undef ATOMIC_TAGGED_REPRESENTATION_LIST 2059#undef ATOMIC64_REPRESENTATION_LIST 2060#undef ATOMIC64_TAGGED_REPRESENTATION_LIST 2061#undef SIMD_LANE_OP_LIST 2062#undef STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST 2063#undef LOAD_TRANSFORM_LIST 2064 2065} // namespace compiler 2066} // namespace internal 2067} // namespace v8 2068