11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_INTERPRETER_BYTECODE_OPERANDS_H_ 61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BYTECODE_OPERANDS_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/base/bounds.h" 91cb0ef41Sopenharmony_ci#include "src/common/globals.h" 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_cinamespace v8 { 121cb0ef41Sopenharmony_cinamespace internal { 131cb0ef41Sopenharmony_cinamespace interpreter { 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci#define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone) 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci#define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \ 181cb0ef41Sopenharmony_ci V(Reg, OperandTypeInfo::kScalableSignedByte) \ 191cb0ef41Sopenharmony_ci V(RegList, OperandTypeInfo::kScalableSignedByte) \ 201cb0ef41Sopenharmony_ci V(RegPair, OperandTypeInfo::kScalableSignedByte) 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci#define REGISTER_OUTPUT_OPERAND_TYPE_LIST(V) \ 231cb0ef41Sopenharmony_ci V(RegOut, OperandTypeInfo::kScalableSignedByte) \ 241cb0ef41Sopenharmony_ci V(RegOutList, OperandTypeInfo::kScalableSignedByte) \ 251cb0ef41Sopenharmony_ci V(RegOutPair, OperandTypeInfo::kScalableSignedByte) \ 261cb0ef41Sopenharmony_ci V(RegOutTriple, OperandTypeInfo::kScalableSignedByte) 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci#define SIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \ 291cb0ef41Sopenharmony_ci V(Imm, OperandTypeInfo::kScalableSignedByte) 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci#define UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \ 321cb0ef41Sopenharmony_ci V(Idx, OperandTypeInfo::kScalableUnsignedByte) \ 331cb0ef41Sopenharmony_ci V(UImm, OperandTypeInfo::kScalableUnsignedByte) \ 341cb0ef41Sopenharmony_ci V(RegCount, OperandTypeInfo::kScalableUnsignedByte) 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci#define UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(V) \ 371cb0ef41Sopenharmony_ci V(Flag8, OperandTypeInfo::kFixedUnsignedByte) \ 381cb0ef41Sopenharmony_ci V(IntrinsicId, OperandTypeInfo::kFixedUnsignedByte) \ 391cb0ef41Sopenharmony_ci V(RuntimeId, OperandTypeInfo::kFixedUnsignedShort) \ 401cb0ef41Sopenharmony_ci V(NativeContextIndex, OperandTypeInfo::kFixedUnsignedByte) 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci// Carefully ordered for operand type range checks below. 431cb0ef41Sopenharmony_ci#define NON_REGISTER_OPERAND_TYPE_LIST(V) \ 441cb0ef41Sopenharmony_ci INVALID_OPERAND_TYPE_LIST(V) \ 451cb0ef41Sopenharmony_ci UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(V) \ 461cb0ef41Sopenharmony_ci UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) \ 471cb0ef41Sopenharmony_ci SIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(V) 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci// Carefully ordered for operand type range checks below. 501cb0ef41Sopenharmony_ci#define REGISTER_OPERAND_TYPE_LIST(V) \ 511cb0ef41Sopenharmony_ci REGISTER_INPUT_OPERAND_TYPE_LIST(V) \ 521cb0ef41Sopenharmony_ci REGISTER_OUTPUT_OPERAND_TYPE_LIST(V) 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci// The list of operand types used by bytecodes. 551cb0ef41Sopenharmony_ci// Carefully ordered for operand type range checks below. 561cb0ef41Sopenharmony_ci#define OPERAND_TYPE_LIST(V) \ 571cb0ef41Sopenharmony_ci NON_REGISTER_OPERAND_TYPE_LIST(V) \ 581cb0ef41Sopenharmony_ci REGISTER_OPERAND_TYPE_LIST(V) 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci// Enumeration of scaling factors applicable to scalable operands. Code 611cb0ef41Sopenharmony_ci// relies on being able to cast values to integer scaling values. 621cb0ef41Sopenharmony_ci#define OPERAND_SCALE_LIST(V) \ 631cb0ef41Sopenharmony_ci V(Single, 1) \ 641cb0ef41Sopenharmony_ci V(Double, 2) \ 651cb0ef41Sopenharmony_ci V(Quadruple, 4) 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_cienum class OperandScale : uint8_t { 681cb0ef41Sopenharmony_ci#define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale, 691cb0ef41Sopenharmony_ci OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE) 701cb0ef41Sopenharmony_ci#undef DECLARE_OPERAND_SCALE 711cb0ef41Sopenharmony_ci kLast = kQuadruple 721cb0ef41Sopenharmony_ci}; 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci// Enumeration of the size classes of operand types used by 751cb0ef41Sopenharmony_ci// bytecodes. Code relies on being able to cast values to integer 761cb0ef41Sopenharmony_ci// types to get the size in bytes. 771cb0ef41Sopenharmony_cienum class OperandSize : uint8_t { 781cb0ef41Sopenharmony_ci kNone = 0, 791cb0ef41Sopenharmony_ci kByte = 1, 801cb0ef41Sopenharmony_ci kShort = 2, 811cb0ef41Sopenharmony_ci kQuad = 4, 821cb0ef41Sopenharmony_ci kLast = kQuad 831cb0ef41Sopenharmony_ci}; 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci// Primitive operand info used that summarize properties of operands. 861cb0ef41Sopenharmony_ci// Columns are Name, IsScalable, IsUnsigned, UnscaledSize. 871cb0ef41Sopenharmony_ci#define OPERAND_TYPE_INFO_LIST(V) \ 881cb0ef41Sopenharmony_ci V(None, false, false, OperandSize::kNone) \ 891cb0ef41Sopenharmony_ci V(ScalableSignedByte, true, false, OperandSize::kByte) \ 901cb0ef41Sopenharmony_ci V(ScalableUnsignedByte, true, true, OperandSize::kByte) \ 911cb0ef41Sopenharmony_ci V(FixedUnsignedByte, false, true, OperandSize::kByte) \ 921cb0ef41Sopenharmony_ci V(FixedUnsignedShort, false, true, OperandSize::kShort) 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_cienum class OperandTypeInfo : uint8_t { 951cb0ef41Sopenharmony_ci#define DECLARE_OPERAND_TYPE_INFO(Name, ...) k##Name, 961cb0ef41Sopenharmony_ci OPERAND_TYPE_INFO_LIST(DECLARE_OPERAND_TYPE_INFO) 971cb0ef41Sopenharmony_ci#undef DECLARE_OPERAND_TYPE_INFO 981cb0ef41Sopenharmony_ci}; 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci// Enumeration of operand types used by bytecodes. 1011cb0ef41Sopenharmony_cienum class OperandType : uint8_t { 1021cb0ef41Sopenharmony_ci#define DECLARE_OPERAND_TYPE(Name, _) k##Name, 1031cb0ef41Sopenharmony_ci OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE) 1041cb0ef41Sopenharmony_ci#undef DECLARE_OPERAND_TYPE 1051cb0ef41Sopenharmony_ci#define COUNT_OPERAND_TYPES(x, _) +1 1061cb0ef41Sopenharmony_ci // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will 1071cb0ef41Sopenharmony_ci // evaluate to the same value as the last operand. 1081cb0ef41Sopenharmony_ci kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES) 1091cb0ef41Sopenharmony_ci#undef COUNT_OPERAND_TYPES 1101cb0ef41Sopenharmony_ci}; 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_cienum class ImplicitRegisterUse : uint8_t { 1131cb0ef41Sopenharmony_ci kNone = 0, 1141cb0ef41Sopenharmony_ci kReadAccumulator = 1 << 0, 1151cb0ef41Sopenharmony_ci kWriteAccumulator = 1 << 1, 1161cb0ef41Sopenharmony_ci kWriteShortStar = 1 << 2, 1171cb0ef41Sopenharmony_ci kReadWriteAccumulator = kReadAccumulator | kWriteAccumulator, 1181cb0ef41Sopenharmony_ci kReadAccumulatorWriteShortStar = kReadAccumulator | kWriteShortStar 1191cb0ef41Sopenharmony_ci}; 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ciconstexpr inline ImplicitRegisterUse operator&(ImplicitRegisterUse lhs, 1221cb0ef41Sopenharmony_ci ImplicitRegisterUse rhs) { 1231cb0ef41Sopenharmony_ci return static_cast<ImplicitRegisterUse>(static_cast<int>(lhs) & 1241cb0ef41Sopenharmony_ci static_cast<int>(rhs)); 1251cb0ef41Sopenharmony_ci} 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ciconstexpr inline ImplicitRegisterUse operator|(ImplicitRegisterUse lhs, 1281cb0ef41Sopenharmony_ci ImplicitRegisterUse rhs) { 1291cb0ef41Sopenharmony_ci return static_cast<ImplicitRegisterUse>(static_cast<int>(lhs) | 1301cb0ef41Sopenharmony_ci static_cast<int>(rhs)); 1311cb0ef41Sopenharmony_ci} 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 1341cb0ef41Sopenharmony_ci const ImplicitRegisterUse& use); 1351cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 1361cb0ef41Sopenharmony_ci const OperandScale& operand_scale); 1371cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 1381cb0ef41Sopenharmony_ci const OperandSize& operand_size); 1391cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 1401cb0ef41Sopenharmony_ci const OperandType& operand_type); 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ciclass BytecodeOperands : public AllStatic { 1431cb0ef41Sopenharmony_ci public: 1441cb0ef41Sopenharmony_ci // The total number of bytecode operand types used. 1451cb0ef41Sopenharmony_ci static const int kOperandTypeCount = static_cast<int>(OperandType::kLast) + 1; 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci// The total number of bytecode operand scales used. 1481cb0ef41Sopenharmony_ci#define OPERAND_SCALE_COUNT(...) +1 1491cb0ef41Sopenharmony_ci static const int kOperandScaleCount = 1501cb0ef41Sopenharmony_ci 0 OPERAND_SCALE_LIST(OPERAND_SCALE_COUNT); 1511cb0ef41Sopenharmony_ci#undef OPERAND_SCALE_COUNT 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci static constexpr int OperandScaleAsIndex(OperandScale operand_scale) { 1541cb0ef41Sopenharmony_ci#ifdef DEBUG 1551cb0ef41Sopenharmony_ci int result = static_cast<int>(operand_scale) >> 1; 1561cb0ef41Sopenharmony_ci switch (operand_scale) { 1571cb0ef41Sopenharmony_ci case OperandScale::kSingle: 1581cb0ef41Sopenharmony_ci DCHECK_EQ(0, result); 1591cb0ef41Sopenharmony_ci break; 1601cb0ef41Sopenharmony_ci case OperandScale::kDouble: 1611cb0ef41Sopenharmony_ci DCHECK_EQ(1, result); 1621cb0ef41Sopenharmony_ci break; 1631cb0ef41Sopenharmony_ci case OperandScale::kQuadruple: 1641cb0ef41Sopenharmony_ci DCHECK_EQ(2, result); 1651cb0ef41Sopenharmony_ci break; 1661cb0ef41Sopenharmony_ci default: 1671cb0ef41Sopenharmony_ci UNREACHABLE(); 1681cb0ef41Sopenharmony_ci } 1691cb0ef41Sopenharmony_ci#endif 1701cb0ef41Sopenharmony_ci return static_cast<int>(operand_scale) >> 1; 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci // Returns true if |implicit_register_use| reads the 1741cb0ef41Sopenharmony_ci // accumulator. 1751cb0ef41Sopenharmony_ci static constexpr bool ReadsAccumulator( 1761cb0ef41Sopenharmony_ci ImplicitRegisterUse implicit_register_use) { 1771cb0ef41Sopenharmony_ci return (implicit_register_use & ImplicitRegisterUse::kReadAccumulator) == 1781cb0ef41Sopenharmony_ci ImplicitRegisterUse::kReadAccumulator; 1791cb0ef41Sopenharmony_ci } 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ci // Returns true if |implicit_register_use| writes the 1821cb0ef41Sopenharmony_ci // accumulator. 1831cb0ef41Sopenharmony_ci static constexpr bool WritesAccumulator( 1841cb0ef41Sopenharmony_ci ImplicitRegisterUse implicit_register_use) { 1851cb0ef41Sopenharmony_ci return (implicit_register_use & ImplicitRegisterUse::kWriteAccumulator) == 1861cb0ef41Sopenharmony_ci ImplicitRegisterUse::kWriteAccumulator; 1871cb0ef41Sopenharmony_ci } 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci // Returns true if |implicit_register_use| writes to a 1901cb0ef41Sopenharmony_ci // register not specified by an operand. 1911cb0ef41Sopenharmony_ci static constexpr bool WritesImplicitRegister( 1921cb0ef41Sopenharmony_ci ImplicitRegisterUse implicit_register_use) { 1931cb0ef41Sopenharmony_ci return (implicit_register_use & ImplicitRegisterUse::kWriteShortStar) == 1941cb0ef41Sopenharmony_ci ImplicitRegisterUse::kWriteShortStar; 1951cb0ef41Sopenharmony_ci } 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci // Returns true if |operand_type| is a scalable signed byte. 1981cb0ef41Sopenharmony_ci static constexpr bool IsScalableSignedByte(OperandType operand_type) { 1991cb0ef41Sopenharmony_ci return base::IsInRange(operand_type, OperandType::kImm, 2001cb0ef41Sopenharmony_ci OperandType::kRegOutTriple); 2011cb0ef41Sopenharmony_ci } 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci // Returns true if |operand_type| is a scalable unsigned byte. 2041cb0ef41Sopenharmony_ci static constexpr bool IsScalableUnsignedByte(OperandType operand_type) { 2051cb0ef41Sopenharmony_ci return base::IsInRange(operand_type, OperandType::kIdx, 2061cb0ef41Sopenharmony_ci OperandType::kRegCount); 2071cb0ef41Sopenharmony_ci } 2081cb0ef41Sopenharmony_ci}; 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_ci} // namespace interpreter 2111cb0ef41Sopenharmony_ci} // namespace internal 2121cb0ef41Sopenharmony_ci} // namespace v8 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci#endif // V8_INTERPRETER_BYTECODE_OPERANDS_H_ 215