11cb0ef41Sopenharmony_ci// Copyright 2014 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_COMPILER_BACKEND_INSTRUCTION_SELECTOR_IMPL_H_ 61cb0ef41Sopenharmony_ci#define V8_COMPILER_BACKEND_INSTRUCTION_SELECTOR_IMPL_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/codegen/macro-assembler.h" 91cb0ef41Sopenharmony_ci#include "src/compiler/backend/instruction-selector.h" 101cb0ef41Sopenharmony_ci#include "src/compiler/backend/instruction.h" 111cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h" 121cb0ef41Sopenharmony_ci#include "src/compiler/linkage.h" 131cb0ef41Sopenharmony_ci#include "src/compiler/schedule.h" 141cb0ef41Sopenharmony_ci#include "src/objects/tagged-index.h" 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cinamespace v8 { 171cb0ef41Sopenharmony_cinamespace internal { 181cb0ef41Sopenharmony_cinamespace compiler { 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_cistruct CaseInfo { 211cb0ef41Sopenharmony_ci int32_t value; // The case value. 221cb0ef41Sopenharmony_ci int32_t order; // The order for lowering to comparisons (less means earlier). 231cb0ef41Sopenharmony_ci BasicBlock* branch; // The basic blocks corresponding to the case value. 241cb0ef41Sopenharmony_ci}; 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ciinline bool operator<(const CaseInfo& l, const CaseInfo& r) { 271cb0ef41Sopenharmony_ci return l.order < r.order; 281cb0ef41Sopenharmony_ci} 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci// Helper struct containing data about a table or lookup switch. 311cb0ef41Sopenharmony_ciclass SwitchInfo { 321cb0ef41Sopenharmony_ci public: 331cb0ef41Sopenharmony_ci SwitchInfo(ZoneVector<CaseInfo> const& cases, int32_t min_value, 341cb0ef41Sopenharmony_ci int32_t max_value, BasicBlock* default_branch) 351cb0ef41Sopenharmony_ci : cases_(cases), 361cb0ef41Sopenharmony_ci min_value_(min_value), 371cb0ef41Sopenharmony_ci max_value_(max_value), 381cb0ef41Sopenharmony_ci default_branch_(default_branch) { 391cb0ef41Sopenharmony_ci if (cases.size() != 0) { 401cb0ef41Sopenharmony_ci DCHECK_LE(min_value, max_value); 411cb0ef41Sopenharmony_ci // Note that {value_range} can be 0 if {min_value} is -2^31 and 421cb0ef41Sopenharmony_ci // {max_value} is 2^31-1, so don't assume that it's non-zero below. 431cb0ef41Sopenharmony_ci value_range_ = 441cb0ef41Sopenharmony_ci 1u + bit_cast<uint32_t>(max_value) - bit_cast<uint32_t>(min_value); 451cb0ef41Sopenharmony_ci } else { 461cb0ef41Sopenharmony_ci value_range_ = 0; 471cb0ef41Sopenharmony_ci } 481cb0ef41Sopenharmony_ci } 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci std::vector<CaseInfo> CasesSortedByValue() const { 511cb0ef41Sopenharmony_ci std::vector<CaseInfo> result(cases_.begin(), cases_.end()); 521cb0ef41Sopenharmony_ci std::stable_sort(result.begin(), result.end(), 531cb0ef41Sopenharmony_ci [](CaseInfo a, CaseInfo b) { return a.value < b.value; }); 541cb0ef41Sopenharmony_ci return result; 551cb0ef41Sopenharmony_ci } 561cb0ef41Sopenharmony_ci const ZoneVector<CaseInfo>& CasesUnsorted() const { return cases_; } 571cb0ef41Sopenharmony_ci int32_t min_value() const { return min_value_; } 581cb0ef41Sopenharmony_ci int32_t max_value() const { return max_value_; } 591cb0ef41Sopenharmony_ci size_t value_range() const { return value_range_; } 601cb0ef41Sopenharmony_ci size_t case_count() const { return cases_.size(); } 611cb0ef41Sopenharmony_ci BasicBlock* default_branch() const { return default_branch_; } 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci private: 641cb0ef41Sopenharmony_ci const ZoneVector<CaseInfo>& cases_; 651cb0ef41Sopenharmony_ci int32_t min_value_; // minimum value of {cases_} 661cb0ef41Sopenharmony_ci int32_t max_value_; // maximum value of {cases_} 671cb0ef41Sopenharmony_ci size_t value_range_; // |max_value - min_value| + 1 681cb0ef41Sopenharmony_ci BasicBlock* default_branch_; 691cb0ef41Sopenharmony_ci}; 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci// A helper class for the instruction selector that simplifies construction of 721cb0ef41Sopenharmony_ci// Operands. This class implements a base for architecture-specific helpers. 731cb0ef41Sopenharmony_ciclass OperandGenerator { 741cb0ef41Sopenharmony_ci public: 751cb0ef41Sopenharmony_ci explicit OperandGenerator(InstructionSelector* selector) 761cb0ef41Sopenharmony_ci : selector_(selector) {} 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci InstructionOperand NoOutput() { 791cb0ef41Sopenharmony_ci return InstructionOperand(); // Generates an invalid operand. 801cb0ef41Sopenharmony_ci } 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci InstructionOperand DefineAsRegister(Node* node) { 831cb0ef41Sopenharmony_ci return Define(node, 841cb0ef41Sopenharmony_ci UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 851cb0ef41Sopenharmony_ci GetVReg(node))); 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci InstructionOperand DefineSameAsInput(Node* node, int input_index) { 891cb0ef41Sopenharmony_ci return Define(node, UnallocatedOperand(GetVReg(node), input_index)); 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci InstructionOperand DefineSameAsFirst(Node* node) { 931cb0ef41Sopenharmony_ci return DefineSameAsInput(node, 0); 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci InstructionOperand DefineAsFixed(Node* node, Register reg) { 971cb0ef41Sopenharmony_ci return Define(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 981cb0ef41Sopenharmony_ci reg.code(), GetVReg(node))); 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci template <typename FPRegType> 1021cb0ef41Sopenharmony_ci InstructionOperand DefineAsFixed(Node* node, FPRegType reg) { 1031cb0ef41Sopenharmony_ci return Define(node, 1041cb0ef41Sopenharmony_ci UnallocatedOperand(UnallocatedOperand::FIXED_FP_REGISTER, 1051cb0ef41Sopenharmony_ci reg.code(), GetVReg(node))); 1061cb0ef41Sopenharmony_ci } 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci InstructionOperand DefineAsConstant(Node* node) { 1091cb0ef41Sopenharmony_ci selector()->MarkAsDefined(node); 1101cb0ef41Sopenharmony_ci int virtual_register = GetVReg(node); 1111cb0ef41Sopenharmony_ci sequence()->AddConstant(virtual_register, ToConstant(node)); 1121cb0ef41Sopenharmony_ci return ConstantOperand(virtual_register); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci InstructionOperand DefineAsLocation(Node* node, LinkageLocation location) { 1161cb0ef41Sopenharmony_ci return Define(node, ToUnallocatedOperand(location, GetVReg(node))); 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci InstructionOperand DefineAsDualLocation(Node* node, 1201cb0ef41Sopenharmony_ci LinkageLocation primary_location, 1211cb0ef41Sopenharmony_ci LinkageLocation secondary_location) { 1221cb0ef41Sopenharmony_ci return Define(node, 1231cb0ef41Sopenharmony_ci ToDualLocationUnallocatedOperand( 1241cb0ef41Sopenharmony_ci primary_location, secondary_location, GetVReg(node))); 1251cb0ef41Sopenharmony_ci } 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci InstructionOperand Use(Node* node) { 1281cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand(UnallocatedOperand::NONE, 1291cb0ef41Sopenharmony_ci UnallocatedOperand::USED_AT_START, 1301cb0ef41Sopenharmony_ci GetVReg(node))); 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci InstructionOperand UseAnyAtEnd(Node* node) { 1341cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand(UnallocatedOperand::REGISTER_OR_SLOT, 1351cb0ef41Sopenharmony_ci UnallocatedOperand::USED_AT_END, 1361cb0ef41Sopenharmony_ci GetVReg(node))); 1371cb0ef41Sopenharmony_ci } 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci InstructionOperand UseAny(Node* node) { 1401cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand(UnallocatedOperand::REGISTER_OR_SLOT, 1411cb0ef41Sopenharmony_ci UnallocatedOperand::USED_AT_START, 1421cb0ef41Sopenharmony_ci GetVReg(node))); 1431cb0ef41Sopenharmony_ci } 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci InstructionOperand UseRegisterOrSlotOrConstant(Node* node) { 1461cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand( 1471cb0ef41Sopenharmony_ci UnallocatedOperand::REGISTER_OR_SLOT_OR_CONSTANT, 1481cb0ef41Sopenharmony_ci UnallocatedOperand::USED_AT_START, GetVReg(node))); 1491cb0ef41Sopenharmony_ci } 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci InstructionOperand UseUniqueRegisterOrSlotOrConstant(Node* node) { 1521cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand( 1531cb0ef41Sopenharmony_ci UnallocatedOperand::REGISTER_OR_SLOT_OR_CONSTANT, 1541cb0ef41Sopenharmony_ci GetVReg(node))); 1551cb0ef41Sopenharmony_ci } 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci InstructionOperand UseRegister(Node* node) { 1581cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 1591cb0ef41Sopenharmony_ci UnallocatedOperand::USED_AT_START, 1601cb0ef41Sopenharmony_ci GetVReg(node))); 1611cb0ef41Sopenharmony_ci } 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci InstructionOperand UseUniqueSlot(Node* node) { 1641cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_SLOT, 1651cb0ef41Sopenharmony_ci GetVReg(node))); 1661cb0ef41Sopenharmony_ci } 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci // Use register or operand for the node. If a register is chosen, it won't 1691cb0ef41Sopenharmony_ci // alias any temporary or output registers. 1701cb0ef41Sopenharmony_ci InstructionOperand UseUnique(Node* node) { 1711cb0ef41Sopenharmony_ci return Use(node, 1721cb0ef41Sopenharmony_ci UnallocatedOperand(UnallocatedOperand::NONE, GetVReg(node))); 1731cb0ef41Sopenharmony_ci } 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci // Use a unique register for the node that does not alias any temporary or 1761cb0ef41Sopenharmony_ci // output registers. 1771cb0ef41Sopenharmony_ci InstructionOperand UseUniqueRegister(Node* node) { 1781cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 1791cb0ef41Sopenharmony_ci GetVReg(node))); 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci enum class RegisterUseKind { kUseRegister, kUseUniqueRegister }; 1831cb0ef41Sopenharmony_ci InstructionOperand UseRegister(Node* node, RegisterUseKind unique_reg) { 1841cb0ef41Sopenharmony_ci if (V8_LIKELY(unique_reg == RegisterUseKind::kUseRegister)) { 1851cb0ef41Sopenharmony_ci return UseRegister(node); 1861cb0ef41Sopenharmony_ci } else { 1871cb0ef41Sopenharmony_ci DCHECK_EQ(unique_reg, RegisterUseKind::kUseUniqueRegister); 1881cb0ef41Sopenharmony_ci return UseUniqueRegister(node); 1891cb0ef41Sopenharmony_ci } 1901cb0ef41Sopenharmony_ci } 1911cb0ef41Sopenharmony_ci 1921cb0ef41Sopenharmony_ci InstructionOperand UseFixed(Node* node, Register reg) { 1931cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 1941cb0ef41Sopenharmony_ci reg.code(), GetVReg(node))); 1951cb0ef41Sopenharmony_ci } 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci template <typename FPRegType> 1981cb0ef41Sopenharmony_ci InstructionOperand UseFixed(Node* node, FPRegType reg) { 1991cb0ef41Sopenharmony_ci return Use(node, UnallocatedOperand(UnallocatedOperand::FIXED_FP_REGISTER, 2001cb0ef41Sopenharmony_ci reg.code(), GetVReg(node))); 2011cb0ef41Sopenharmony_ci } 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci InstructionOperand UseImmediate(int immediate) { 2041cb0ef41Sopenharmony_ci return sequence()->AddImmediate(Constant(immediate)); 2051cb0ef41Sopenharmony_ci } 2061cb0ef41Sopenharmony_ci 2071cb0ef41Sopenharmony_ci InstructionOperand UseImmediate64(int64_t immediate) { 2081cb0ef41Sopenharmony_ci return sequence()->AddImmediate(Constant(immediate)); 2091cb0ef41Sopenharmony_ci } 2101cb0ef41Sopenharmony_ci 2111cb0ef41Sopenharmony_ci InstructionOperand UseImmediate(Node* node) { 2121cb0ef41Sopenharmony_ci return sequence()->AddImmediate(ToConstant(node)); 2131cb0ef41Sopenharmony_ci } 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci InstructionOperand UseNegatedImmediate(Node* node) { 2161cb0ef41Sopenharmony_ci return sequence()->AddImmediate(ToNegatedConstant(node)); 2171cb0ef41Sopenharmony_ci } 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci InstructionOperand UseLocation(Node* node, LinkageLocation location) { 2201cb0ef41Sopenharmony_ci return Use(node, ToUnallocatedOperand(location, GetVReg(node))); 2211cb0ef41Sopenharmony_ci } 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci // Used to force gap moves from the from_location to the to_location 2241cb0ef41Sopenharmony_ci // immediately before an instruction. 2251cb0ef41Sopenharmony_ci InstructionOperand UsePointerLocation(LinkageLocation to_location, 2261cb0ef41Sopenharmony_ci LinkageLocation from_location) { 2271cb0ef41Sopenharmony_ci UnallocatedOperand casted_from_operand = 2281cb0ef41Sopenharmony_ci UnallocatedOperand::cast(TempLocation(from_location)); 2291cb0ef41Sopenharmony_ci selector_->Emit(kArchNop, casted_from_operand); 2301cb0ef41Sopenharmony_ci return ToUnallocatedOperand(to_location, 2311cb0ef41Sopenharmony_ci casted_from_operand.virtual_register()); 2321cb0ef41Sopenharmony_ci } 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci InstructionOperand TempRegister() { 2351cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 2361cb0ef41Sopenharmony_ci UnallocatedOperand::USED_AT_START, 2371cb0ef41Sopenharmony_ci sequence()->NextVirtualRegister()); 2381cb0ef41Sopenharmony_ci } 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ci int AllocateVirtualRegister() { return sequence()->NextVirtualRegister(); } 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci InstructionOperand DefineSameAsFirstForVreg(int vreg) { 2431cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::SAME_AS_INPUT, vreg); 2441cb0ef41Sopenharmony_ci } 2451cb0ef41Sopenharmony_ci 2461cb0ef41Sopenharmony_ci InstructionOperand DefineAsRegistertForVreg(int vreg) { 2471cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg); 2481cb0ef41Sopenharmony_ci } 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci InstructionOperand UseRegisterForVreg(int vreg) { 2511cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 2521cb0ef41Sopenharmony_ci UnallocatedOperand::USED_AT_START, vreg); 2531cb0ef41Sopenharmony_ci } 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci // The kind of register generated for memory operands. kRegister is alive 2561cb0ef41Sopenharmony_ci // until the start of the operation, kUniqueRegister until the end. 2571cb0ef41Sopenharmony_ci enum RegisterMode { 2581cb0ef41Sopenharmony_ci kRegister, 2591cb0ef41Sopenharmony_ci kUniqueRegister, 2601cb0ef41Sopenharmony_ci }; 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci InstructionOperand UseRegisterWithMode(Node* node, 2631cb0ef41Sopenharmony_ci RegisterMode register_mode) { 2641cb0ef41Sopenharmony_ci return register_mode == kRegister ? UseRegister(node) 2651cb0ef41Sopenharmony_ci : UseUniqueRegister(node); 2661cb0ef41Sopenharmony_ci } 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci InstructionOperand TempDoubleRegister() { 2691cb0ef41Sopenharmony_ci UnallocatedOperand op = UnallocatedOperand( 2701cb0ef41Sopenharmony_ci UnallocatedOperand::MUST_HAVE_REGISTER, 2711cb0ef41Sopenharmony_ci UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister()); 2721cb0ef41Sopenharmony_ci sequence()->MarkAsRepresentation(MachineRepresentation::kFloat64, 2731cb0ef41Sopenharmony_ci op.virtual_register()); 2741cb0ef41Sopenharmony_ci return op; 2751cb0ef41Sopenharmony_ci } 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci InstructionOperand TempSimd128Register() { 2781cb0ef41Sopenharmony_ci UnallocatedOperand op = UnallocatedOperand( 2791cb0ef41Sopenharmony_ci UnallocatedOperand::MUST_HAVE_REGISTER, 2801cb0ef41Sopenharmony_ci UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister()); 2811cb0ef41Sopenharmony_ci sequence()->MarkAsRepresentation(MachineRepresentation::kSimd128, 2821cb0ef41Sopenharmony_ci op.virtual_register()); 2831cb0ef41Sopenharmony_ci return op; 2841cb0ef41Sopenharmony_ci } 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci InstructionOperand TempRegister(Register reg) { 2871cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, reg.code(), 2881cb0ef41Sopenharmony_ci InstructionOperand::kInvalidVirtualRegister); 2891cb0ef41Sopenharmony_ci } 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_ci template <typename FPRegType> 2921cb0ef41Sopenharmony_ci InstructionOperand TempFpRegister(FPRegType reg) { 2931cb0ef41Sopenharmony_ci UnallocatedOperand op = 2941cb0ef41Sopenharmony_ci UnallocatedOperand(UnallocatedOperand::FIXED_FP_REGISTER, reg.code(), 2951cb0ef41Sopenharmony_ci sequence()->NextVirtualRegister()); 2961cb0ef41Sopenharmony_ci sequence()->MarkAsRepresentation(MachineRepresentation::kSimd128, 2971cb0ef41Sopenharmony_ci op.virtual_register()); 2981cb0ef41Sopenharmony_ci return op; 2991cb0ef41Sopenharmony_ci } 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_ci InstructionOperand TempImmediate(int32_t imm) { 3021cb0ef41Sopenharmony_ci return sequence()->AddImmediate(Constant(imm)); 3031cb0ef41Sopenharmony_ci } 3041cb0ef41Sopenharmony_ci 3051cb0ef41Sopenharmony_ci InstructionOperand TempLocation(LinkageLocation location) { 3061cb0ef41Sopenharmony_ci return ToUnallocatedOperand(location, sequence()->NextVirtualRegister()); 3071cb0ef41Sopenharmony_ci } 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci InstructionOperand Label(BasicBlock* block) { 3101cb0ef41Sopenharmony_ci return sequence()->AddImmediate( 3111cb0ef41Sopenharmony_ci Constant(RpoNumber::FromInt(block->rpo_number()))); 3121cb0ef41Sopenharmony_ci } 3131cb0ef41Sopenharmony_ci 3141cb0ef41Sopenharmony_ci protected: 3151cb0ef41Sopenharmony_ci InstructionSelector* selector() const { return selector_; } 3161cb0ef41Sopenharmony_ci InstructionSequence* sequence() const { return selector()->sequence(); } 3171cb0ef41Sopenharmony_ci Zone* zone() const { return selector()->instruction_zone(); } 3181cb0ef41Sopenharmony_ci 3191cb0ef41Sopenharmony_ci private: 3201cb0ef41Sopenharmony_ci int GetVReg(Node* node) const { return selector_->GetVirtualRegister(node); } 3211cb0ef41Sopenharmony_ci 3221cb0ef41Sopenharmony_ci static Constant ToConstant(const Node* node) { 3231cb0ef41Sopenharmony_ci switch (node->opcode()) { 3241cb0ef41Sopenharmony_ci case IrOpcode::kInt32Constant: 3251cb0ef41Sopenharmony_ci return Constant(OpParameter<int32_t>(node->op())); 3261cb0ef41Sopenharmony_ci case IrOpcode::kInt64Constant: 3271cb0ef41Sopenharmony_ci return Constant(OpParameter<int64_t>(node->op())); 3281cb0ef41Sopenharmony_ci case IrOpcode::kTaggedIndexConstant: { 3291cb0ef41Sopenharmony_ci // Unencoded index value. 3301cb0ef41Sopenharmony_ci intptr_t value = 3311cb0ef41Sopenharmony_ci static_cast<intptr_t>(OpParameter<int32_t>(node->op())); 3321cb0ef41Sopenharmony_ci DCHECK(TaggedIndex::IsValid(value)); 3331cb0ef41Sopenharmony_ci // Generate it as 32/64-bit constant in a tagged form. 3341cb0ef41Sopenharmony_ci Address tagged_index = TaggedIndex::FromIntptr(value).ptr(); 3351cb0ef41Sopenharmony_ci if (kSystemPointerSize == kInt32Size) { 3361cb0ef41Sopenharmony_ci return Constant(static_cast<int32_t>(tagged_index)); 3371cb0ef41Sopenharmony_ci } else { 3381cb0ef41Sopenharmony_ci return Constant(static_cast<int64_t>(tagged_index)); 3391cb0ef41Sopenharmony_ci } 3401cb0ef41Sopenharmony_ci } 3411cb0ef41Sopenharmony_ci case IrOpcode::kFloat32Constant: 3421cb0ef41Sopenharmony_ci return Constant(OpParameter<float>(node->op())); 3431cb0ef41Sopenharmony_ci case IrOpcode::kRelocatableInt32Constant: 3441cb0ef41Sopenharmony_ci case IrOpcode::kRelocatableInt64Constant: 3451cb0ef41Sopenharmony_ci return Constant(OpParameter<RelocatablePtrConstantInfo>(node->op())); 3461cb0ef41Sopenharmony_ci case IrOpcode::kFloat64Constant: 3471cb0ef41Sopenharmony_ci case IrOpcode::kNumberConstant: 3481cb0ef41Sopenharmony_ci return Constant(OpParameter<double>(node->op())); 3491cb0ef41Sopenharmony_ci case IrOpcode::kExternalConstant: 3501cb0ef41Sopenharmony_ci return Constant(OpParameter<ExternalReference>(node->op())); 3511cb0ef41Sopenharmony_ci case IrOpcode::kComment: { 3521cb0ef41Sopenharmony_ci // We cannot use {intptr_t} here, since the Constant constructor would 3531cb0ef41Sopenharmony_ci // be ambiguous on some architectures. 3541cb0ef41Sopenharmony_ci using ptrsize_int_t = 3551cb0ef41Sopenharmony_ci std::conditional<kSystemPointerSize == 8, int64_t, int32_t>::type; 3561cb0ef41Sopenharmony_ci return Constant(reinterpret_cast<ptrsize_int_t>( 3571cb0ef41Sopenharmony_ci OpParameter<const char*>(node->op()))); 3581cb0ef41Sopenharmony_ci } 3591cb0ef41Sopenharmony_ci case IrOpcode::kHeapConstant: 3601cb0ef41Sopenharmony_ci return Constant(HeapConstantOf(node->op())); 3611cb0ef41Sopenharmony_ci case IrOpcode::kCompressedHeapConstant: 3621cb0ef41Sopenharmony_ci return Constant(HeapConstantOf(node->op()), true); 3631cb0ef41Sopenharmony_ci case IrOpcode::kDelayedStringConstant: 3641cb0ef41Sopenharmony_ci return Constant(StringConstantBaseOf(node->op())); 3651cb0ef41Sopenharmony_ci case IrOpcode::kDeadValue: { 3661cb0ef41Sopenharmony_ci switch (DeadValueRepresentationOf(node->op())) { 3671cb0ef41Sopenharmony_ci case MachineRepresentation::kBit: 3681cb0ef41Sopenharmony_ci case MachineRepresentation::kWord32: 3691cb0ef41Sopenharmony_ci case MachineRepresentation::kTagged: 3701cb0ef41Sopenharmony_ci case MachineRepresentation::kTaggedSigned: 3711cb0ef41Sopenharmony_ci case MachineRepresentation::kTaggedPointer: 3721cb0ef41Sopenharmony_ci case MachineRepresentation::kCompressed: 3731cb0ef41Sopenharmony_ci case MachineRepresentation::kCompressedPointer: 3741cb0ef41Sopenharmony_ci return Constant(static_cast<int32_t>(0)); 3751cb0ef41Sopenharmony_ci case MachineRepresentation::kWord64: 3761cb0ef41Sopenharmony_ci return Constant(static_cast<int64_t>(0)); 3771cb0ef41Sopenharmony_ci case MachineRepresentation::kFloat64: 3781cb0ef41Sopenharmony_ci return Constant(static_cast<double>(0)); 3791cb0ef41Sopenharmony_ci case MachineRepresentation::kFloat32: 3801cb0ef41Sopenharmony_ci return Constant(static_cast<float>(0)); 3811cb0ef41Sopenharmony_ci default: 3821cb0ef41Sopenharmony_ci UNREACHABLE(); 3831cb0ef41Sopenharmony_ci } 3841cb0ef41Sopenharmony_ci break; 3851cb0ef41Sopenharmony_ci } 3861cb0ef41Sopenharmony_ci default: 3871cb0ef41Sopenharmony_ci break; 3881cb0ef41Sopenharmony_ci } 3891cb0ef41Sopenharmony_ci UNREACHABLE(); 3901cb0ef41Sopenharmony_ci } 3911cb0ef41Sopenharmony_ci 3921cb0ef41Sopenharmony_ci static Constant ToNegatedConstant(const Node* node) { 3931cb0ef41Sopenharmony_ci switch (node->opcode()) { 3941cb0ef41Sopenharmony_ci case IrOpcode::kInt32Constant: 3951cb0ef41Sopenharmony_ci return Constant(-OpParameter<int32_t>(node->op())); 3961cb0ef41Sopenharmony_ci case IrOpcode::kInt64Constant: 3971cb0ef41Sopenharmony_ci return Constant(-OpParameter<int64_t>(node->op())); 3981cb0ef41Sopenharmony_ci default: 3991cb0ef41Sopenharmony_ci break; 4001cb0ef41Sopenharmony_ci } 4011cb0ef41Sopenharmony_ci UNREACHABLE(); 4021cb0ef41Sopenharmony_ci } 4031cb0ef41Sopenharmony_ci 4041cb0ef41Sopenharmony_ci UnallocatedOperand Define(Node* node, UnallocatedOperand operand) { 4051cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(node); 4061cb0ef41Sopenharmony_ci DCHECK_EQ(operand.virtual_register(), GetVReg(node)); 4071cb0ef41Sopenharmony_ci selector()->MarkAsDefined(node); 4081cb0ef41Sopenharmony_ci return operand; 4091cb0ef41Sopenharmony_ci } 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ci UnallocatedOperand Use(Node* node, UnallocatedOperand operand) { 4121cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(node); 4131cb0ef41Sopenharmony_ci DCHECK_EQ(operand.virtual_register(), GetVReg(node)); 4141cb0ef41Sopenharmony_ci selector()->MarkAsUsed(node); 4151cb0ef41Sopenharmony_ci return operand; 4161cb0ef41Sopenharmony_ci } 4171cb0ef41Sopenharmony_ci 4181cb0ef41Sopenharmony_ci UnallocatedOperand ToDualLocationUnallocatedOperand( 4191cb0ef41Sopenharmony_ci LinkageLocation primary_location, LinkageLocation secondary_location, 4201cb0ef41Sopenharmony_ci int virtual_register) { 4211cb0ef41Sopenharmony_ci // We only support the primary location being a register and the secondary 4221cb0ef41Sopenharmony_ci // one a slot. 4231cb0ef41Sopenharmony_ci DCHECK(primary_location.IsRegister() && 4241cb0ef41Sopenharmony_ci secondary_location.IsCalleeFrameSlot()); 4251cb0ef41Sopenharmony_ci int reg_id = primary_location.AsRegister(); 4261cb0ef41Sopenharmony_ci int slot_id = secondary_location.AsCalleeFrameSlot(); 4271cb0ef41Sopenharmony_ci return UnallocatedOperand(reg_id, slot_id, virtual_register); 4281cb0ef41Sopenharmony_ci } 4291cb0ef41Sopenharmony_ci 4301cb0ef41Sopenharmony_ci UnallocatedOperand ToUnallocatedOperand(LinkageLocation location, 4311cb0ef41Sopenharmony_ci int virtual_register) { 4321cb0ef41Sopenharmony_ci if (location.IsAnyRegister()) { 4331cb0ef41Sopenharmony_ci // any machine register. 4341cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 4351cb0ef41Sopenharmony_ci virtual_register); 4361cb0ef41Sopenharmony_ci } 4371cb0ef41Sopenharmony_ci if (location.IsCallerFrameSlot()) { 4381cb0ef41Sopenharmony_ci // a location on the caller frame. 4391cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, 4401cb0ef41Sopenharmony_ci location.AsCallerFrameSlot(), virtual_register); 4411cb0ef41Sopenharmony_ci } 4421cb0ef41Sopenharmony_ci if (location.IsCalleeFrameSlot()) { 4431cb0ef41Sopenharmony_ci // a spill location on this (callee) frame. 4441cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, 4451cb0ef41Sopenharmony_ci location.AsCalleeFrameSlot(), virtual_register); 4461cb0ef41Sopenharmony_ci } 4471cb0ef41Sopenharmony_ci // a fixed register. 4481cb0ef41Sopenharmony_ci if (IsFloatingPoint(location.GetType().representation())) { 4491cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::FIXED_FP_REGISTER, 4501cb0ef41Sopenharmony_ci location.AsRegister(), virtual_register); 4511cb0ef41Sopenharmony_ci } 4521cb0ef41Sopenharmony_ci return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 4531cb0ef41Sopenharmony_ci location.AsRegister(), virtual_register); 4541cb0ef41Sopenharmony_ci } 4551cb0ef41Sopenharmony_ci 4561cb0ef41Sopenharmony_ci InstructionSelector* selector_; 4571cb0ef41Sopenharmony_ci}; 4581cb0ef41Sopenharmony_ci 4591cb0ef41Sopenharmony_ci} // namespace compiler 4601cb0ef41Sopenharmony_ci} // namespace internal 4611cb0ef41Sopenharmony_ci} // namespace v8 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_ci#endif // V8_COMPILER_BACKEND_INSTRUCTION_SELECTOR_IMPL_H_ 464