11cb0ef41Sopenharmony_ci// Copyright 2015 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#include "src/compiler/code-assembler.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <ostream>
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#include "src/base/bits.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h"
111cb0ef41Sopenharmony_ci#include "src/codegen/interface-descriptors-inl.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/machine-type.h"
131cb0ef41Sopenharmony_ci#include "src/codegen/macro-assembler.h"
141cb0ef41Sopenharmony_ci#include "src/compiler/backend/instruction-selector.h"
151cb0ef41Sopenharmony_ci#include "src/compiler/graph.h"
161cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h"
171cb0ef41Sopenharmony_ci#include "src/compiler/linkage.h"
181cb0ef41Sopenharmony_ci#include "src/compiler/node-matchers.h"
191cb0ef41Sopenharmony_ci#include "src/compiler/pipeline.h"
201cb0ef41Sopenharmony_ci#include "src/compiler/raw-machine-assembler.h"
211cb0ef41Sopenharmony_ci#include "src/compiler/schedule.h"
221cb0ef41Sopenharmony_ci#include "src/execution/frames.h"
231cb0ef41Sopenharmony_ci#include "src/handles/handles-inl.h"
241cb0ef41Sopenharmony_ci#include "src/heap/factory-inl.h"
251cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h"
261cb0ef41Sopenharmony_ci#include "src/numbers/conversions-inl.h"
271cb0ef41Sopenharmony_ci#include "src/objects/smi.h"
281cb0ef41Sopenharmony_ci#include "src/utils/memcopy.h"
291cb0ef41Sopenharmony_ci#include "src/zone/zone.h"
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_cinamespace v8 {
321cb0ef41Sopenharmony_cinamespace internal {
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciconstexpr MachineType MachineTypeOf<Smi>::value;
351cb0ef41Sopenharmony_ciconstexpr MachineType MachineTypeOf<Object>::value;
361cb0ef41Sopenharmony_ciconstexpr MachineType MachineTypeOf<MaybeObject>::value;
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_cinamespace compiler {
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_cistatic_assert(std::is_convertible<TNode<Number>, TNode<Object>>::value,
411cb0ef41Sopenharmony_ci              "test subtyping");
421cb0ef41Sopenharmony_cistatic_assert(
431cb0ef41Sopenharmony_ci    std::is_convertible<TNode<Number>, TNode<UnionT<Smi, HeapObject>>>::value,
441cb0ef41Sopenharmony_ci    "test subtyping");
451cb0ef41Sopenharmony_cistatic_assert(
461cb0ef41Sopenharmony_ci    !std::is_convertible<TNode<UnionT<Smi, HeapObject>>, TNode<Number>>::value,
471cb0ef41Sopenharmony_ci    "test subtyping");
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ciCodeAssemblerState::CodeAssemblerState(
501cb0ef41Sopenharmony_ci    Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
511cb0ef41Sopenharmony_ci    CodeKind kind, const char* name, Builtin builtin)
521cb0ef41Sopenharmony_ci    // TODO(rmcilroy): Should we use Linkage::GetBytecodeDispatchDescriptor for
531cb0ef41Sopenharmony_ci    // bytecode handlers?
541cb0ef41Sopenharmony_ci    : CodeAssemblerState(
551cb0ef41Sopenharmony_ci          isolate, zone,
561cb0ef41Sopenharmony_ci          Linkage::GetStubCallDescriptor(
571cb0ef41Sopenharmony_ci              zone, descriptor, descriptor.GetStackParameterCount(),
581cb0ef41Sopenharmony_ci              CallDescriptor::kNoFlags, Operator::kNoProperties),
591cb0ef41Sopenharmony_ci          kind, name, builtin) {}
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ciCodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone,
621cb0ef41Sopenharmony_ci                                       int parameter_count, CodeKind kind,
631cb0ef41Sopenharmony_ci                                       const char* name, Builtin builtin)
641cb0ef41Sopenharmony_ci    : CodeAssemblerState(
651cb0ef41Sopenharmony_ci          isolate, zone,
661cb0ef41Sopenharmony_ci          Linkage::GetJSCallDescriptor(zone, false, parameter_count,
671cb0ef41Sopenharmony_ci                                       CallDescriptor::kCanUseRoots),
681cb0ef41Sopenharmony_ci          kind, name, builtin) {}
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ciCodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone,
711cb0ef41Sopenharmony_ci                                       CallDescriptor* call_descriptor,
721cb0ef41Sopenharmony_ci                                       CodeKind kind, const char* name,
731cb0ef41Sopenharmony_ci                                       Builtin builtin)
741cb0ef41Sopenharmony_ci    : raw_assembler_(new RawMachineAssembler(
751cb0ef41Sopenharmony_ci          isolate, zone->New<Graph>(zone), call_descriptor,
761cb0ef41Sopenharmony_ci          MachineType::PointerRepresentation(),
771cb0ef41Sopenharmony_ci          InstructionSelector::SupportedMachineOperatorFlags(),
781cb0ef41Sopenharmony_ci          InstructionSelector::AlignmentRequirements())),
791cb0ef41Sopenharmony_ci      kind_(kind),
801cb0ef41Sopenharmony_ci      name_(name),
811cb0ef41Sopenharmony_ci      builtin_(builtin),
821cb0ef41Sopenharmony_ci      code_generated_(false),
831cb0ef41Sopenharmony_ci      variables_(zone),
841cb0ef41Sopenharmony_ci      jsgraph_(zone->New<JSGraph>(
851cb0ef41Sopenharmony_ci          isolate, raw_assembler_->graph(), raw_assembler_->common(),
861cb0ef41Sopenharmony_ci          zone->New<JSOperatorBuilder>(zone), raw_assembler_->simplified(),
871cb0ef41Sopenharmony_ci          raw_assembler_->machine())) {}
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ciCodeAssemblerState::~CodeAssemblerState() = default;
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ciint CodeAssemblerState::parameter_count() const {
921cb0ef41Sopenharmony_ci  return static_cast<int>(raw_assembler_->call_descriptor()->ParameterCount());
931cb0ef41Sopenharmony_ci}
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ciCodeAssembler::~CodeAssembler() = default;
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci#if DEBUG
981cb0ef41Sopenharmony_civoid CodeAssemblerState::PrintCurrentBlock(std::ostream& os) {
991cb0ef41Sopenharmony_ci  raw_assembler_->PrintCurrentBlock(os);
1001cb0ef41Sopenharmony_ci}
1011cb0ef41Sopenharmony_ci#endif
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_cibool CodeAssemblerState::InsideBlock() { return raw_assembler_->InsideBlock(); }
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_civoid CodeAssemblerState::SetInitialDebugInformation(const char* msg,
1061cb0ef41Sopenharmony_ci                                                    const char* file,
1071cb0ef41Sopenharmony_ci                                                    int line) {
1081cb0ef41Sopenharmony_ci#if DEBUG
1091cb0ef41Sopenharmony_ci  AssemblerDebugInfo debug_info = {msg, file, line};
1101cb0ef41Sopenharmony_ci  raw_assembler_->SetCurrentExternalSourcePosition({file, line});
1111cb0ef41Sopenharmony_ci  raw_assembler_->SetInitialDebugInformation(debug_info);
1121cb0ef41Sopenharmony_ci#endif  // DEBUG
1131cb0ef41Sopenharmony_ci}
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ciclass BreakOnNodeDecorator final : public GraphDecorator {
1161cb0ef41Sopenharmony_ci public:
1171cb0ef41Sopenharmony_ci  explicit BreakOnNodeDecorator(NodeId node_id) : node_id_(node_id) {}
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  void Decorate(Node* node) final {
1201cb0ef41Sopenharmony_ci    if (node->id() == node_id_) {
1211cb0ef41Sopenharmony_ci      base::OS::DebugBreak();
1221cb0ef41Sopenharmony_ci    }
1231cb0ef41Sopenharmony_ci  }
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci private:
1261cb0ef41Sopenharmony_ci  NodeId node_id_;
1271cb0ef41Sopenharmony_ci};
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_civoid CodeAssembler::BreakOnNode(int node_id) {
1301cb0ef41Sopenharmony_ci  Graph* graph = raw_assembler()->graph();
1311cb0ef41Sopenharmony_ci  Zone* zone = graph->zone();
1321cb0ef41Sopenharmony_ci  GraphDecorator* decorator =
1331cb0ef41Sopenharmony_ci      zone->New<BreakOnNodeDecorator>(static_cast<NodeId>(node_id));
1341cb0ef41Sopenharmony_ci  graph->AddDecorator(decorator);
1351cb0ef41Sopenharmony_ci}
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_civoid CodeAssembler::RegisterCallGenerationCallbacks(
1381cb0ef41Sopenharmony_ci    const CodeAssemblerCallback& call_prologue,
1391cb0ef41Sopenharmony_ci    const CodeAssemblerCallback& call_epilogue) {
1401cb0ef41Sopenharmony_ci  // The callback can be registered only once.
1411cb0ef41Sopenharmony_ci  DCHECK(!state_->call_prologue_);
1421cb0ef41Sopenharmony_ci  DCHECK(!state_->call_epilogue_);
1431cb0ef41Sopenharmony_ci  state_->call_prologue_ = call_prologue;
1441cb0ef41Sopenharmony_ci  state_->call_epilogue_ = call_epilogue;
1451cb0ef41Sopenharmony_ci}
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_civoid CodeAssembler::UnregisterCallGenerationCallbacks() {
1481cb0ef41Sopenharmony_ci  state_->call_prologue_ = nullptr;
1491cb0ef41Sopenharmony_ci  state_->call_epilogue_ = nullptr;
1501cb0ef41Sopenharmony_ci}
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_civoid CodeAssembler::CallPrologue() {
1531cb0ef41Sopenharmony_ci  if (state_->call_prologue_) {
1541cb0ef41Sopenharmony_ci    state_->call_prologue_();
1551cb0ef41Sopenharmony_ci  }
1561cb0ef41Sopenharmony_ci}
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_civoid CodeAssembler::CallEpilogue() {
1591cb0ef41Sopenharmony_ci  if (state_->call_epilogue_) {
1601cb0ef41Sopenharmony_ci    state_->call_epilogue_();
1611cb0ef41Sopenharmony_ci  }
1621cb0ef41Sopenharmony_ci}
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_cibool CodeAssembler::Word32ShiftIsSafe() const {
1651cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Word32ShiftIsSafe();
1661cb0ef41Sopenharmony_ci}
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci// static
1691cb0ef41Sopenharmony_ciHandle<Code> CodeAssembler::GenerateCode(
1701cb0ef41Sopenharmony_ci    CodeAssemblerState* state, const AssemblerOptions& options,
1711cb0ef41Sopenharmony_ci    const ProfileDataFromFile* profile_data) {
1721cb0ef41Sopenharmony_ci  DCHECK(!state->code_generated_);
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci  RawMachineAssembler* rasm = state->raw_assembler_.get();
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci  Handle<Code> code;
1771cb0ef41Sopenharmony_ci  Graph* graph = rasm->ExportForOptimization();
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci  code = Pipeline::GenerateCodeForCodeStub(
1801cb0ef41Sopenharmony_ci             rasm->isolate(), rasm->call_descriptor(), graph, state->jsgraph_,
1811cb0ef41Sopenharmony_ci             rasm->source_positions(), state->kind_, state->name_,
1821cb0ef41Sopenharmony_ci             state->builtin_, options, profile_data)
1831cb0ef41Sopenharmony_ci             .ToHandleChecked();
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  state->code_generated_ = true;
1861cb0ef41Sopenharmony_ci  return code;
1871cb0ef41Sopenharmony_ci}
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_cibool CodeAssembler::Is64() const { return raw_assembler()->machine()->Is64(); }
1901cb0ef41Sopenharmony_cibool CodeAssembler::Is32() const { return raw_assembler()->machine()->Is32(); }
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_cibool CodeAssembler::IsFloat64RoundUpSupported() const {
1931cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Float64RoundUp().IsSupported();
1941cb0ef41Sopenharmony_ci}
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_cibool CodeAssembler::IsFloat64RoundDownSupported() const {
1971cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Float64RoundDown().IsSupported();
1981cb0ef41Sopenharmony_ci}
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_cibool CodeAssembler::IsFloat64RoundTiesEvenSupported() const {
2011cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Float64RoundTiesEven().IsSupported();
2021cb0ef41Sopenharmony_ci}
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_cibool CodeAssembler::IsFloat64RoundTruncateSupported() const {
2051cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Float64RoundTruncate().IsSupported();
2061cb0ef41Sopenharmony_ci}
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_cibool CodeAssembler::IsInt32AbsWithOverflowSupported() const {
2091cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Int32AbsWithOverflow().IsSupported();
2101cb0ef41Sopenharmony_ci}
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_cibool CodeAssembler::IsInt64AbsWithOverflowSupported() const {
2131cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Int64AbsWithOverflow().IsSupported();
2141cb0ef41Sopenharmony_ci}
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_cibool CodeAssembler::IsIntPtrAbsWithOverflowSupported() const {
2171cb0ef41Sopenharmony_ci  return Is64() ? IsInt64AbsWithOverflowSupported()
2181cb0ef41Sopenharmony_ci                : IsInt32AbsWithOverflowSupported();
2191cb0ef41Sopenharmony_ci}
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_cibool CodeAssembler::IsWord32PopcntSupported() const {
2221cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Word32Popcnt().IsSupported();
2231cb0ef41Sopenharmony_ci}
2241cb0ef41Sopenharmony_ci
2251cb0ef41Sopenharmony_cibool CodeAssembler::IsWord64PopcntSupported() const {
2261cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Word64Popcnt().IsSupported();
2271cb0ef41Sopenharmony_ci}
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_cibool CodeAssembler::IsWord32CtzSupported() const {
2301cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Word32Ctz().IsSupported();
2311cb0ef41Sopenharmony_ci}
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_cibool CodeAssembler::IsWord64CtzSupported() const {
2341cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->Word64Ctz().IsSupported();
2351cb0ef41Sopenharmony_ci}
2361cb0ef41Sopenharmony_ci
2371cb0ef41Sopenharmony_ci#ifdef DEBUG
2381cb0ef41Sopenharmony_civoid CodeAssembler::GenerateCheckMaybeObjectIsObject(TNode<MaybeObject> node,
2391cb0ef41Sopenharmony_ci                                                     const char* location) {
2401cb0ef41Sopenharmony_ci  Label ok(this);
2411cb0ef41Sopenharmony_ci  GotoIf(WordNotEqual(WordAnd(BitcastMaybeObjectToWord(node),
2421cb0ef41Sopenharmony_ci                              IntPtrConstant(kHeapObjectTagMask)),
2431cb0ef41Sopenharmony_ci                      IntPtrConstant(kWeakHeapObjectTag)),
2441cb0ef41Sopenharmony_ci         &ok);
2451cb0ef41Sopenharmony_ci  base::EmbeddedVector<char, 1024> message;
2461cb0ef41Sopenharmony_ci  SNPrintF(message, "no Object: %s", location);
2471cb0ef41Sopenharmony_ci  TNode<String> message_node = StringConstant(message.begin());
2481cb0ef41Sopenharmony_ci  // This somewhat misuses the AbortCSADcheck runtime function. This will print
2491cb0ef41Sopenharmony_ci  // "abort: CSA_DCHECK failed: <message>", which is good enough.
2501cb0ef41Sopenharmony_ci  AbortCSADcheck(message_node);
2511cb0ef41Sopenharmony_ci  Unreachable();
2521cb0ef41Sopenharmony_ci  Bind(&ok);
2531cb0ef41Sopenharmony_ci}
2541cb0ef41Sopenharmony_ci#endif
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ciTNode<Int32T> CodeAssembler::Int32Constant(int32_t value) {
2571cb0ef41Sopenharmony_ci  return UncheckedCast<Int32T>(jsgraph()->Int32Constant(value));
2581cb0ef41Sopenharmony_ci}
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ciTNode<Int64T> CodeAssembler::Int64Constant(int64_t value) {
2611cb0ef41Sopenharmony_ci  return UncheckedCast<Int64T>(jsgraph()->Int64Constant(value));
2621cb0ef41Sopenharmony_ci}
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ciTNode<IntPtrT> CodeAssembler::IntPtrConstant(intptr_t value) {
2651cb0ef41Sopenharmony_ci  return UncheckedCast<IntPtrT>(jsgraph()->IntPtrConstant(value));
2661cb0ef41Sopenharmony_ci}
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ciTNode<TaggedIndex> CodeAssembler::TaggedIndexConstant(intptr_t value) {
2691cb0ef41Sopenharmony_ci  DCHECK(TaggedIndex::IsValid(value));
2701cb0ef41Sopenharmony_ci  return UncheckedCast<TaggedIndex>(raw_assembler()->IntPtrConstant(value));
2711cb0ef41Sopenharmony_ci}
2721cb0ef41Sopenharmony_ci
2731cb0ef41Sopenharmony_ciTNode<Number> CodeAssembler::NumberConstant(double value) {
2741cb0ef41Sopenharmony_ci  int smi_value;
2751cb0ef41Sopenharmony_ci  if (DoubleToSmiInteger(value, &smi_value)) {
2761cb0ef41Sopenharmony_ci    return UncheckedCast<Number>(SmiConstant(smi_value));
2771cb0ef41Sopenharmony_ci  } else {
2781cb0ef41Sopenharmony_ci    // We allocate the heap number constant eagerly at this point instead of
2791cb0ef41Sopenharmony_ci    // deferring allocation to code generation
2801cb0ef41Sopenharmony_ci    // (see AllocateAndInstallRequestedHeapObjects) since that makes it easier
2811cb0ef41Sopenharmony_ci    // to generate constant lookups for embedded builtins.
2821cb0ef41Sopenharmony_ci    return UncheckedCast<Number>(HeapConstant(
2831cb0ef41Sopenharmony_ci        isolate()->factory()->NewHeapNumberForCodeAssembler(value)));
2841cb0ef41Sopenharmony_ci  }
2851cb0ef41Sopenharmony_ci}
2861cb0ef41Sopenharmony_ci
2871cb0ef41Sopenharmony_ciTNode<Smi> CodeAssembler::SmiConstant(Smi value) {
2881cb0ef41Sopenharmony_ci  return UncheckedCast<Smi>(BitcastWordToTaggedSigned(
2891cb0ef41Sopenharmony_ci      IntPtrConstant(static_cast<intptr_t>(value.ptr()))));
2901cb0ef41Sopenharmony_ci}
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ciTNode<Smi> CodeAssembler::SmiConstant(int value) {
2931cb0ef41Sopenharmony_ci  return SmiConstant(Smi::FromInt(value));
2941cb0ef41Sopenharmony_ci}
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ciTNode<HeapObject> CodeAssembler::UntypedHeapConstant(
2971cb0ef41Sopenharmony_ci    Handle<HeapObject> object) {
2981cb0ef41Sopenharmony_ci  return UncheckedCast<HeapObject>(jsgraph()->HeapConstant(object));
2991cb0ef41Sopenharmony_ci}
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ciTNode<String> CodeAssembler::StringConstant(const char* str) {
3021cb0ef41Sopenharmony_ci  Handle<String> internalized_string =
3031cb0ef41Sopenharmony_ci      factory()->InternalizeString(base::OneByteVector(str));
3041cb0ef41Sopenharmony_ci  return UncheckedCast<String>(HeapConstant(internalized_string));
3051cb0ef41Sopenharmony_ci}
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ciTNode<Oddball> CodeAssembler::BooleanConstant(bool value) {
3081cb0ef41Sopenharmony_ci  Handle<Object> object = isolate()->factory()->ToBoolean(value);
3091cb0ef41Sopenharmony_ci  return UncheckedCast<Oddball>(
3101cb0ef41Sopenharmony_ci      jsgraph()->HeapConstant(Handle<HeapObject>::cast(object)));
3111cb0ef41Sopenharmony_ci}
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ciTNode<ExternalReference> CodeAssembler::ExternalConstant(
3141cb0ef41Sopenharmony_ci    ExternalReference address) {
3151cb0ef41Sopenharmony_ci  return UncheckedCast<ExternalReference>(
3161cb0ef41Sopenharmony_ci      raw_assembler()->ExternalConstant(address));
3171cb0ef41Sopenharmony_ci}
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_ciTNode<Float32T> CodeAssembler::Float32Constant(double value) {
3201cb0ef41Sopenharmony_ci  return UncheckedCast<Float32T>(jsgraph()->Float32Constant(value));
3211cb0ef41Sopenharmony_ci}
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ciTNode<Float64T> CodeAssembler::Float64Constant(double value) {
3241cb0ef41Sopenharmony_ci  return UncheckedCast<Float64T>(jsgraph()->Float64Constant(value));
3251cb0ef41Sopenharmony_ci}
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_cibool CodeAssembler::IsMapOffsetConstant(Node* node) {
3281cb0ef41Sopenharmony_ci  return raw_assembler()->IsMapOffsetConstant(node);
3291cb0ef41Sopenharmony_ci}
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_cibool CodeAssembler::TryToInt32Constant(TNode<IntegralT> node,
3321cb0ef41Sopenharmony_ci                                       int32_t* out_value) {
3331cb0ef41Sopenharmony_ci  {
3341cb0ef41Sopenharmony_ci    Int64Matcher m(node);
3351cb0ef41Sopenharmony_ci    if (m.HasResolvedValue() &&
3361cb0ef41Sopenharmony_ci        m.IsInRange(std::numeric_limits<int32_t>::min(),
3371cb0ef41Sopenharmony_ci                    std::numeric_limits<int32_t>::max())) {
3381cb0ef41Sopenharmony_ci      *out_value = static_cast<int32_t>(m.ResolvedValue());
3391cb0ef41Sopenharmony_ci      return true;
3401cb0ef41Sopenharmony_ci    }
3411cb0ef41Sopenharmony_ci  }
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci  {
3441cb0ef41Sopenharmony_ci    Int32Matcher m(node);
3451cb0ef41Sopenharmony_ci    if (m.HasResolvedValue()) {
3461cb0ef41Sopenharmony_ci      *out_value = m.ResolvedValue();
3471cb0ef41Sopenharmony_ci      return true;
3481cb0ef41Sopenharmony_ci    }
3491cb0ef41Sopenharmony_ci  }
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ci  return false;
3521cb0ef41Sopenharmony_ci}
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_cibool CodeAssembler::TryToInt64Constant(TNode<IntegralT> node,
3551cb0ef41Sopenharmony_ci                                       int64_t* out_value) {
3561cb0ef41Sopenharmony_ci  Int64Matcher m(node);
3571cb0ef41Sopenharmony_ci  if (m.HasResolvedValue()) *out_value = m.ResolvedValue();
3581cb0ef41Sopenharmony_ci  return m.HasResolvedValue();
3591cb0ef41Sopenharmony_ci}
3601cb0ef41Sopenharmony_ci
3611cb0ef41Sopenharmony_cibool CodeAssembler::TryToSmiConstant(TNode<Smi> tnode, Smi* out_value) {
3621cb0ef41Sopenharmony_ci  Node* node = tnode;
3631cb0ef41Sopenharmony_ci  if (node->opcode() == IrOpcode::kBitcastWordToTaggedSigned) {
3641cb0ef41Sopenharmony_ci    node = node->InputAt(0);
3651cb0ef41Sopenharmony_ci  }
3661cb0ef41Sopenharmony_ci  return TryToSmiConstant(ReinterpretCast<IntPtrT>(tnode), out_value);
3671cb0ef41Sopenharmony_ci}
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_cibool CodeAssembler::TryToSmiConstant(TNode<IntegralT> node, Smi* out_value) {
3701cb0ef41Sopenharmony_ci  IntPtrMatcher m(node);
3711cb0ef41Sopenharmony_ci  if (m.HasResolvedValue()) {
3721cb0ef41Sopenharmony_ci    intptr_t value = m.ResolvedValue();
3731cb0ef41Sopenharmony_ci    // Make sure that the value is actually a smi
3741cb0ef41Sopenharmony_ci    CHECK_EQ(0, value & ((static_cast<intptr_t>(1) << kSmiShiftSize) - 1));
3751cb0ef41Sopenharmony_ci    *out_value = Smi(static_cast<Address>(value));
3761cb0ef41Sopenharmony_ci    return true;
3771cb0ef41Sopenharmony_ci  }
3781cb0ef41Sopenharmony_ci  return false;
3791cb0ef41Sopenharmony_ci}
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_cibool CodeAssembler::TryToIntPtrConstant(TNode<Smi> tnode, intptr_t* out_value) {
3821cb0ef41Sopenharmony_ci  Node* node = tnode;
3831cb0ef41Sopenharmony_ci  if (node->opcode() == IrOpcode::kBitcastWordToTaggedSigned ||
3841cb0ef41Sopenharmony_ci      node->opcode() == IrOpcode::kBitcastWordToTagged) {
3851cb0ef41Sopenharmony_ci    node = node->InputAt(0);
3861cb0ef41Sopenharmony_ci  }
3871cb0ef41Sopenharmony_ci  return TryToIntPtrConstant(ReinterpretCast<IntPtrT>(tnode), out_value);
3881cb0ef41Sopenharmony_ci}
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_cibool CodeAssembler::TryToIntPtrConstant(TNode<IntegralT> node,
3911cb0ef41Sopenharmony_ci                                        intptr_t* out_value) {
3921cb0ef41Sopenharmony_ci  IntPtrMatcher m(node);
3931cb0ef41Sopenharmony_ci  if (m.HasResolvedValue()) *out_value = m.ResolvedValue();
3941cb0ef41Sopenharmony_ci  return m.HasResolvedValue();
3951cb0ef41Sopenharmony_ci}
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_cibool CodeAssembler::IsUndefinedConstant(TNode<Object> node) {
3981cb0ef41Sopenharmony_ci  compiler::HeapObjectMatcher m(node);
3991cb0ef41Sopenharmony_ci  return m.Is(isolate()->factory()->undefined_value());
4001cb0ef41Sopenharmony_ci}
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_cibool CodeAssembler::IsNullConstant(TNode<Object> node) {
4031cb0ef41Sopenharmony_ci  compiler::HeapObjectMatcher m(node);
4041cb0ef41Sopenharmony_ci  return m.Is(isolate()->factory()->null_value());
4051cb0ef41Sopenharmony_ci}
4061cb0ef41Sopenharmony_ci
4071cb0ef41Sopenharmony_ciNode* CodeAssembler::UntypedParameter(int index) {
4081cb0ef41Sopenharmony_ci  if (index == kTargetParameterIndex) return raw_assembler()->TargetParameter();
4091cb0ef41Sopenharmony_ci  return raw_assembler()->Parameter(index);
4101cb0ef41Sopenharmony_ci}
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_cibool CodeAssembler::IsJSFunctionCall() const {
4131cb0ef41Sopenharmony_ci  auto call_descriptor = raw_assembler()->call_descriptor();
4141cb0ef41Sopenharmony_ci  return call_descriptor->IsJSFunctionCall();
4151cb0ef41Sopenharmony_ci}
4161cb0ef41Sopenharmony_ci
4171cb0ef41Sopenharmony_ciTNode<Context> CodeAssembler::GetJSContextParameter() {
4181cb0ef41Sopenharmony_ci  auto call_descriptor = raw_assembler()->call_descriptor();
4191cb0ef41Sopenharmony_ci  DCHECK(call_descriptor->IsJSFunctionCall());
4201cb0ef41Sopenharmony_ci  return Parameter<Context>(Linkage::GetJSCallContextParamIndex(
4211cb0ef41Sopenharmony_ci      static_cast<int>(call_descriptor->JSParameterCount())));
4221cb0ef41Sopenharmony_ci}
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<Object> value) {
4251cb0ef41Sopenharmony_ci  DCHECK_EQ(1, raw_assembler()->call_descriptor()->ReturnCount());
4261cb0ef41Sopenharmony_ci  DCHECK(raw_assembler()->call_descriptor()->GetReturnType(0).IsTagged());
4271cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value);
4281cb0ef41Sopenharmony_ci}
4291cb0ef41Sopenharmony_ci
4301cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<Object> value1, TNode<Object> value2) {
4311cb0ef41Sopenharmony_ci  DCHECK_EQ(2, raw_assembler()->call_descriptor()->ReturnCount());
4321cb0ef41Sopenharmony_ci  DCHECK(raw_assembler()->call_descriptor()->GetReturnType(0).IsTagged());
4331cb0ef41Sopenharmony_ci  DCHECK(raw_assembler()->call_descriptor()->GetReturnType(1).IsTagged());
4341cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value1, value2);
4351cb0ef41Sopenharmony_ci}
4361cb0ef41Sopenharmony_ci
4371cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<Object> value1, TNode<Object> value2,
4381cb0ef41Sopenharmony_ci                           TNode<Object> value3) {
4391cb0ef41Sopenharmony_ci  DCHECK_EQ(3, raw_assembler()->call_descriptor()->ReturnCount());
4401cb0ef41Sopenharmony_ci  DCHECK(raw_assembler()->call_descriptor()->GetReturnType(0).IsTagged());
4411cb0ef41Sopenharmony_ci  DCHECK(raw_assembler()->call_descriptor()->GetReturnType(1).IsTagged());
4421cb0ef41Sopenharmony_ci  DCHECK(raw_assembler()->call_descriptor()->GetReturnType(2).IsTagged());
4431cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value1, value2, value3);
4441cb0ef41Sopenharmony_ci}
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<Int32T> value) {
4471cb0ef41Sopenharmony_ci  DCHECK_EQ(1, raw_assembler()->call_descriptor()->ReturnCount());
4481cb0ef41Sopenharmony_ci  DCHECK_EQ(MachineType::Int32(),
4491cb0ef41Sopenharmony_ci            raw_assembler()->call_descriptor()->GetReturnType(0));
4501cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value);
4511cb0ef41Sopenharmony_ci}
4521cb0ef41Sopenharmony_ci
4531cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<Uint32T> value) {
4541cb0ef41Sopenharmony_ci  DCHECK_EQ(1, raw_assembler()->call_descriptor()->ReturnCount());
4551cb0ef41Sopenharmony_ci  DCHECK_EQ(MachineType::Uint32(),
4561cb0ef41Sopenharmony_ci            raw_assembler()->call_descriptor()->GetReturnType(0));
4571cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value);
4581cb0ef41Sopenharmony_ci}
4591cb0ef41Sopenharmony_ci
4601cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<WordT> value) {
4611cb0ef41Sopenharmony_ci  DCHECK_EQ(1, raw_assembler()->call_descriptor()->ReturnCount());
4621cb0ef41Sopenharmony_ci  DCHECK_EQ(
4631cb0ef41Sopenharmony_ci      MachineType::PointerRepresentation(),
4641cb0ef41Sopenharmony_ci      raw_assembler()->call_descriptor()->GetReturnType(0).representation());
4651cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value);
4661cb0ef41Sopenharmony_ci}
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<Float32T> value) {
4691cb0ef41Sopenharmony_ci  DCHECK_EQ(1, raw_assembler()->call_descriptor()->ReturnCount());
4701cb0ef41Sopenharmony_ci  DCHECK_EQ(MachineType::Float32(),
4711cb0ef41Sopenharmony_ci            raw_assembler()->call_descriptor()->GetReturnType(0));
4721cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value);
4731cb0ef41Sopenharmony_ci}
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<Float64T> value) {
4761cb0ef41Sopenharmony_ci  DCHECK_EQ(1, raw_assembler()->call_descriptor()->ReturnCount());
4771cb0ef41Sopenharmony_ci  DCHECK_EQ(MachineType::Float64(),
4781cb0ef41Sopenharmony_ci            raw_assembler()->call_descriptor()->GetReturnType(0));
4791cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value);
4801cb0ef41Sopenharmony_ci}
4811cb0ef41Sopenharmony_ci
4821cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<WordT> value1, TNode<WordT> value2) {
4831cb0ef41Sopenharmony_ci  DCHECK_EQ(2, raw_assembler()->call_descriptor()->ReturnCount());
4841cb0ef41Sopenharmony_ci  DCHECK_EQ(
4851cb0ef41Sopenharmony_ci      MachineType::PointerRepresentation(),
4861cb0ef41Sopenharmony_ci      raw_assembler()->call_descriptor()->GetReturnType(0).representation());
4871cb0ef41Sopenharmony_ci  DCHECK_EQ(
4881cb0ef41Sopenharmony_ci      MachineType::PointerRepresentation(),
4891cb0ef41Sopenharmony_ci      raw_assembler()->call_descriptor()->GetReturnType(1).representation());
4901cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value1, value2);
4911cb0ef41Sopenharmony_ci}
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_civoid CodeAssembler::Return(TNode<WordT> value1, TNode<Object> value2) {
4941cb0ef41Sopenharmony_ci  DCHECK_EQ(2, raw_assembler()->call_descriptor()->ReturnCount());
4951cb0ef41Sopenharmony_ci  DCHECK_EQ(
4961cb0ef41Sopenharmony_ci      MachineType::PointerRepresentation(),
4971cb0ef41Sopenharmony_ci      raw_assembler()->call_descriptor()->GetReturnType(0).representation());
4981cb0ef41Sopenharmony_ci  DCHECK(raw_assembler()->call_descriptor()->GetReturnType(1).IsTagged());
4991cb0ef41Sopenharmony_ci  return raw_assembler()->Return(value1, value2);
5001cb0ef41Sopenharmony_ci}
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_civoid CodeAssembler::PopAndReturn(Node* pop, Node* value) {
5031cb0ef41Sopenharmony_ci  DCHECK_EQ(1, raw_assembler()->call_descriptor()->ReturnCount());
5041cb0ef41Sopenharmony_ci  return raw_assembler()->PopAndReturn(pop, value);
5051cb0ef41Sopenharmony_ci}
5061cb0ef41Sopenharmony_ci
5071cb0ef41Sopenharmony_civoid CodeAssembler::ReturnIf(TNode<BoolT> condition, TNode<Object> value) {
5081cb0ef41Sopenharmony_ci  Label if_return(this), if_continue(this);
5091cb0ef41Sopenharmony_ci  Branch(condition, &if_return, &if_continue);
5101cb0ef41Sopenharmony_ci  Bind(&if_return);
5111cb0ef41Sopenharmony_ci  Return(value);
5121cb0ef41Sopenharmony_ci  Bind(&if_continue);
5131cb0ef41Sopenharmony_ci}
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_civoid CodeAssembler::AbortCSADcheck(Node* message) {
5161cb0ef41Sopenharmony_ci  raw_assembler()->AbortCSADcheck(message);
5171cb0ef41Sopenharmony_ci}
5181cb0ef41Sopenharmony_ci
5191cb0ef41Sopenharmony_civoid CodeAssembler::DebugBreak() { raw_assembler()->DebugBreak(); }
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_civoid CodeAssembler::Unreachable() {
5221cb0ef41Sopenharmony_ci  DebugBreak();
5231cb0ef41Sopenharmony_ci  raw_assembler()->Unreachable();
5241cb0ef41Sopenharmony_ci}
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_civoid CodeAssembler::Comment(std::string str) {
5271cb0ef41Sopenharmony_ci  if (!FLAG_code_comments) return;
5281cb0ef41Sopenharmony_ci  raw_assembler()->Comment(str);
5291cb0ef41Sopenharmony_ci}
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_civoid CodeAssembler::StaticAssert(TNode<BoolT> value, const char* source) {
5321cb0ef41Sopenharmony_ci  raw_assembler()->StaticAssert(value, source);
5331cb0ef41Sopenharmony_ci}
5341cb0ef41Sopenharmony_ci
5351cb0ef41Sopenharmony_civoid CodeAssembler::SetSourcePosition(const char* file, int line) {
5361cb0ef41Sopenharmony_ci  raw_assembler()->SetCurrentExternalSourcePosition({file, line});
5371cb0ef41Sopenharmony_ci}
5381cb0ef41Sopenharmony_ci
5391cb0ef41Sopenharmony_civoid CodeAssembler::PushSourcePosition() {
5401cb0ef41Sopenharmony_ci  auto position = raw_assembler()->GetCurrentExternalSourcePosition();
5411cb0ef41Sopenharmony_ci  state_->macro_call_stack_.push_back(position);
5421cb0ef41Sopenharmony_ci}
5431cb0ef41Sopenharmony_ci
5441cb0ef41Sopenharmony_civoid CodeAssembler::PopSourcePosition() {
5451cb0ef41Sopenharmony_ci  state_->macro_call_stack_.pop_back();
5461cb0ef41Sopenharmony_ci}
5471cb0ef41Sopenharmony_ci
5481cb0ef41Sopenharmony_ciconst std::vector<FileAndLine>& CodeAssembler::GetMacroSourcePositionStack()
5491cb0ef41Sopenharmony_ci    const {
5501cb0ef41Sopenharmony_ci  return state_->macro_call_stack_;
5511cb0ef41Sopenharmony_ci}
5521cb0ef41Sopenharmony_ci
5531cb0ef41Sopenharmony_civoid CodeAssembler::Bind(Label* label) { return label->Bind(); }
5541cb0ef41Sopenharmony_ci
5551cb0ef41Sopenharmony_ci#if DEBUG
5561cb0ef41Sopenharmony_civoid CodeAssembler::Bind(Label* label, AssemblerDebugInfo debug_info) {
5571cb0ef41Sopenharmony_ci  return label->Bind(debug_info);
5581cb0ef41Sopenharmony_ci}
5591cb0ef41Sopenharmony_ci#endif  // DEBUG
5601cb0ef41Sopenharmony_ci
5611cb0ef41Sopenharmony_ciTNode<RawPtrT> CodeAssembler::LoadFramePointer() {
5621cb0ef41Sopenharmony_ci  return UncheckedCast<RawPtrT>(raw_assembler()->LoadFramePointer());
5631cb0ef41Sopenharmony_ci}
5641cb0ef41Sopenharmony_ci
5651cb0ef41Sopenharmony_ciTNode<RawPtrT> CodeAssembler::LoadParentFramePointer() {
5661cb0ef41Sopenharmony_ci  return UncheckedCast<RawPtrT>(raw_assembler()->LoadParentFramePointer());
5671cb0ef41Sopenharmony_ci}
5681cb0ef41Sopenharmony_ci
5691cb0ef41Sopenharmony_ci#define DEFINE_CODE_ASSEMBLER_BINARY_OP(name, ResType, Arg1Type, Arg2Type)   \
5701cb0ef41Sopenharmony_ci  TNode<ResType> CodeAssembler::name(TNode<Arg1Type> a, TNode<Arg2Type> b) { \
5711cb0ef41Sopenharmony_ci    return UncheckedCast<ResType>(raw_assembler()->name(a, b));              \
5721cb0ef41Sopenharmony_ci  }
5731cb0ef41Sopenharmony_ciCODE_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_ASSEMBLER_BINARY_OP)
5741cb0ef41Sopenharmony_ci#undef DEFINE_CODE_ASSEMBLER_BINARY_OP
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ciTNode<WordT> CodeAssembler::WordShl(TNode<WordT> value, int shift) {
5771cb0ef41Sopenharmony_ci  return (shift != 0) ? WordShl(value, IntPtrConstant(shift)) : value;
5781cb0ef41Sopenharmony_ci}
5791cb0ef41Sopenharmony_ci
5801cb0ef41Sopenharmony_ciTNode<WordT> CodeAssembler::WordShr(TNode<WordT> value, int shift) {
5811cb0ef41Sopenharmony_ci  return (shift != 0) ? WordShr(value, IntPtrConstant(shift)) : value;
5821cb0ef41Sopenharmony_ci}
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ciTNode<WordT> CodeAssembler::WordSar(TNode<WordT> value, int shift) {
5851cb0ef41Sopenharmony_ci  return (shift != 0) ? WordSar(value, IntPtrConstant(shift)) : value;
5861cb0ef41Sopenharmony_ci}
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ciTNode<Word32T> CodeAssembler::Word32Shr(TNode<Word32T> value, int shift) {
5891cb0ef41Sopenharmony_ci  return (shift != 0) ? Word32Shr(value, Int32Constant(shift)) : value;
5901cb0ef41Sopenharmony_ci}
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_ciTNode<Word32T> CodeAssembler::Word32Sar(TNode<Word32T> value, int shift) {
5931cb0ef41Sopenharmony_ci  return (shift != 0) ? Word32Sar(value, Int32Constant(shift)) : value;
5941cb0ef41Sopenharmony_ci}
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_ci#define CODE_ASSEMBLER_COMPARE(Name, ArgT, VarT, ToConstant, op)          \
5971cb0ef41Sopenharmony_ci  TNode<BoolT> CodeAssembler::Name(TNode<ArgT> left, TNode<ArgT> right) { \
5981cb0ef41Sopenharmony_ci    VarT lhs, rhs;                                                        \
5991cb0ef41Sopenharmony_ci    if (ToConstant(left, &lhs) && ToConstant(right, &rhs)) {              \
6001cb0ef41Sopenharmony_ci      return BoolConstant(lhs op rhs);                                    \
6011cb0ef41Sopenharmony_ci    }                                                                     \
6021cb0ef41Sopenharmony_ci    return UncheckedCast<BoolT>(raw_assembler()->Name(left, right));      \
6031cb0ef41Sopenharmony_ci  }
6041cb0ef41Sopenharmony_ci
6051cb0ef41Sopenharmony_ciCODE_ASSEMBLER_COMPARE(IntPtrEqual, WordT, intptr_t, TryToIntPtrConstant, ==)
6061cb0ef41Sopenharmony_ciCODE_ASSEMBLER_COMPARE(WordEqual, WordT, intptr_t, TryToIntPtrConstant, ==)
6071cb0ef41Sopenharmony_ciCODE_ASSEMBLER_COMPARE(WordNotEqual, WordT, intptr_t, TryToIntPtrConstant, !=)
6081cb0ef41Sopenharmony_ciCODE_ASSEMBLER_COMPARE(Word32Equal, Word32T, int32_t, TryToInt32Constant, ==)
6091cb0ef41Sopenharmony_ciCODE_ASSEMBLER_COMPARE(Word32NotEqual, Word32T, int32_t, TryToInt32Constant, !=)
6101cb0ef41Sopenharmony_ciCODE_ASSEMBLER_COMPARE(Word64Equal, Word64T, int64_t, TryToInt64Constant, ==)
6111cb0ef41Sopenharmony_ciCODE_ASSEMBLER_COMPARE(Word64NotEqual, Word64T, int64_t, TryToInt64Constant, !=)
6121cb0ef41Sopenharmony_ci#undef CODE_ASSEMBLER_COMPARE
6131cb0ef41Sopenharmony_ci
6141cb0ef41Sopenharmony_ciTNode<UintPtrT> CodeAssembler::ChangeUint32ToWord(TNode<Word32T> value) {
6151cb0ef41Sopenharmony_ci  if (raw_assembler()->machine()->Is64()) {
6161cb0ef41Sopenharmony_ci    return UncheckedCast<UintPtrT>(
6171cb0ef41Sopenharmony_ci        raw_assembler()->ChangeUint32ToUint64(value));
6181cb0ef41Sopenharmony_ci  }
6191cb0ef41Sopenharmony_ci  return ReinterpretCast<UintPtrT>(value);
6201cb0ef41Sopenharmony_ci}
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ciTNode<IntPtrT> CodeAssembler::ChangeInt32ToIntPtr(TNode<Word32T> value) {
6231cb0ef41Sopenharmony_ci  if (raw_assembler()->machine()->Is64()) {
6241cb0ef41Sopenharmony_ci    return UncheckedCast<IntPtrT>(raw_assembler()->ChangeInt32ToInt64(value));
6251cb0ef41Sopenharmony_ci  }
6261cb0ef41Sopenharmony_ci  return ReinterpretCast<IntPtrT>(value);
6271cb0ef41Sopenharmony_ci}
6281cb0ef41Sopenharmony_ci
6291cb0ef41Sopenharmony_ciTNode<IntPtrT> CodeAssembler::ChangeFloat64ToIntPtr(TNode<Float64T> value) {
6301cb0ef41Sopenharmony_ci  if (raw_assembler()->machine()->Is64()) {
6311cb0ef41Sopenharmony_ci    return UncheckedCast<IntPtrT>(raw_assembler()->ChangeFloat64ToInt64(value));
6321cb0ef41Sopenharmony_ci  }
6331cb0ef41Sopenharmony_ci  return UncheckedCast<IntPtrT>(raw_assembler()->ChangeFloat64ToInt32(value));
6341cb0ef41Sopenharmony_ci}
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ciTNode<UintPtrT> CodeAssembler::ChangeFloat64ToUintPtr(TNode<Float64T> value) {
6371cb0ef41Sopenharmony_ci  if (raw_assembler()->machine()->Is64()) {
6381cb0ef41Sopenharmony_ci    return UncheckedCast<UintPtrT>(
6391cb0ef41Sopenharmony_ci        raw_assembler()->ChangeFloat64ToUint64(value));
6401cb0ef41Sopenharmony_ci  }
6411cb0ef41Sopenharmony_ci  return UncheckedCast<UintPtrT>(raw_assembler()->ChangeFloat64ToUint32(value));
6421cb0ef41Sopenharmony_ci}
6431cb0ef41Sopenharmony_ci
6441cb0ef41Sopenharmony_ciTNode<Float64T> CodeAssembler::ChangeUintPtrToFloat64(TNode<UintPtrT> value) {
6451cb0ef41Sopenharmony_ci  if (raw_assembler()->machine()->Is64()) {
6461cb0ef41Sopenharmony_ci    // TODO(turbofan): Maybe we should introduce a ChangeUint64ToFloat64
6471cb0ef41Sopenharmony_ci    // machine operator to TurboFan here?
6481cb0ef41Sopenharmony_ci    return UncheckedCast<Float64T>(
6491cb0ef41Sopenharmony_ci        raw_assembler()->RoundUint64ToFloat64(value));
6501cb0ef41Sopenharmony_ci  }
6511cb0ef41Sopenharmony_ci  return UncheckedCast<Float64T>(raw_assembler()->ChangeUint32ToFloat64(value));
6521cb0ef41Sopenharmony_ci}
6531cb0ef41Sopenharmony_ci
6541cb0ef41Sopenharmony_ciTNode<Float64T> CodeAssembler::RoundIntPtrToFloat64(Node* value) {
6551cb0ef41Sopenharmony_ci  if (raw_assembler()->machine()->Is64()) {
6561cb0ef41Sopenharmony_ci    return UncheckedCast<Float64T>(raw_assembler()->RoundInt64ToFloat64(value));
6571cb0ef41Sopenharmony_ci  }
6581cb0ef41Sopenharmony_ci  return UncheckedCast<Float64T>(raw_assembler()->ChangeInt32ToFloat64(value));
6591cb0ef41Sopenharmony_ci}
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ciTNode<Int32T> CodeAssembler::TruncateFloat32ToInt32(TNode<Float32T> value) {
6621cb0ef41Sopenharmony_ci  return UncheckedCast<Int32T>(raw_assembler()->TruncateFloat32ToInt32(
6631cb0ef41Sopenharmony_ci      value, TruncateKind::kSetOverflowToMin));
6641cb0ef41Sopenharmony_ci}
6651cb0ef41Sopenharmony_ci#define DEFINE_CODE_ASSEMBLER_UNARY_OP(name, ResType, ArgType) \
6661cb0ef41Sopenharmony_ci  TNode<ResType> CodeAssembler::name(TNode<ArgType> a) {       \
6671cb0ef41Sopenharmony_ci    return UncheckedCast<ResType>(raw_assembler()->name(a));   \
6681cb0ef41Sopenharmony_ci  }
6691cb0ef41Sopenharmony_ciCODE_ASSEMBLER_UNARY_OP_LIST(DEFINE_CODE_ASSEMBLER_UNARY_OP)
6701cb0ef41Sopenharmony_ci#undef DEFINE_CODE_ASSEMBLER_UNARY_OP
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ciNode* CodeAssembler::Load(MachineType type, Node* base) {
6731cb0ef41Sopenharmony_ci  return raw_assembler()->Load(type, base);
6741cb0ef41Sopenharmony_ci}
6751cb0ef41Sopenharmony_ci
6761cb0ef41Sopenharmony_ciNode* CodeAssembler::Load(MachineType type, Node* base, Node* offset) {
6771cb0ef41Sopenharmony_ci  return raw_assembler()->Load(type, base, offset);
6781cb0ef41Sopenharmony_ci}
6791cb0ef41Sopenharmony_ci
6801cb0ef41Sopenharmony_ciTNode<Object> CodeAssembler::LoadFullTagged(Node* base) {
6811cb0ef41Sopenharmony_ci  return BitcastWordToTagged(Load<RawPtrT>(base));
6821cb0ef41Sopenharmony_ci}
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ciTNode<Object> CodeAssembler::LoadFullTagged(Node* base, TNode<IntPtrT> offset) {
6851cb0ef41Sopenharmony_ci  // Please use LoadFromObject(MachineType::MapInHeader(), object,
6861cb0ef41Sopenharmony_ci  // IntPtrConstant(-kHeapObjectTag)) instead.
6871cb0ef41Sopenharmony_ci  DCHECK(!raw_assembler()->IsMapOffsetConstantMinusTag(offset));
6881cb0ef41Sopenharmony_ci  return BitcastWordToTagged(Load<RawPtrT>(base, offset));
6891cb0ef41Sopenharmony_ci}
6901cb0ef41Sopenharmony_ci
6911cb0ef41Sopenharmony_ciNode* CodeAssembler::AtomicLoad(MachineType type, AtomicMemoryOrder order,
6921cb0ef41Sopenharmony_ci                                TNode<RawPtrT> base, TNode<WordT> offset) {
6931cb0ef41Sopenharmony_ci  DCHECK(!raw_assembler()->IsMapOffsetConstantMinusTag(offset));
6941cb0ef41Sopenharmony_ci  return raw_assembler()->AtomicLoad(AtomicLoadParameters(type, order), base,
6951cb0ef41Sopenharmony_ci                                     offset);
6961cb0ef41Sopenharmony_ci}
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_citemplate <class Type>
6991cb0ef41Sopenharmony_ciTNode<Type> CodeAssembler::AtomicLoad64(AtomicMemoryOrder order,
7001cb0ef41Sopenharmony_ci                                        TNode<RawPtrT> base,
7011cb0ef41Sopenharmony_ci                                        TNode<WordT> offset) {
7021cb0ef41Sopenharmony_ci  return UncheckedCast<Type>(raw_assembler()->AtomicLoad64(
7031cb0ef41Sopenharmony_ci      AtomicLoadParameters(MachineType::Uint64(), order), base, offset));
7041cb0ef41Sopenharmony_ci}
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_citemplate TNode<AtomicInt64> CodeAssembler::AtomicLoad64<AtomicInt64>(
7071cb0ef41Sopenharmony_ci    AtomicMemoryOrder order, TNode<RawPtrT> base, TNode<WordT> offset);
7081cb0ef41Sopenharmony_citemplate TNode<AtomicUint64> CodeAssembler::AtomicLoad64<AtomicUint64>(
7091cb0ef41Sopenharmony_ci    AtomicMemoryOrder order, TNode<RawPtrT> base, TNode<WordT> offset);
7101cb0ef41Sopenharmony_ci
7111cb0ef41Sopenharmony_ciNode* CodeAssembler::LoadFromObject(MachineType type, TNode<Object> object,
7121cb0ef41Sopenharmony_ci                                    TNode<IntPtrT> offset) {
7131cb0ef41Sopenharmony_ci  return raw_assembler()->LoadFromObject(type, object, offset);
7141cb0ef41Sopenharmony_ci}
7151cb0ef41Sopenharmony_ci
7161cb0ef41Sopenharmony_ci#ifdef V8_MAP_PACKING
7171cb0ef41Sopenharmony_ciNode* CodeAssembler::PackMapWord(Node* value) {
7181cb0ef41Sopenharmony_ci  TNode<IntPtrT> map_word =
7191cb0ef41Sopenharmony_ci      BitcastTaggedToWordForTagAndSmiBits(UncheckedCast<AnyTaggedT>(value));
7201cb0ef41Sopenharmony_ci  TNode<WordT> packed = WordXor(UncheckedCast<WordT>(map_word),
7211cb0ef41Sopenharmony_ci                                IntPtrConstant(Internals::kMapWordXorMask));
7221cb0ef41Sopenharmony_ci  return BitcastWordToTaggedSigned(packed);
7231cb0ef41Sopenharmony_ci}
7241cb0ef41Sopenharmony_ci#endif
7251cb0ef41Sopenharmony_ci
7261cb0ef41Sopenharmony_ciTNode<AnyTaggedT> CodeAssembler::LoadRootMapWord(RootIndex root_index) {
7271cb0ef41Sopenharmony_ci#ifdef V8_MAP_PACKING
7281cb0ef41Sopenharmony_ci  Handle<Object> root = isolate()->root_handle(root_index);
7291cb0ef41Sopenharmony_ci  Node* map = HeapConstant(Handle<Map>::cast(root));
7301cb0ef41Sopenharmony_ci  map = PackMapWord(map);
7311cb0ef41Sopenharmony_ci  return ReinterpretCast<AnyTaggedT>(map);
7321cb0ef41Sopenharmony_ci#else
7331cb0ef41Sopenharmony_ci  return LoadRoot(root_index);
7341cb0ef41Sopenharmony_ci#endif
7351cb0ef41Sopenharmony_ci}
7361cb0ef41Sopenharmony_ci
7371cb0ef41Sopenharmony_ciTNode<Object> CodeAssembler::LoadRoot(RootIndex root_index) {
7381cb0ef41Sopenharmony_ci  if (RootsTable::IsImmortalImmovable(root_index)) {
7391cb0ef41Sopenharmony_ci    Handle<Object> root = isolate()->root_handle(root_index);
7401cb0ef41Sopenharmony_ci    if (root->IsSmi()) {
7411cb0ef41Sopenharmony_ci      return SmiConstant(Smi::cast(*root));
7421cb0ef41Sopenharmony_ci    } else {
7431cb0ef41Sopenharmony_ci      return HeapConstant(Handle<HeapObject>::cast(root));
7441cb0ef41Sopenharmony_ci    }
7451cb0ef41Sopenharmony_ci  }
7461cb0ef41Sopenharmony_ci
7471cb0ef41Sopenharmony_ci  // TODO(jgruber): In theory we could generate better code for this by
7481cb0ef41Sopenharmony_ci  // letting the macro assembler decide how to load from the roots list. In most
7491cb0ef41Sopenharmony_ci  // cases, it would boil down to loading from a fixed kRootRegister offset.
7501cb0ef41Sopenharmony_ci  TNode<ExternalReference> isolate_root =
7511cb0ef41Sopenharmony_ci      ExternalConstant(ExternalReference::isolate_root(isolate()));
7521cb0ef41Sopenharmony_ci  int offset = IsolateData::root_slot_offset(root_index);
7531cb0ef41Sopenharmony_ci  return UncheckedCast<Object>(
7541cb0ef41Sopenharmony_ci      LoadFullTagged(isolate_root, IntPtrConstant(offset)));
7551cb0ef41Sopenharmony_ci}
7561cb0ef41Sopenharmony_ci
7571cb0ef41Sopenharmony_ciNode* CodeAssembler::UnalignedLoad(MachineType type, TNode<RawPtrT> base,
7581cb0ef41Sopenharmony_ci                                   TNode<WordT> offset) {
7591cb0ef41Sopenharmony_ci  return raw_assembler()->UnalignedLoad(type, static_cast<Node*>(base), offset);
7601cb0ef41Sopenharmony_ci}
7611cb0ef41Sopenharmony_ci
7621cb0ef41Sopenharmony_civoid CodeAssembler::Store(Node* base, Node* value) {
7631cb0ef41Sopenharmony_ci  raw_assembler()->Store(MachineRepresentation::kTagged, base, value,
7641cb0ef41Sopenharmony_ci                         kFullWriteBarrier);
7651cb0ef41Sopenharmony_ci}
7661cb0ef41Sopenharmony_ci
7671cb0ef41Sopenharmony_civoid CodeAssembler::StoreToObject(MachineRepresentation rep,
7681cb0ef41Sopenharmony_ci                                  TNode<Object> object, TNode<IntPtrT> offset,
7691cb0ef41Sopenharmony_ci                                  Node* value,
7701cb0ef41Sopenharmony_ci                                  StoreToObjectWriteBarrier write_barrier) {
7711cb0ef41Sopenharmony_ci  WriteBarrierKind write_barrier_kind;
7721cb0ef41Sopenharmony_ci  switch (write_barrier) {
7731cb0ef41Sopenharmony_ci    case StoreToObjectWriteBarrier::kFull:
7741cb0ef41Sopenharmony_ci      write_barrier_kind = WriteBarrierKind::kFullWriteBarrier;
7751cb0ef41Sopenharmony_ci      break;
7761cb0ef41Sopenharmony_ci    case StoreToObjectWriteBarrier::kMap:
7771cb0ef41Sopenharmony_ci      write_barrier_kind = WriteBarrierKind::kMapWriteBarrier;
7781cb0ef41Sopenharmony_ci      break;
7791cb0ef41Sopenharmony_ci    case StoreToObjectWriteBarrier::kNone:
7801cb0ef41Sopenharmony_ci      if (CanBeTaggedPointer(rep)) {
7811cb0ef41Sopenharmony_ci        write_barrier_kind = WriteBarrierKind::kAssertNoWriteBarrier;
7821cb0ef41Sopenharmony_ci      } else {
7831cb0ef41Sopenharmony_ci        write_barrier_kind = WriteBarrierKind::kNoWriteBarrier;
7841cb0ef41Sopenharmony_ci      }
7851cb0ef41Sopenharmony_ci      break;
7861cb0ef41Sopenharmony_ci  }
7871cb0ef41Sopenharmony_ci  raw_assembler()->StoreToObject(rep, object, offset, value,
7881cb0ef41Sopenharmony_ci                                 write_barrier_kind);
7891cb0ef41Sopenharmony_ci}
7901cb0ef41Sopenharmony_ci
7911cb0ef41Sopenharmony_civoid CodeAssembler::OptimizedStoreField(MachineRepresentation rep,
7921cb0ef41Sopenharmony_ci                                        TNode<HeapObject> object, int offset,
7931cb0ef41Sopenharmony_ci                                        Node* value) {
7941cb0ef41Sopenharmony_ci  raw_assembler()->OptimizedStoreField(rep, object, offset, value,
7951cb0ef41Sopenharmony_ci                                       WriteBarrierKind::kFullWriteBarrier);
7961cb0ef41Sopenharmony_ci}
7971cb0ef41Sopenharmony_ci
7981cb0ef41Sopenharmony_civoid CodeAssembler::OptimizedStoreFieldAssertNoWriteBarrier(
7991cb0ef41Sopenharmony_ci    MachineRepresentation rep, TNode<HeapObject> object, int offset,
8001cb0ef41Sopenharmony_ci    Node* value) {
8011cb0ef41Sopenharmony_ci  raw_assembler()->OptimizedStoreField(rep, object, offset, value,
8021cb0ef41Sopenharmony_ci                                       WriteBarrierKind::kAssertNoWriteBarrier);
8031cb0ef41Sopenharmony_ci}
8041cb0ef41Sopenharmony_ci
8051cb0ef41Sopenharmony_civoid CodeAssembler::OptimizedStoreFieldUnsafeNoWriteBarrier(
8061cb0ef41Sopenharmony_ci    MachineRepresentation rep, TNode<HeapObject> object, int offset,
8071cb0ef41Sopenharmony_ci    Node* value) {
8081cb0ef41Sopenharmony_ci  raw_assembler()->OptimizedStoreField(rep, object, offset, value,
8091cb0ef41Sopenharmony_ci                                       WriteBarrierKind::kNoWriteBarrier);
8101cb0ef41Sopenharmony_ci}
8111cb0ef41Sopenharmony_ci
8121cb0ef41Sopenharmony_civoid CodeAssembler::OptimizedStoreMap(TNode<HeapObject> object,
8131cb0ef41Sopenharmony_ci                                      TNode<Map> map) {
8141cb0ef41Sopenharmony_ci  raw_assembler()->OptimizedStoreMap(object, map);
8151cb0ef41Sopenharmony_ci}
8161cb0ef41Sopenharmony_ci
8171cb0ef41Sopenharmony_civoid CodeAssembler::Store(Node* base, Node* offset, Node* value) {
8181cb0ef41Sopenharmony_ci  // Please use OptimizedStoreMap(base, value) instead.
8191cb0ef41Sopenharmony_ci  DCHECK(!raw_assembler()->IsMapOffsetConstantMinusTag(offset));
8201cb0ef41Sopenharmony_ci  raw_assembler()->Store(MachineRepresentation::kTagged, base, offset, value,
8211cb0ef41Sopenharmony_ci                         kFullWriteBarrier);
8221cb0ef41Sopenharmony_ci}
8231cb0ef41Sopenharmony_ci
8241cb0ef41Sopenharmony_civoid CodeAssembler::StoreEphemeronKey(Node* base, Node* offset, Node* value) {
8251cb0ef41Sopenharmony_ci  DCHECK(!raw_assembler()->IsMapOffsetConstantMinusTag(offset));
8261cb0ef41Sopenharmony_ci  raw_assembler()->Store(MachineRepresentation::kTagged, base, offset, value,
8271cb0ef41Sopenharmony_ci                         kEphemeronKeyWriteBarrier);
8281cb0ef41Sopenharmony_ci}
8291cb0ef41Sopenharmony_ci
8301cb0ef41Sopenharmony_civoid CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base,
8311cb0ef41Sopenharmony_ci                                        Node* value) {
8321cb0ef41Sopenharmony_ci  raw_assembler()->Store(
8331cb0ef41Sopenharmony_ci      rep, base, value,
8341cb0ef41Sopenharmony_ci      CanBeTaggedPointer(rep) ? kAssertNoWriteBarrier : kNoWriteBarrier);
8351cb0ef41Sopenharmony_ci}
8361cb0ef41Sopenharmony_ci
8371cb0ef41Sopenharmony_civoid CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base,
8381cb0ef41Sopenharmony_ci                                        Node* offset, Node* value) {
8391cb0ef41Sopenharmony_ci  // Please use OptimizedStoreMap(base, value) instead.
8401cb0ef41Sopenharmony_ci  DCHECK(!raw_assembler()->IsMapOffsetConstantMinusTag(offset));
8411cb0ef41Sopenharmony_ci  raw_assembler()->Store(
8421cb0ef41Sopenharmony_ci      rep, base, offset, value,
8431cb0ef41Sopenharmony_ci      CanBeTaggedPointer(rep) ? kAssertNoWriteBarrier : kNoWriteBarrier);
8441cb0ef41Sopenharmony_ci}
8451cb0ef41Sopenharmony_ci
8461cb0ef41Sopenharmony_civoid CodeAssembler::UnsafeStoreNoWriteBarrier(MachineRepresentation rep,
8471cb0ef41Sopenharmony_ci                                              Node* base, Node* value) {
8481cb0ef41Sopenharmony_ci  raw_assembler()->Store(rep, base, value, kNoWriteBarrier);
8491cb0ef41Sopenharmony_ci}
8501cb0ef41Sopenharmony_ci
8511cb0ef41Sopenharmony_civoid CodeAssembler::UnsafeStoreNoWriteBarrier(MachineRepresentation rep,
8521cb0ef41Sopenharmony_ci                                              Node* base, Node* offset,
8531cb0ef41Sopenharmony_ci                                              Node* value) {
8541cb0ef41Sopenharmony_ci  // Please use OptimizedStoreMap(base, value) instead.
8551cb0ef41Sopenharmony_ci  DCHECK(!raw_assembler()->IsMapOffsetConstantMinusTag(offset));
8561cb0ef41Sopenharmony_ci  raw_assembler()->Store(rep, base, offset, value, kNoWriteBarrier);
8571cb0ef41Sopenharmony_ci}
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_civoid CodeAssembler::StoreFullTaggedNoWriteBarrier(TNode<RawPtrT> base,
8601cb0ef41Sopenharmony_ci                                                  TNode<Object> tagged_value) {
8611cb0ef41Sopenharmony_ci  StoreNoWriteBarrier(MachineType::PointerRepresentation(), base,
8621cb0ef41Sopenharmony_ci                      BitcastTaggedToWord(tagged_value));
8631cb0ef41Sopenharmony_ci}
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_civoid CodeAssembler::StoreFullTaggedNoWriteBarrier(TNode<RawPtrT> base,
8661cb0ef41Sopenharmony_ci                                                  TNode<IntPtrT> offset,
8671cb0ef41Sopenharmony_ci                                                  TNode<Object> tagged_value) {
8681cb0ef41Sopenharmony_ci  // Please use OptimizedStoreMap(base, tagged_value) instead.
8691cb0ef41Sopenharmony_ci  DCHECK(!raw_assembler()->IsMapOffsetConstantMinusTag(offset));
8701cb0ef41Sopenharmony_ci  StoreNoWriteBarrier(MachineType::PointerRepresentation(), base, offset,
8711cb0ef41Sopenharmony_ci                      BitcastTaggedToWord(tagged_value));
8721cb0ef41Sopenharmony_ci}
8731cb0ef41Sopenharmony_ci
8741cb0ef41Sopenharmony_civoid CodeAssembler::AtomicStore(MachineRepresentation rep,
8751cb0ef41Sopenharmony_ci                                AtomicMemoryOrder order, TNode<RawPtrT> base,
8761cb0ef41Sopenharmony_ci                                TNode<WordT> offset, TNode<Word32T> value) {
8771cb0ef41Sopenharmony_ci  DCHECK(!raw_assembler()->IsMapOffsetConstantMinusTag(offset));
8781cb0ef41Sopenharmony_ci  raw_assembler()->AtomicStore(
8791cb0ef41Sopenharmony_ci      AtomicStoreParameters(rep, WriteBarrierKind::kNoWriteBarrier, order),
8801cb0ef41Sopenharmony_ci      base, offset, value);
8811cb0ef41Sopenharmony_ci}
8821cb0ef41Sopenharmony_ci
8831cb0ef41Sopenharmony_civoid CodeAssembler::AtomicStore64(AtomicMemoryOrder order, TNode<RawPtrT> base,
8841cb0ef41Sopenharmony_ci                                  TNode<WordT> offset, TNode<UintPtrT> value,
8851cb0ef41Sopenharmony_ci                                  TNode<UintPtrT> value_high) {
8861cb0ef41Sopenharmony_ci  raw_assembler()->AtomicStore64(
8871cb0ef41Sopenharmony_ci      AtomicStoreParameters(MachineRepresentation::kWord64,
8881cb0ef41Sopenharmony_ci                            WriteBarrierKind::kNoWriteBarrier, order),
8891cb0ef41Sopenharmony_ci      base, offset, value, value_high);
8901cb0ef41Sopenharmony_ci}
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_ci#define ATOMIC_FUNCTION(name)                                                 \
8931cb0ef41Sopenharmony_ci  TNode<Word32T> CodeAssembler::Atomic##name(                                 \
8941cb0ef41Sopenharmony_ci      MachineType type, TNode<RawPtrT> base, TNode<UintPtrT> offset,          \
8951cb0ef41Sopenharmony_ci      TNode<Word32T> value) {                                                 \
8961cb0ef41Sopenharmony_ci    return UncheckedCast<Word32T>(                                            \
8971cb0ef41Sopenharmony_ci        raw_assembler()->Atomic##name(type, base, offset, value));            \
8981cb0ef41Sopenharmony_ci  }                                                                           \
8991cb0ef41Sopenharmony_ci  template <class Type>                                                       \
9001cb0ef41Sopenharmony_ci  TNode<Type> CodeAssembler::Atomic##name##64(                                \
9011cb0ef41Sopenharmony_ci      TNode<RawPtrT> base, TNode<UintPtrT> offset, TNode<UintPtrT> value,     \
9021cb0ef41Sopenharmony_ci      TNode<UintPtrT> value_high) {                                           \
9031cb0ef41Sopenharmony_ci    return UncheckedCast<Type>(                                               \
9041cb0ef41Sopenharmony_ci        raw_assembler()->Atomic##name##64(base, offset, value, value_high));  \
9051cb0ef41Sopenharmony_ci  }                                                                           \
9061cb0ef41Sopenharmony_ci  template TNode<AtomicInt64> CodeAssembler::Atomic##name##64 < AtomicInt64 > \
9071cb0ef41Sopenharmony_ci      (TNode<RawPtrT> base, TNode<UintPtrT> offset, TNode<UintPtrT> value,    \
9081cb0ef41Sopenharmony_ci       TNode<UintPtrT> value_high);                                           \
9091cb0ef41Sopenharmony_ci  template TNode<AtomicUint64> CodeAssembler::Atomic##name##64 <              \
9101cb0ef41Sopenharmony_ci      AtomicUint64 > (TNode<RawPtrT> base, TNode<UintPtrT> offset,            \
9111cb0ef41Sopenharmony_ci                      TNode<UintPtrT> value, TNode<UintPtrT> value_high);
9121cb0ef41Sopenharmony_ciATOMIC_FUNCTION(Add)
9131cb0ef41Sopenharmony_ciATOMIC_FUNCTION(Sub)
9141cb0ef41Sopenharmony_ciATOMIC_FUNCTION(And)
9151cb0ef41Sopenharmony_ciATOMIC_FUNCTION(Or)
9161cb0ef41Sopenharmony_ciATOMIC_FUNCTION(Xor)
9171cb0ef41Sopenharmony_ciATOMIC_FUNCTION(Exchange)
9181cb0ef41Sopenharmony_ci#undef ATOMIC_FUNCTION
9191cb0ef41Sopenharmony_ci
9201cb0ef41Sopenharmony_ciTNode<Word32T> CodeAssembler::AtomicCompareExchange(MachineType type,
9211cb0ef41Sopenharmony_ci                                                    TNode<RawPtrT> base,
9221cb0ef41Sopenharmony_ci                                                    TNode<WordT> offset,
9231cb0ef41Sopenharmony_ci                                                    TNode<Word32T> old_value,
9241cb0ef41Sopenharmony_ci                                                    TNode<Word32T> new_value) {
9251cb0ef41Sopenharmony_ci  return UncheckedCast<Word32T>(raw_assembler()->AtomicCompareExchange(
9261cb0ef41Sopenharmony_ci      type, base, offset, old_value, new_value));
9271cb0ef41Sopenharmony_ci}
9281cb0ef41Sopenharmony_ci
9291cb0ef41Sopenharmony_citemplate <class Type>
9301cb0ef41Sopenharmony_ciTNode<Type> CodeAssembler::AtomicCompareExchange64(
9311cb0ef41Sopenharmony_ci    TNode<RawPtrT> base, TNode<WordT> offset, TNode<UintPtrT> old_value,
9321cb0ef41Sopenharmony_ci    TNode<UintPtrT> new_value, TNode<UintPtrT> old_value_high,
9331cb0ef41Sopenharmony_ci    TNode<UintPtrT> new_value_high) {
9341cb0ef41Sopenharmony_ci  // This uses Uint64() intentionally: AtomicCompareExchange is not implemented
9351cb0ef41Sopenharmony_ci  // for Int64(), which is fine because the machine instruction only cares
9361cb0ef41Sopenharmony_ci  // about words.
9371cb0ef41Sopenharmony_ci  return UncheckedCast<Type>(raw_assembler()->AtomicCompareExchange64(
9381cb0ef41Sopenharmony_ci      base, offset, old_value, old_value_high, new_value, new_value_high));
9391cb0ef41Sopenharmony_ci}
9401cb0ef41Sopenharmony_ci
9411cb0ef41Sopenharmony_citemplate TNode<AtomicInt64> CodeAssembler::AtomicCompareExchange64<AtomicInt64>(
9421cb0ef41Sopenharmony_ci    TNode<RawPtrT> base, TNode<WordT> offset, TNode<UintPtrT> old_value,
9431cb0ef41Sopenharmony_ci    TNode<UintPtrT> new_value, TNode<UintPtrT> old_value_high,
9441cb0ef41Sopenharmony_ci    TNode<UintPtrT> new_value_high);
9451cb0ef41Sopenharmony_citemplate TNode<AtomicUint64>
9461cb0ef41Sopenharmony_ciCodeAssembler::AtomicCompareExchange64<AtomicUint64>(
9471cb0ef41Sopenharmony_ci    TNode<RawPtrT> base, TNode<WordT> offset, TNode<UintPtrT> old_value,
9481cb0ef41Sopenharmony_ci    TNode<UintPtrT> new_value, TNode<UintPtrT> old_value_high,
9491cb0ef41Sopenharmony_ci    TNode<UintPtrT> new_value_high);
9501cb0ef41Sopenharmony_ci
9511cb0ef41Sopenharmony_civoid CodeAssembler::StoreRoot(RootIndex root_index, TNode<Object> value) {
9521cb0ef41Sopenharmony_ci  DCHECK(!RootsTable::IsImmortalImmovable(root_index));
9531cb0ef41Sopenharmony_ci  TNode<ExternalReference> isolate_root =
9541cb0ef41Sopenharmony_ci      ExternalConstant(ExternalReference::isolate_root(isolate()));
9551cb0ef41Sopenharmony_ci  int offset = IsolateData::root_slot_offset(root_index);
9561cb0ef41Sopenharmony_ci  StoreFullTaggedNoWriteBarrier(isolate_root, IntPtrConstant(offset), value);
9571cb0ef41Sopenharmony_ci}
9581cb0ef41Sopenharmony_ci
9591cb0ef41Sopenharmony_ciNode* CodeAssembler::Projection(int index, Node* value) {
9601cb0ef41Sopenharmony_ci  DCHECK_LT(index, value->op()->ValueOutputCount());
9611cb0ef41Sopenharmony_ci  return raw_assembler()->Projection(index, value);
9621cb0ef41Sopenharmony_ci}
9631cb0ef41Sopenharmony_ci
9641cb0ef41Sopenharmony_ciTNode<HeapObject> CodeAssembler::OptimizedAllocate(
9651cb0ef41Sopenharmony_ci    TNode<IntPtrT> size, AllocationType allocation,
9661cb0ef41Sopenharmony_ci    AllowLargeObjects allow_large_objects) {
9671cb0ef41Sopenharmony_ci  return UncheckedCast<HeapObject>(raw_assembler()->OptimizedAllocate(
9681cb0ef41Sopenharmony_ci      size, allocation, allow_large_objects));
9691cb0ef41Sopenharmony_ci}
9701cb0ef41Sopenharmony_ci
9711cb0ef41Sopenharmony_civoid CodeAssembler::HandleException(Node* node) {
9721cb0ef41Sopenharmony_ci  if (state_->exception_handler_labels_.size() == 0) return;
9731cb0ef41Sopenharmony_ci  CodeAssemblerExceptionHandlerLabel* label =
9741cb0ef41Sopenharmony_ci      state_->exception_handler_labels_.back();
9751cb0ef41Sopenharmony_ci
9761cb0ef41Sopenharmony_ci  if (node->op()->HasProperty(Operator::kNoThrow)) {
9771cb0ef41Sopenharmony_ci    return;
9781cb0ef41Sopenharmony_ci  }
9791cb0ef41Sopenharmony_ci
9801cb0ef41Sopenharmony_ci  Label success(this), exception(this, Label::kDeferred);
9811cb0ef41Sopenharmony_ci  success.MergeVariables();
9821cb0ef41Sopenharmony_ci  exception.MergeVariables();
9831cb0ef41Sopenharmony_ci
9841cb0ef41Sopenharmony_ci  raw_assembler()->Continuations(node, success.label_, exception.label_);
9851cb0ef41Sopenharmony_ci
9861cb0ef41Sopenharmony_ci  Bind(&exception);
9871cb0ef41Sopenharmony_ci  const Operator* op = raw_assembler()->common()->IfException();
9881cb0ef41Sopenharmony_ci  Node* exception_value = raw_assembler()->AddNode(op, node, node);
9891cb0ef41Sopenharmony_ci  label->AddInputs({UncheckedCast<Object>(exception_value)});
9901cb0ef41Sopenharmony_ci  Goto(label->plain_label());
9911cb0ef41Sopenharmony_ci
9921cb0ef41Sopenharmony_ci  Bind(&success);
9931cb0ef41Sopenharmony_ci  raw_assembler()->AddNode(raw_assembler()->common()->IfSuccess(), node);
9941cb0ef41Sopenharmony_ci}
9951cb0ef41Sopenharmony_ci
9961cb0ef41Sopenharmony_cinamespace {
9971cb0ef41Sopenharmony_citemplate <size_t kMaxSize>
9981cb0ef41Sopenharmony_ciclass NodeArray {
9991cb0ef41Sopenharmony_ci public:
10001cb0ef41Sopenharmony_ci  void Add(Node* node) {
10011cb0ef41Sopenharmony_ci    DCHECK_GT(kMaxSize, size());
10021cb0ef41Sopenharmony_ci    *ptr_++ = node;
10031cb0ef41Sopenharmony_ci  }
10041cb0ef41Sopenharmony_ci
10051cb0ef41Sopenharmony_ci  Node* const* data() const { return arr_; }
10061cb0ef41Sopenharmony_ci  int size() const { return static_cast<int>(ptr_ - arr_); }
10071cb0ef41Sopenharmony_ci
10081cb0ef41Sopenharmony_ci private:
10091cb0ef41Sopenharmony_ci  Node* arr_[kMaxSize];
10101cb0ef41Sopenharmony_ci  Node** ptr_ = arr_;
10111cb0ef41Sopenharmony_ci};
10121cb0ef41Sopenharmony_ci}  // namespace
10131cb0ef41Sopenharmony_ci
10141cb0ef41Sopenharmony_ciNode* CodeAssembler::CallRuntimeImpl(
10151cb0ef41Sopenharmony_ci    Runtime::FunctionId function, TNode<Object> context,
10161cb0ef41Sopenharmony_ci    std::initializer_list<TNode<Object>> args) {
10171cb0ef41Sopenharmony_ci  int result_size = Runtime::FunctionForId(function)->result_size;
10181cb0ef41Sopenharmony_ci  TNode<CodeT> centry =
10191cb0ef41Sopenharmony_ci      HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size));
10201cb0ef41Sopenharmony_ci  constexpr size_t kMaxNumArgs = 6;
10211cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxNumArgs, args.size());
10221cb0ef41Sopenharmony_ci  int argc = static_cast<int>(args.size());
10231cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
10241cb0ef41Sopenharmony_ci      zone(), function, argc, Operator::kNoProperties,
10251cb0ef41Sopenharmony_ci      Runtime::MayAllocate(function) ? CallDescriptor::kNoFlags
10261cb0ef41Sopenharmony_ci                                     : CallDescriptor::kNoAllocate);
10271cb0ef41Sopenharmony_ci
10281cb0ef41Sopenharmony_ci  TNode<ExternalReference> ref =
10291cb0ef41Sopenharmony_ci      ExternalConstant(ExternalReference::Create(function));
10301cb0ef41Sopenharmony_ci  TNode<Int32T> arity = Int32Constant(argc);
10311cb0ef41Sopenharmony_ci
10321cb0ef41Sopenharmony_ci  NodeArray<kMaxNumArgs + 4> inputs;
10331cb0ef41Sopenharmony_ci  inputs.Add(centry);
10341cb0ef41Sopenharmony_ci  for (auto arg : args) inputs.Add(arg);
10351cb0ef41Sopenharmony_ci  inputs.Add(ref);
10361cb0ef41Sopenharmony_ci  inputs.Add(arity);
10371cb0ef41Sopenharmony_ci  inputs.Add(context);
10381cb0ef41Sopenharmony_ci
10391cb0ef41Sopenharmony_ci  CallPrologue();
10401cb0ef41Sopenharmony_ci  Node* return_value =
10411cb0ef41Sopenharmony_ci      raw_assembler()->CallN(call_descriptor, inputs.size(), inputs.data());
10421cb0ef41Sopenharmony_ci  HandleException(return_value);
10431cb0ef41Sopenharmony_ci  CallEpilogue();
10441cb0ef41Sopenharmony_ci  return return_value;
10451cb0ef41Sopenharmony_ci}
10461cb0ef41Sopenharmony_ci
10471cb0ef41Sopenharmony_civoid CodeAssembler::TailCallRuntimeImpl(
10481cb0ef41Sopenharmony_ci    Runtime::FunctionId function, TNode<Int32T> arity, TNode<Object> context,
10491cb0ef41Sopenharmony_ci    std::initializer_list<TNode<Object>> args) {
10501cb0ef41Sopenharmony_ci  int result_size = Runtime::FunctionForId(function)->result_size;
10511cb0ef41Sopenharmony_ci  TNode<CodeT> centry =
10521cb0ef41Sopenharmony_ci      HeapConstant(CodeFactory::RuntimeCEntry(isolate(), result_size));
10531cb0ef41Sopenharmony_ci  constexpr size_t kMaxNumArgs = 6;
10541cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxNumArgs, args.size());
10551cb0ef41Sopenharmony_ci  int argc = static_cast<int>(args.size());
10561cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetRuntimeCallDescriptor(
10571cb0ef41Sopenharmony_ci      zone(), function, argc, Operator::kNoProperties,
10581cb0ef41Sopenharmony_ci      CallDescriptor::kNoFlags);
10591cb0ef41Sopenharmony_ci
10601cb0ef41Sopenharmony_ci  TNode<ExternalReference> ref =
10611cb0ef41Sopenharmony_ci      ExternalConstant(ExternalReference::Create(function));
10621cb0ef41Sopenharmony_ci
10631cb0ef41Sopenharmony_ci  NodeArray<kMaxNumArgs + 4> inputs;
10641cb0ef41Sopenharmony_ci  inputs.Add(centry);
10651cb0ef41Sopenharmony_ci  for (auto arg : args) inputs.Add(arg);
10661cb0ef41Sopenharmony_ci  inputs.Add(ref);
10671cb0ef41Sopenharmony_ci  inputs.Add(arity);
10681cb0ef41Sopenharmony_ci  inputs.Add(context);
10691cb0ef41Sopenharmony_ci
10701cb0ef41Sopenharmony_ci  raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
10711cb0ef41Sopenharmony_ci}
10721cb0ef41Sopenharmony_ci
10731cb0ef41Sopenharmony_ciNode* CodeAssembler::CallStubN(StubCallMode call_mode,
10741cb0ef41Sopenharmony_ci                               const CallInterfaceDescriptor& descriptor,
10751cb0ef41Sopenharmony_ci                               int input_count, Node* const* inputs) {
10761cb0ef41Sopenharmony_ci  DCHECK(call_mode == StubCallMode::kCallCodeObject ||
10771cb0ef41Sopenharmony_ci         call_mode == StubCallMode::kCallBuiltinPointer);
10781cb0ef41Sopenharmony_ci
10791cb0ef41Sopenharmony_ci  // implicit nodes are target and optionally context.
10801cb0ef41Sopenharmony_ci  int implicit_nodes = descriptor.HasContextParameter() ? 2 : 1;
10811cb0ef41Sopenharmony_ci  DCHECK_LE(implicit_nodes, input_count);
10821cb0ef41Sopenharmony_ci  int argc = input_count - implicit_nodes;
10831cb0ef41Sopenharmony_ci#ifdef DEBUG
10841cb0ef41Sopenharmony_ci  if (descriptor.AllowVarArgs()) {
10851cb0ef41Sopenharmony_ci    DCHECK_LE(descriptor.GetParameterCount(), argc);
10861cb0ef41Sopenharmony_ci  } else {
10871cb0ef41Sopenharmony_ci    DCHECK_EQ(descriptor.GetParameterCount(), argc);
10881cb0ef41Sopenharmony_ci  }
10891cb0ef41Sopenharmony_ci#endif
10901cb0ef41Sopenharmony_ci  // Extra arguments not mentioned in the descriptor are passed on the stack.
10911cb0ef41Sopenharmony_ci  int stack_parameter_count = argc - descriptor.GetRegisterParameterCount();
10921cb0ef41Sopenharmony_ci  DCHECK_LE(descriptor.GetStackParameterCount(), stack_parameter_count);
10931cb0ef41Sopenharmony_ci
10941cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
10951cb0ef41Sopenharmony_ci      zone(), descriptor, stack_parameter_count, CallDescriptor::kNoFlags,
10961cb0ef41Sopenharmony_ci      Operator::kNoProperties, call_mode);
10971cb0ef41Sopenharmony_ci
10981cb0ef41Sopenharmony_ci  CallPrologue();
10991cb0ef41Sopenharmony_ci  Node* return_value =
11001cb0ef41Sopenharmony_ci      raw_assembler()->CallN(call_descriptor, input_count, inputs);
11011cb0ef41Sopenharmony_ci  HandleException(return_value);
11021cb0ef41Sopenharmony_ci  CallEpilogue();
11031cb0ef41Sopenharmony_ci  return return_value;
11041cb0ef41Sopenharmony_ci}
11051cb0ef41Sopenharmony_ci
11061cb0ef41Sopenharmony_civoid CodeAssembler::TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
11071cb0ef41Sopenharmony_ci                                     TNode<CodeT> target, TNode<Object> context,
11081cb0ef41Sopenharmony_ci                                     std::initializer_list<Node*> args) {
11091cb0ef41Sopenharmony_ci  constexpr size_t kMaxNumArgs = 11;
11101cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxNumArgs, args.size());
11111cb0ef41Sopenharmony_ci  DCHECK_EQ(descriptor.GetParameterCount(), args.size());
11121cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
11131cb0ef41Sopenharmony_ci      zone(), descriptor, descriptor.GetStackParameterCount(),
11141cb0ef41Sopenharmony_ci      CallDescriptor::kNoFlags, Operator::kNoProperties);
11151cb0ef41Sopenharmony_ci
11161cb0ef41Sopenharmony_ci  NodeArray<kMaxNumArgs + 2> inputs;
11171cb0ef41Sopenharmony_ci  inputs.Add(target);
11181cb0ef41Sopenharmony_ci  for (auto arg : args) inputs.Add(arg);
11191cb0ef41Sopenharmony_ci  if (descriptor.HasContextParameter()) {
11201cb0ef41Sopenharmony_ci    inputs.Add(context);
11211cb0ef41Sopenharmony_ci  }
11221cb0ef41Sopenharmony_ci
11231cb0ef41Sopenharmony_ci  raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
11241cb0ef41Sopenharmony_ci}
11251cb0ef41Sopenharmony_ci
11261cb0ef41Sopenharmony_ciNode* CodeAssembler::CallStubRImpl(StubCallMode call_mode,
11271cb0ef41Sopenharmony_ci                                   const CallInterfaceDescriptor& descriptor,
11281cb0ef41Sopenharmony_ci                                   TNode<Object> target, TNode<Object> context,
11291cb0ef41Sopenharmony_ci                                   std::initializer_list<Node*> args) {
11301cb0ef41Sopenharmony_ci  DCHECK(call_mode == StubCallMode::kCallCodeObject ||
11311cb0ef41Sopenharmony_ci         call_mode == StubCallMode::kCallBuiltinPointer);
11321cb0ef41Sopenharmony_ci
11331cb0ef41Sopenharmony_ci  constexpr size_t kMaxNumArgs = 10;
11341cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxNumArgs, args.size());
11351cb0ef41Sopenharmony_ci
11361cb0ef41Sopenharmony_ci  NodeArray<kMaxNumArgs + 2> inputs;
11371cb0ef41Sopenharmony_ci  inputs.Add(target);
11381cb0ef41Sopenharmony_ci  for (auto arg : args) inputs.Add(arg);
11391cb0ef41Sopenharmony_ci  if (descriptor.HasContextParameter()) {
11401cb0ef41Sopenharmony_ci    inputs.Add(context);
11411cb0ef41Sopenharmony_ci  }
11421cb0ef41Sopenharmony_ci
11431cb0ef41Sopenharmony_ci  return CallStubN(call_mode, descriptor, inputs.size(), inputs.data());
11441cb0ef41Sopenharmony_ci}
11451cb0ef41Sopenharmony_ci
11461cb0ef41Sopenharmony_ciNode* CodeAssembler::CallJSStubImpl(const CallInterfaceDescriptor& descriptor,
11471cb0ef41Sopenharmony_ci                                    TNode<Object> target, TNode<Object> context,
11481cb0ef41Sopenharmony_ci                                    TNode<Object> function,
11491cb0ef41Sopenharmony_ci                                    base::Optional<TNode<Object>> new_target,
11501cb0ef41Sopenharmony_ci                                    TNode<Int32T> arity,
11511cb0ef41Sopenharmony_ci                                    std::initializer_list<Node*> args) {
11521cb0ef41Sopenharmony_ci  constexpr size_t kMaxNumArgs = 10;
11531cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxNumArgs, args.size());
11541cb0ef41Sopenharmony_ci  NodeArray<kMaxNumArgs + 5> inputs;
11551cb0ef41Sopenharmony_ci  inputs.Add(target);
11561cb0ef41Sopenharmony_ci  inputs.Add(function);
11571cb0ef41Sopenharmony_ci  if (new_target) {
11581cb0ef41Sopenharmony_ci    inputs.Add(*new_target);
11591cb0ef41Sopenharmony_ci  }
11601cb0ef41Sopenharmony_ci  inputs.Add(arity);
11611cb0ef41Sopenharmony_ci  for (auto arg : args) inputs.Add(arg);
11621cb0ef41Sopenharmony_ci  if (descriptor.HasContextParameter()) {
11631cb0ef41Sopenharmony_ci    inputs.Add(context);
11641cb0ef41Sopenharmony_ci  }
11651cb0ef41Sopenharmony_ci  return CallStubN(StubCallMode::kCallCodeObject, descriptor, inputs.size(),
11661cb0ef41Sopenharmony_ci                   inputs.data());
11671cb0ef41Sopenharmony_ci}
11681cb0ef41Sopenharmony_ci
11691cb0ef41Sopenharmony_civoid CodeAssembler::TailCallStubThenBytecodeDispatchImpl(
11701cb0ef41Sopenharmony_ci    const CallInterfaceDescriptor& descriptor, Node* target, Node* context,
11711cb0ef41Sopenharmony_ci    std::initializer_list<Node*> args) {
11721cb0ef41Sopenharmony_ci  constexpr size_t kMaxNumArgs = 6;
11731cb0ef41Sopenharmony_ci  DCHECK_GE(kMaxNumArgs, args.size());
11741cb0ef41Sopenharmony_ci
11751cb0ef41Sopenharmony_ci  DCHECK_LE(descriptor.GetParameterCount(), args.size());
11761cb0ef41Sopenharmony_ci  int argc = static_cast<int>(args.size());
11771cb0ef41Sopenharmony_ci  // Extra arguments not mentioned in the descriptor are passed on the stack.
11781cb0ef41Sopenharmony_ci  int stack_parameter_count = argc - descriptor.GetRegisterParameterCount();
11791cb0ef41Sopenharmony_ci  DCHECK_LE(descriptor.GetStackParameterCount(), stack_parameter_count);
11801cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
11811cb0ef41Sopenharmony_ci      zone(), descriptor, stack_parameter_count, CallDescriptor::kNoFlags,
11821cb0ef41Sopenharmony_ci      Operator::kNoProperties);
11831cb0ef41Sopenharmony_ci
11841cb0ef41Sopenharmony_ci  NodeArray<kMaxNumArgs + 2> inputs;
11851cb0ef41Sopenharmony_ci  inputs.Add(target);
11861cb0ef41Sopenharmony_ci  for (auto arg : args) inputs.Add(arg);
11871cb0ef41Sopenharmony_ci  inputs.Add(context);
11881cb0ef41Sopenharmony_ci
11891cb0ef41Sopenharmony_ci  raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data());
11901cb0ef41Sopenharmony_ci}
11911cb0ef41Sopenharmony_ci
11921cb0ef41Sopenharmony_citemplate <class... TArgs>
11931cb0ef41Sopenharmony_civoid CodeAssembler::TailCallBytecodeDispatch(
11941cb0ef41Sopenharmony_ci    const CallInterfaceDescriptor& descriptor, TNode<RawPtrT> target,
11951cb0ef41Sopenharmony_ci    TArgs... args) {
11961cb0ef41Sopenharmony_ci  DCHECK_EQ(descriptor.GetParameterCount(), sizeof...(args));
11971cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetBytecodeDispatchCallDescriptor(
11981cb0ef41Sopenharmony_ci      zone(), descriptor, descriptor.GetStackParameterCount());
11991cb0ef41Sopenharmony_ci
12001cb0ef41Sopenharmony_ci  Node* nodes[] = {target, args...};
12011cb0ef41Sopenharmony_ci  CHECK_EQ(descriptor.GetParameterCount() + 1, arraysize(nodes));
12021cb0ef41Sopenharmony_ci  raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
12031cb0ef41Sopenharmony_ci}
12041cb0ef41Sopenharmony_ci
12051cb0ef41Sopenharmony_ci// Instantiate TailCallBytecodeDispatch() for argument counts used by
12061cb0ef41Sopenharmony_ci// CSA-generated code
12071cb0ef41Sopenharmony_citemplate V8_EXPORT_PRIVATE void CodeAssembler::TailCallBytecodeDispatch(
12081cb0ef41Sopenharmony_ci    const CallInterfaceDescriptor& descriptor, TNode<RawPtrT> target,
12091cb0ef41Sopenharmony_ci    TNode<Object>, TNode<IntPtrT>, TNode<BytecodeArray>,
12101cb0ef41Sopenharmony_ci    TNode<ExternalReference>);
12111cb0ef41Sopenharmony_ci
12121cb0ef41Sopenharmony_civoid CodeAssembler::TailCallJSCode(TNode<CodeT> code, TNode<Context> context,
12131cb0ef41Sopenharmony_ci                                   TNode<JSFunction> function,
12141cb0ef41Sopenharmony_ci                                   TNode<Object> new_target,
12151cb0ef41Sopenharmony_ci                                   TNode<Int32T> arg_count) {
12161cb0ef41Sopenharmony_ci  JSTrampolineDescriptor descriptor;
12171cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetStubCallDescriptor(
12181cb0ef41Sopenharmony_ci      zone(), descriptor, descriptor.GetStackParameterCount(),
12191cb0ef41Sopenharmony_ci      CallDescriptor::kFixedTargetRegister, Operator::kNoProperties);
12201cb0ef41Sopenharmony_ci
12211cb0ef41Sopenharmony_ci  Node* nodes[] = {code, function, new_target, arg_count, context};
12221cb0ef41Sopenharmony_ci  CHECK_EQ(descriptor.GetParameterCount() + 2, arraysize(nodes));
12231cb0ef41Sopenharmony_ci  raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes);
12241cb0ef41Sopenharmony_ci}
12251cb0ef41Sopenharmony_ci
12261cb0ef41Sopenharmony_ciNode* CodeAssembler::CallCFunctionN(Signature<MachineType>* signature,
12271cb0ef41Sopenharmony_ci                                    int input_count, Node* const* inputs) {
12281cb0ef41Sopenharmony_ci  auto call_descriptor = Linkage::GetSimplifiedCDescriptor(zone(), signature);
12291cb0ef41Sopenharmony_ci  return raw_assembler()->CallN(call_descriptor, input_count, inputs);
12301cb0ef41Sopenharmony_ci}
12311cb0ef41Sopenharmony_ci
12321cb0ef41Sopenharmony_ciNode* CodeAssembler::CallCFunction(
12331cb0ef41Sopenharmony_ci    Node* function, base::Optional<MachineType> return_type,
12341cb0ef41Sopenharmony_ci    std::initializer_list<CodeAssembler::CFunctionArg> args) {
12351cb0ef41Sopenharmony_ci  return raw_assembler()->CallCFunction(function, return_type, args);
12361cb0ef41Sopenharmony_ci}
12371cb0ef41Sopenharmony_ci
12381cb0ef41Sopenharmony_ciNode* CodeAssembler::CallCFunctionWithoutFunctionDescriptor(
12391cb0ef41Sopenharmony_ci    Node* function, MachineType return_type,
12401cb0ef41Sopenharmony_ci    std::initializer_list<CodeAssembler::CFunctionArg> args) {
12411cb0ef41Sopenharmony_ci  return raw_assembler()->CallCFunctionWithoutFunctionDescriptor(
12421cb0ef41Sopenharmony_ci      function, return_type, args);
12431cb0ef41Sopenharmony_ci}
12441cb0ef41Sopenharmony_ci
12451cb0ef41Sopenharmony_ciNode* CodeAssembler::CallCFunctionWithCallerSavedRegisters(
12461cb0ef41Sopenharmony_ci    Node* function, MachineType return_type, SaveFPRegsMode mode,
12471cb0ef41Sopenharmony_ci    std::initializer_list<CodeAssembler::CFunctionArg> args) {
12481cb0ef41Sopenharmony_ci  DCHECK(return_type.LessThanOrEqualPointerSize());
12491cb0ef41Sopenharmony_ci  return raw_assembler()->CallCFunctionWithCallerSavedRegisters(
12501cb0ef41Sopenharmony_ci      function, return_type, mode, args);
12511cb0ef41Sopenharmony_ci}
12521cb0ef41Sopenharmony_ci
12531cb0ef41Sopenharmony_civoid CodeAssembler::Goto(Label* label) {
12541cb0ef41Sopenharmony_ci  label->MergeVariables();
12551cb0ef41Sopenharmony_ci  raw_assembler()->Goto(label->label_);
12561cb0ef41Sopenharmony_ci}
12571cb0ef41Sopenharmony_ci
12581cb0ef41Sopenharmony_civoid CodeAssembler::GotoIf(TNode<IntegralT> condition, Label* true_label) {
12591cb0ef41Sopenharmony_ci  Label false_label(this);
12601cb0ef41Sopenharmony_ci  Branch(condition, true_label, &false_label);
12611cb0ef41Sopenharmony_ci  Bind(&false_label);
12621cb0ef41Sopenharmony_ci}
12631cb0ef41Sopenharmony_ci
12641cb0ef41Sopenharmony_civoid CodeAssembler::GotoIfNot(TNode<IntegralT> condition, Label* false_label) {
12651cb0ef41Sopenharmony_ci  Label true_label(this);
12661cb0ef41Sopenharmony_ci  Branch(condition, &true_label, false_label);
12671cb0ef41Sopenharmony_ci  Bind(&true_label);
12681cb0ef41Sopenharmony_ci}
12691cb0ef41Sopenharmony_ci
12701cb0ef41Sopenharmony_civoid CodeAssembler::Branch(TNode<IntegralT> condition, Label* true_label,
12711cb0ef41Sopenharmony_ci                           Label* false_label) {
12721cb0ef41Sopenharmony_ci  int32_t constant;
12731cb0ef41Sopenharmony_ci  if (TryToInt32Constant(condition, &constant)) {
12741cb0ef41Sopenharmony_ci    if ((true_label->is_used() || true_label->is_bound()) &&
12751cb0ef41Sopenharmony_ci        (false_label->is_used() || false_label->is_bound())) {
12761cb0ef41Sopenharmony_ci      return Goto(constant ? true_label : false_label);
12771cb0ef41Sopenharmony_ci    }
12781cb0ef41Sopenharmony_ci  }
12791cb0ef41Sopenharmony_ci  true_label->MergeVariables();
12801cb0ef41Sopenharmony_ci  false_label->MergeVariables();
12811cb0ef41Sopenharmony_ci  return raw_assembler()->Branch(condition, true_label->label_,
12821cb0ef41Sopenharmony_ci                                 false_label->label_);
12831cb0ef41Sopenharmony_ci}
12841cb0ef41Sopenharmony_ci
12851cb0ef41Sopenharmony_civoid CodeAssembler::Branch(TNode<BoolT> condition,
12861cb0ef41Sopenharmony_ci                           const std::function<void()>& true_body,
12871cb0ef41Sopenharmony_ci                           const std::function<void()>& false_body) {
12881cb0ef41Sopenharmony_ci  int32_t constant;
12891cb0ef41Sopenharmony_ci  if (TryToInt32Constant(condition, &constant)) {
12901cb0ef41Sopenharmony_ci    return constant ? true_body() : false_body();
12911cb0ef41Sopenharmony_ci  }
12921cb0ef41Sopenharmony_ci
12931cb0ef41Sopenharmony_ci  Label vtrue(this), vfalse(this);
12941cb0ef41Sopenharmony_ci  Branch(condition, &vtrue, &vfalse);
12951cb0ef41Sopenharmony_ci
12961cb0ef41Sopenharmony_ci  Bind(&vtrue);
12971cb0ef41Sopenharmony_ci  true_body();
12981cb0ef41Sopenharmony_ci
12991cb0ef41Sopenharmony_ci  Bind(&vfalse);
13001cb0ef41Sopenharmony_ci  false_body();
13011cb0ef41Sopenharmony_ci}
13021cb0ef41Sopenharmony_ci
13031cb0ef41Sopenharmony_civoid CodeAssembler::Branch(TNode<BoolT> condition, Label* true_label,
13041cb0ef41Sopenharmony_ci                           const std::function<void()>& false_body) {
13051cb0ef41Sopenharmony_ci  int32_t constant;
13061cb0ef41Sopenharmony_ci  if (TryToInt32Constant(condition, &constant)) {
13071cb0ef41Sopenharmony_ci    return constant ? Goto(true_label) : false_body();
13081cb0ef41Sopenharmony_ci  }
13091cb0ef41Sopenharmony_ci
13101cb0ef41Sopenharmony_ci  Label vfalse(this);
13111cb0ef41Sopenharmony_ci  Branch(condition, true_label, &vfalse);
13121cb0ef41Sopenharmony_ci  Bind(&vfalse);
13131cb0ef41Sopenharmony_ci  false_body();
13141cb0ef41Sopenharmony_ci}
13151cb0ef41Sopenharmony_ci
13161cb0ef41Sopenharmony_civoid CodeAssembler::Branch(TNode<BoolT> condition,
13171cb0ef41Sopenharmony_ci                           const std::function<void()>& true_body,
13181cb0ef41Sopenharmony_ci                           Label* false_label) {
13191cb0ef41Sopenharmony_ci  int32_t constant;
13201cb0ef41Sopenharmony_ci  if (TryToInt32Constant(condition, &constant)) {
13211cb0ef41Sopenharmony_ci    return constant ? true_body() : Goto(false_label);
13221cb0ef41Sopenharmony_ci  }
13231cb0ef41Sopenharmony_ci
13241cb0ef41Sopenharmony_ci  Label vtrue(this);
13251cb0ef41Sopenharmony_ci  Branch(condition, &vtrue, false_label);
13261cb0ef41Sopenharmony_ci  Bind(&vtrue);
13271cb0ef41Sopenharmony_ci  true_body();
13281cb0ef41Sopenharmony_ci}
13291cb0ef41Sopenharmony_ci
13301cb0ef41Sopenharmony_civoid CodeAssembler::Switch(Node* index, Label* default_label,
13311cb0ef41Sopenharmony_ci                           const int32_t* case_values, Label** case_labels,
13321cb0ef41Sopenharmony_ci                           size_t case_count) {
13331cb0ef41Sopenharmony_ci  RawMachineLabel** labels = zone()->NewArray<RawMachineLabel*>(case_count);
13341cb0ef41Sopenharmony_ci  for (size_t i = 0; i < case_count; ++i) {
13351cb0ef41Sopenharmony_ci    labels[i] = case_labels[i]->label_;
13361cb0ef41Sopenharmony_ci    case_labels[i]->MergeVariables();
13371cb0ef41Sopenharmony_ci  }
13381cb0ef41Sopenharmony_ci  default_label->MergeVariables();
13391cb0ef41Sopenharmony_ci  return raw_assembler()->Switch(index, default_label->label_, case_values,
13401cb0ef41Sopenharmony_ci                                 labels, case_count);
13411cb0ef41Sopenharmony_ci}
13421cb0ef41Sopenharmony_ci
13431cb0ef41Sopenharmony_cibool CodeAssembler::UnalignedLoadSupported(MachineRepresentation rep) const {
13441cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->UnalignedLoadSupported(rep);
13451cb0ef41Sopenharmony_ci}
13461cb0ef41Sopenharmony_cibool CodeAssembler::UnalignedStoreSupported(MachineRepresentation rep) const {
13471cb0ef41Sopenharmony_ci  return raw_assembler()->machine()->UnalignedStoreSupported(rep);
13481cb0ef41Sopenharmony_ci}
13491cb0ef41Sopenharmony_ci
13501cb0ef41Sopenharmony_ci// RawMachineAssembler delegate helpers:
13511cb0ef41Sopenharmony_ciIsolate* CodeAssembler::isolate() const { return raw_assembler()->isolate(); }
13521cb0ef41Sopenharmony_ci
13531cb0ef41Sopenharmony_ciFactory* CodeAssembler::factory() const { return isolate()->factory(); }
13541cb0ef41Sopenharmony_ci
13551cb0ef41Sopenharmony_ciZone* CodeAssembler::zone() const { return raw_assembler()->zone(); }
13561cb0ef41Sopenharmony_ci
13571cb0ef41Sopenharmony_cibool CodeAssembler::IsExceptionHandlerActive() const {
13581cb0ef41Sopenharmony_ci  return state_->exception_handler_labels_.size() != 0;
13591cb0ef41Sopenharmony_ci}
13601cb0ef41Sopenharmony_ci
13611cb0ef41Sopenharmony_ciRawMachineAssembler* CodeAssembler::raw_assembler() const {
13621cb0ef41Sopenharmony_ci  return state_->raw_assembler_.get();
13631cb0ef41Sopenharmony_ci}
13641cb0ef41Sopenharmony_ci
13651cb0ef41Sopenharmony_ciJSGraph* CodeAssembler::jsgraph() const { return state_->jsgraph_; }
13661cb0ef41Sopenharmony_ci
13671cb0ef41Sopenharmony_ci// The core implementation of Variable is stored through an indirection so
13681cb0ef41Sopenharmony_ci// that it can outlive the often block-scoped Variable declarations. This is
13691cb0ef41Sopenharmony_ci// needed to ensure that variable binding and merging through phis can
13701cb0ef41Sopenharmony_ci// properly be verified.
13711cb0ef41Sopenharmony_ciclass CodeAssemblerVariable::Impl : public ZoneObject {
13721cb0ef41Sopenharmony_ci public:
13731cb0ef41Sopenharmony_ci  explicit Impl(MachineRepresentation rep, CodeAssemblerState::VariableId id)
13741cb0ef41Sopenharmony_ci      :
13751cb0ef41Sopenharmony_ci#if DEBUG
13761cb0ef41Sopenharmony_ci        debug_info_(AssemblerDebugInfo(nullptr, nullptr, -1)),
13771cb0ef41Sopenharmony_ci#endif
13781cb0ef41Sopenharmony_ci        value_(nullptr),
13791cb0ef41Sopenharmony_ci        rep_(rep),
13801cb0ef41Sopenharmony_ci        var_id_(id) {
13811cb0ef41Sopenharmony_ci  }
13821cb0ef41Sopenharmony_ci
13831cb0ef41Sopenharmony_ci#if DEBUG
13841cb0ef41Sopenharmony_ci  AssemblerDebugInfo debug_info() const { return debug_info_; }
13851cb0ef41Sopenharmony_ci  void set_debug_info(AssemblerDebugInfo debug_info) {
13861cb0ef41Sopenharmony_ci    debug_info_ = debug_info;
13871cb0ef41Sopenharmony_ci  }
13881cb0ef41Sopenharmony_ci
13891cb0ef41Sopenharmony_ci  AssemblerDebugInfo debug_info_;
13901cb0ef41Sopenharmony_ci#endif  // DEBUG
13911cb0ef41Sopenharmony_ci  bool operator<(const CodeAssemblerVariable::Impl& other) const {
13921cb0ef41Sopenharmony_ci    return var_id_ < other.var_id_;
13931cb0ef41Sopenharmony_ci  }
13941cb0ef41Sopenharmony_ci  Node* value_;
13951cb0ef41Sopenharmony_ci  MachineRepresentation rep_;
13961cb0ef41Sopenharmony_ci  CodeAssemblerState::VariableId var_id_;
13971cb0ef41Sopenharmony_ci};
13981cb0ef41Sopenharmony_ci
13991cb0ef41Sopenharmony_cibool CodeAssemblerVariable::ImplComparator::operator()(
14001cb0ef41Sopenharmony_ci    const CodeAssemblerVariable::Impl* a,
14011cb0ef41Sopenharmony_ci    const CodeAssemblerVariable::Impl* b) const {
14021cb0ef41Sopenharmony_ci  return *a < *b;
14031cb0ef41Sopenharmony_ci}
14041cb0ef41Sopenharmony_ci
14051cb0ef41Sopenharmony_ciCodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler,
14061cb0ef41Sopenharmony_ci                                             MachineRepresentation rep)
14071cb0ef41Sopenharmony_ci    : impl_(assembler->zone()->New<Impl>(rep,
14081cb0ef41Sopenharmony_ci                                         assembler->state()->NextVariableId())),
14091cb0ef41Sopenharmony_ci      state_(assembler->state()) {
14101cb0ef41Sopenharmony_ci  state_->variables_.insert(impl_);
14111cb0ef41Sopenharmony_ci}
14121cb0ef41Sopenharmony_ci
14131cb0ef41Sopenharmony_ciCodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler,
14141cb0ef41Sopenharmony_ci                                             MachineRepresentation rep,
14151cb0ef41Sopenharmony_ci                                             Node* initial_value)
14161cb0ef41Sopenharmony_ci    : CodeAssemblerVariable(assembler, rep) {
14171cb0ef41Sopenharmony_ci  Bind(initial_value);
14181cb0ef41Sopenharmony_ci}
14191cb0ef41Sopenharmony_ci
14201cb0ef41Sopenharmony_ci#if DEBUG
14211cb0ef41Sopenharmony_ciCodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler,
14221cb0ef41Sopenharmony_ci                                             AssemblerDebugInfo debug_info,
14231cb0ef41Sopenharmony_ci                                             MachineRepresentation rep)
14241cb0ef41Sopenharmony_ci    : impl_(assembler->zone()->New<Impl>(rep,
14251cb0ef41Sopenharmony_ci                                         assembler->state()->NextVariableId())),
14261cb0ef41Sopenharmony_ci      state_(assembler->state()) {
14271cb0ef41Sopenharmony_ci  impl_->set_debug_info(debug_info);
14281cb0ef41Sopenharmony_ci  state_->variables_.insert(impl_);
14291cb0ef41Sopenharmony_ci}
14301cb0ef41Sopenharmony_ci
14311cb0ef41Sopenharmony_ciCodeAssemblerVariable::CodeAssemblerVariable(CodeAssembler* assembler,
14321cb0ef41Sopenharmony_ci                                             AssemblerDebugInfo debug_info,
14331cb0ef41Sopenharmony_ci                                             MachineRepresentation rep,
14341cb0ef41Sopenharmony_ci                                             Node* initial_value)
14351cb0ef41Sopenharmony_ci    : CodeAssemblerVariable(assembler, debug_info, rep) {
14361cb0ef41Sopenharmony_ci  impl_->set_debug_info(debug_info);
14371cb0ef41Sopenharmony_ci  Bind(initial_value);
14381cb0ef41Sopenharmony_ci}
14391cb0ef41Sopenharmony_ci#endif  // DEBUG
14401cb0ef41Sopenharmony_ci
14411cb0ef41Sopenharmony_ciCodeAssemblerVariable::~CodeAssemblerVariable() {
14421cb0ef41Sopenharmony_ci  state_->variables_.erase(impl_);
14431cb0ef41Sopenharmony_ci}
14441cb0ef41Sopenharmony_ci
14451cb0ef41Sopenharmony_civoid CodeAssemblerVariable::Bind(Node* value) { impl_->value_ = value; }
14461cb0ef41Sopenharmony_ci
14471cb0ef41Sopenharmony_ciNode* CodeAssemblerVariable::value() const {
14481cb0ef41Sopenharmony_ci#if DEBUG
14491cb0ef41Sopenharmony_ci  if (!IsBound()) {
14501cb0ef41Sopenharmony_ci    std::stringstream str;
14511cb0ef41Sopenharmony_ci    str << "#Use of unbound variable:"
14521cb0ef41Sopenharmony_ci        << "#\n    Variable:      " << *this << "#\n    Current Block: ";
14531cb0ef41Sopenharmony_ci    state_->PrintCurrentBlock(str);
14541cb0ef41Sopenharmony_ci    FATAL("%s", str.str().c_str());
14551cb0ef41Sopenharmony_ci  }
14561cb0ef41Sopenharmony_ci  if (!state_->InsideBlock()) {
14571cb0ef41Sopenharmony_ci    std::stringstream str;
14581cb0ef41Sopenharmony_ci    str << "#Accessing variable value outside a block:"
14591cb0ef41Sopenharmony_ci        << "#\n    Variable:      " << *this;
14601cb0ef41Sopenharmony_ci    FATAL("%s", str.str().c_str());
14611cb0ef41Sopenharmony_ci  }
14621cb0ef41Sopenharmony_ci#endif  // DEBUG
14631cb0ef41Sopenharmony_ci  return impl_->value_;
14641cb0ef41Sopenharmony_ci}
14651cb0ef41Sopenharmony_ci
14661cb0ef41Sopenharmony_ciMachineRepresentation CodeAssemblerVariable::rep() const { return impl_->rep_; }
14671cb0ef41Sopenharmony_ci
14681cb0ef41Sopenharmony_cibool CodeAssemblerVariable::IsBound() const { return impl_->value_ != nullptr; }
14691cb0ef41Sopenharmony_ci
14701cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os,
14711cb0ef41Sopenharmony_ci                         const CodeAssemblerVariable::Impl& impl) {
14721cb0ef41Sopenharmony_ci#if DEBUG
14731cb0ef41Sopenharmony_ci  AssemblerDebugInfo info = impl.debug_info();
14741cb0ef41Sopenharmony_ci  if (info.name) os << "V" << info;
14751cb0ef41Sopenharmony_ci#endif  // DEBUG
14761cb0ef41Sopenharmony_ci  return os;
14771cb0ef41Sopenharmony_ci}
14781cb0ef41Sopenharmony_ci
14791cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os,
14801cb0ef41Sopenharmony_ci                         const CodeAssemblerVariable& variable) {
14811cb0ef41Sopenharmony_ci  os << *variable.impl_;
14821cb0ef41Sopenharmony_ci  return os;
14831cb0ef41Sopenharmony_ci}
14841cb0ef41Sopenharmony_ci
14851cb0ef41Sopenharmony_ciCodeAssemblerLabel::CodeAssemblerLabel(CodeAssembler* assembler,
14861cb0ef41Sopenharmony_ci                                       size_t vars_count,
14871cb0ef41Sopenharmony_ci                                       CodeAssemblerVariable* const* vars,
14881cb0ef41Sopenharmony_ci                                       CodeAssemblerLabel::Type type)
14891cb0ef41Sopenharmony_ci    : bound_(false),
14901cb0ef41Sopenharmony_ci      merge_count_(0),
14911cb0ef41Sopenharmony_ci      state_(assembler->state()),
14921cb0ef41Sopenharmony_ci      label_(nullptr) {
14931cb0ef41Sopenharmony_ci  label_ = assembler->zone()->New<RawMachineLabel>(
14941cb0ef41Sopenharmony_ci      type == kDeferred ? RawMachineLabel::kDeferred
14951cb0ef41Sopenharmony_ci                        : RawMachineLabel::kNonDeferred);
14961cb0ef41Sopenharmony_ci  for (size_t i = 0; i < vars_count; ++i) {
14971cb0ef41Sopenharmony_ci    variable_phis_[vars[i]->impl_] = nullptr;
14981cb0ef41Sopenharmony_ci  }
14991cb0ef41Sopenharmony_ci}
15001cb0ef41Sopenharmony_ci
15011cb0ef41Sopenharmony_ciCodeAssemblerLabel::~CodeAssemblerLabel() { label_->~RawMachineLabel(); }
15021cb0ef41Sopenharmony_ci
15031cb0ef41Sopenharmony_civoid CodeAssemblerLabel::MergeVariables() {
15041cb0ef41Sopenharmony_ci  ++merge_count_;
15051cb0ef41Sopenharmony_ci  for (CodeAssemblerVariable::Impl* var : state_->variables_) {
15061cb0ef41Sopenharmony_ci    size_t count = 0;
15071cb0ef41Sopenharmony_ci    Node* node = var->value_;
15081cb0ef41Sopenharmony_ci    if (node != nullptr) {
15091cb0ef41Sopenharmony_ci      auto i = variable_merges_.find(var);
15101cb0ef41Sopenharmony_ci      if (i != variable_merges_.end()) {
15111cb0ef41Sopenharmony_ci        i->second.push_back(node);
15121cb0ef41Sopenharmony_ci        count = i->second.size();
15131cb0ef41Sopenharmony_ci      } else {
15141cb0ef41Sopenharmony_ci        count = 1;
15151cb0ef41Sopenharmony_ci        variable_merges_[var] = std::vector<Node*>(1, node);
15161cb0ef41Sopenharmony_ci      }
15171cb0ef41Sopenharmony_ci    }
15181cb0ef41Sopenharmony_ci    // If the following asserts, then you've jumped to a label without a bound
15191cb0ef41Sopenharmony_ci    // variable along that path that expects to merge its value into a phi.
15201cb0ef41Sopenharmony_ci    // This can also occur if a label is bound that is never jumped to.
15211cb0ef41Sopenharmony_ci    DCHECK(variable_phis_.find(var) == variable_phis_.end() ||
15221cb0ef41Sopenharmony_ci           count == merge_count_);
15231cb0ef41Sopenharmony_ci    USE(count);
15241cb0ef41Sopenharmony_ci
15251cb0ef41Sopenharmony_ci    // If the label is already bound, we already know the set of variables to
15261cb0ef41Sopenharmony_ci    // merge and phi nodes have already been created.
15271cb0ef41Sopenharmony_ci    if (bound_) {
15281cb0ef41Sopenharmony_ci      auto phi = variable_phis_.find(var);
15291cb0ef41Sopenharmony_ci      if (phi != variable_phis_.end()) {
15301cb0ef41Sopenharmony_ci        DCHECK_NOT_NULL(phi->second);
15311cb0ef41Sopenharmony_ci        state_->raw_assembler_->AppendPhiInput(phi->second, node);
15321cb0ef41Sopenharmony_ci      } else {
15331cb0ef41Sopenharmony_ci        auto i = variable_merges_.find(var);
15341cb0ef41Sopenharmony_ci        if (i != variable_merges_.end()) {
15351cb0ef41Sopenharmony_ci          // If the following assert fires, then you've declared a variable that
15361cb0ef41Sopenharmony_ci          // has the same bound value along all paths up until the point you
15371cb0ef41Sopenharmony_ci          // bound this label, but then later merged a path with a new value for
15381cb0ef41Sopenharmony_ci          // the variable after the label bind (it's not possible to add phis to
15391cb0ef41Sopenharmony_ci          // the bound label after the fact, just make sure to list the variable
15401cb0ef41Sopenharmony_ci          // in the label's constructor's list of merged variables).
15411cb0ef41Sopenharmony_ci#if DEBUG
15421cb0ef41Sopenharmony_ci          if (find_if(i->second.begin(), i->second.end(),
15431cb0ef41Sopenharmony_ci                      [node](Node* e) -> bool { return node != e; }) !=
15441cb0ef41Sopenharmony_ci              i->second.end()) {
15451cb0ef41Sopenharmony_ci            std::stringstream str;
15461cb0ef41Sopenharmony_ci            str << "Unmerged variable found when jumping to block. \n"
15471cb0ef41Sopenharmony_ci                << "#    Variable:      " << *var;
15481cb0ef41Sopenharmony_ci            if (bound_) {
15491cb0ef41Sopenharmony_ci              str << "\n#    Target block:  " << *label_->block();
15501cb0ef41Sopenharmony_ci            }
15511cb0ef41Sopenharmony_ci            str << "\n#    Current Block: ";
15521cb0ef41Sopenharmony_ci            state_->PrintCurrentBlock(str);
15531cb0ef41Sopenharmony_ci            FATAL("%s", str.str().c_str());
15541cb0ef41Sopenharmony_ci          }
15551cb0ef41Sopenharmony_ci#endif  // DEBUG
15561cb0ef41Sopenharmony_ci        }
15571cb0ef41Sopenharmony_ci      }
15581cb0ef41Sopenharmony_ci    }
15591cb0ef41Sopenharmony_ci  }
15601cb0ef41Sopenharmony_ci}
15611cb0ef41Sopenharmony_ci
15621cb0ef41Sopenharmony_ci#if DEBUG
15631cb0ef41Sopenharmony_civoid CodeAssemblerLabel::Bind(AssemblerDebugInfo debug_info) {
15641cb0ef41Sopenharmony_ci  if (bound_) {
15651cb0ef41Sopenharmony_ci    std::stringstream str;
15661cb0ef41Sopenharmony_ci    str << "Cannot bind the same label twice:"
15671cb0ef41Sopenharmony_ci        << "\n#    current:  " << debug_info
15681cb0ef41Sopenharmony_ci        << "\n#    previous: " << *label_->block();
15691cb0ef41Sopenharmony_ci    FATAL("%s", str.str().c_str());
15701cb0ef41Sopenharmony_ci  }
15711cb0ef41Sopenharmony_ci  if (FLAG_enable_source_at_csa_bind) {
15721cb0ef41Sopenharmony_ci    state_->raw_assembler_->SetCurrentExternalSourcePosition(
15731cb0ef41Sopenharmony_ci        {debug_info.file, debug_info.line});
15741cb0ef41Sopenharmony_ci  }
15751cb0ef41Sopenharmony_ci  state_->raw_assembler_->Bind(label_, debug_info);
15761cb0ef41Sopenharmony_ci  UpdateVariablesAfterBind();
15771cb0ef41Sopenharmony_ci}
15781cb0ef41Sopenharmony_ci#endif  // DEBUG
15791cb0ef41Sopenharmony_ci
15801cb0ef41Sopenharmony_civoid CodeAssemblerLabel::Bind() {
15811cb0ef41Sopenharmony_ci  DCHECK(!bound_);
15821cb0ef41Sopenharmony_ci  state_->raw_assembler_->Bind(label_);
15831cb0ef41Sopenharmony_ci  UpdateVariablesAfterBind();
15841cb0ef41Sopenharmony_ci}
15851cb0ef41Sopenharmony_ci
15861cb0ef41Sopenharmony_civoid CodeAssemblerLabel::UpdateVariablesAfterBind() {
15871cb0ef41Sopenharmony_ci  // Make sure that all variables that have changed along any path up to this
15881cb0ef41Sopenharmony_ci  // point are marked as merge variables.
15891cb0ef41Sopenharmony_ci  for (auto var : state_->variables_) {
15901cb0ef41Sopenharmony_ci    Node* shared_value = nullptr;
15911cb0ef41Sopenharmony_ci    auto i = variable_merges_.find(var);
15921cb0ef41Sopenharmony_ci    if (i != variable_merges_.end()) {
15931cb0ef41Sopenharmony_ci      for (auto value : i->second) {
15941cb0ef41Sopenharmony_ci        DCHECK_NOT_NULL(value);
15951cb0ef41Sopenharmony_ci        if (value != shared_value) {
15961cb0ef41Sopenharmony_ci          if (shared_value == nullptr) {
15971cb0ef41Sopenharmony_ci            shared_value = value;
15981cb0ef41Sopenharmony_ci          } else {
15991cb0ef41Sopenharmony_ci            variable_phis_[var] = nullptr;
16001cb0ef41Sopenharmony_ci          }
16011cb0ef41Sopenharmony_ci        }
16021cb0ef41Sopenharmony_ci      }
16031cb0ef41Sopenharmony_ci    }
16041cb0ef41Sopenharmony_ci  }
16051cb0ef41Sopenharmony_ci
16061cb0ef41Sopenharmony_ci  for (auto var : variable_phis_) {
16071cb0ef41Sopenharmony_ci    CodeAssemblerVariable::Impl* var_impl = var.first;
16081cb0ef41Sopenharmony_ci    auto i = variable_merges_.find(var_impl);
16091cb0ef41Sopenharmony_ci#if DEBUG
16101cb0ef41Sopenharmony_ci    bool not_found = i == variable_merges_.end();
16111cb0ef41Sopenharmony_ci    if (not_found || i->second.size() != merge_count_) {
16121cb0ef41Sopenharmony_ci      std::stringstream str;
16131cb0ef41Sopenharmony_ci      str << "A variable that has been marked as beeing merged at the label"
16141cb0ef41Sopenharmony_ci          << "\n# doesn't have a bound value along all of the paths that "
16151cb0ef41Sopenharmony_ci          << "\n# have been merged into the label up to this point."
16161cb0ef41Sopenharmony_ci          << "\n#"
16171cb0ef41Sopenharmony_ci          << "\n# This can happen in the following cases:"
16181cb0ef41Sopenharmony_ci          << "\n# - By explicitly marking it so in the label constructor"
16191cb0ef41Sopenharmony_ci          << "\n# - By having seen different bound values at branches"
16201cb0ef41Sopenharmony_ci          << "\n#"
16211cb0ef41Sopenharmony_ci          << "\n# Merge count:     expected=" << merge_count_
16221cb0ef41Sopenharmony_ci          << " vs. found=" << (not_found ? 0 : i->second.size())
16231cb0ef41Sopenharmony_ci          << "\n# Variable:      " << *var_impl
16241cb0ef41Sopenharmony_ci          << "\n# Current Block: " << *label_->block();
16251cb0ef41Sopenharmony_ci      FATAL("%s", str.str().c_str());
16261cb0ef41Sopenharmony_ci    }
16271cb0ef41Sopenharmony_ci#endif  // DEBUG
16281cb0ef41Sopenharmony_ci    Node* phi = state_->raw_assembler_->Phi(
16291cb0ef41Sopenharmony_ci        var.first->rep_, static_cast<int>(merge_count_), &(i->second[0]));
16301cb0ef41Sopenharmony_ci    variable_phis_[var_impl] = phi;
16311cb0ef41Sopenharmony_ci  }
16321cb0ef41Sopenharmony_ci
16331cb0ef41Sopenharmony_ci  // Bind all variables to a merge phi, the common value along all paths or
16341cb0ef41Sopenharmony_ci  // null.
16351cb0ef41Sopenharmony_ci  for (auto var : state_->variables_) {
16361cb0ef41Sopenharmony_ci    auto i = variable_phis_.find(var);
16371cb0ef41Sopenharmony_ci    if (i != variable_phis_.end()) {
16381cb0ef41Sopenharmony_ci      var->value_ = i->second;
16391cb0ef41Sopenharmony_ci    } else {
16401cb0ef41Sopenharmony_ci      auto j = variable_merges_.find(var);
16411cb0ef41Sopenharmony_ci      if (j != variable_merges_.end() && j->second.size() == merge_count_) {
16421cb0ef41Sopenharmony_ci        var->value_ = j->second.back();
16431cb0ef41Sopenharmony_ci      } else {
16441cb0ef41Sopenharmony_ci        var->value_ = nullptr;
16451cb0ef41Sopenharmony_ci      }
16461cb0ef41Sopenharmony_ci    }
16471cb0ef41Sopenharmony_ci  }
16481cb0ef41Sopenharmony_ci
16491cb0ef41Sopenharmony_ci  bound_ = true;
16501cb0ef41Sopenharmony_ci}
16511cb0ef41Sopenharmony_ci
16521cb0ef41Sopenharmony_civoid CodeAssemblerParameterizedLabelBase::AddInputs(std::vector<Node*> inputs) {
16531cb0ef41Sopenharmony_ci  if (!phi_nodes_.empty()) {
16541cb0ef41Sopenharmony_ci    DCHECK_EQ(inputs.size(), phi_nodes_.size());
16551cb0ef41Sopenharmony_ci    for (size_t i = 0; i < inputs.size(); ++i) {
16561cb0ef41Sopenharmony_ci      // We use {nullptr} as a sentinel for an uninitialized value.
16571cb0ef41Sopenharmony_ci      if (phi_nodes_[i] == nullptr) continue;
16581cb0ef41Sopenharmony_ci      state_->raw_assembler_->AppendPhiInput(phi_nodes_[i], inputs[i]);
16591cb0ef41Sopenharmony_ci    }
16601cb0ef41Sopenharmony_ci  } else {
16611cb0ef41Sopenharmony_ci    DCHECK_EQ(inputs.size(), phi_inputs_.size());
16621cb0ef41Sopenharmony_ci    for (size_t i = 0; i < inputs.size(); ++i) {
16631cb0ef41Sopenharmony_ci      phi_inputs_[i].push_back(inputs[i]);
16641cb0ef41Sopenharmony_ci    }
16651cb0ef41Sopenharmony_ci  }
16661cb0ef41Sopenharmony_ci}
16671cb0ef41Sopenharmony_ci
16681cb0ef41Sopenharmony_ciNode* CodeAssemblerParameterizedLabelBase::CreatePhi(
16691cb0ef41Sopenharmony_ci    MachineRepresentation rep, const std::vector<Node*>& inputs) {
16701cb0ef41Sopenharmony_ci  for (Node* input : inputs) {
16711cb0ef41Sopenharmony_ci    // We use {nullptr} as a sentinel for an uninitialized value. We must not
16721cb0ef41Sopenharmony_ci    // create phi nodes for these.
16731cb0ef41Sopenharmony_ci    if (input == nullptr) return nullptr;
16741cb0ef41Sopenharmony_ci  }
16751cb0ef41Sopenharmony_ci  return state_->raw_assembler_->Phi(rep, static_cast<int>(inputs.size()),
16761cb0ef41Sopenharmony_ci                                     &inputs.front());
16771cb0ef41Sopenharmony_ci}
16781cb0ef41Sopenharmony_ci
16791cb0ef41Sopenharmony_ciconst std::vector<Node*>& CodeAssemblerParameterizedLabelBase::CreatePhis(
16801cb0ef41Sopenharmony_ci    std::vector<MachineRepresentation> representations) {
16811cb0ef41Sopenharmony_ci  DCHECK(is_used());
16821cb0ef41Sopenharmony_ci  DCHECK(phi_nodes_.empty());
16831cb0ef41Sopenharmony_ci  phi_nodes_.reserve(phi_inputs_.size());
16841cb0ef41Sopenharmony_ci  DCHECK_EQ(representations.size(), phi_inputs_.size());
16851cb0ef41Sopenharmony_ci  for (size_t i = 0; i < phi_inputs_.size(); ++i) {
16861cb0ef41Sopenharmony_ci    phi_nodes_.push_back(CreatePhi(representations[i], phi_inputs_[i]));
16871cb0ef41Sopenharmony_ci  }
16881cb0ef41Sopenharmony_ci  return phi_nodes_;
16891cb0ef41Sopenharmony_ci}
16901cb0ef41Sopenharmony_ci
16911cb0ef41Sopenharmony_civoid CodeAssemblerState::PushExceptionHandler(
16921cb0ef41Sopenharmony_ci    CodeAssemblerExceptionHandlerLabel* label) {
16931cb0ef41Sopenharmony_ci  exception_handler_labels_.push_back(label);
16941cb0ef41Sopenharmony_ci}
16951cb0ef41Sopenharmony_ci
16961cb0ef41Sopenharmony_civoid CodeAssemblerState::PopExceptionHandler() {
16971cb0ef41Sopenharmony_ci  exception_handler_labels_.pop_back();
16981cb0ef41Sopenharmony_ci}
16991cb0ef41Sopenharmony_ci
17001cb0ef41Sopenharmony_ciScopedExceptionHandler::ScopedExceptionHandler(
17011cb0ef41Sopenharmony_ci    CodeAssembler* assembler, CodeAssemblerExceptionHandlerLabel* label)
17021cb0ef41Sopenharmony_ci    : has_handler_(label != nullptr),
17031cb0ef41Sopenharmony_ci      assembler_(assembler),
17041cb0ef41Sopenharmony_ci      compatibility_label_(nullptr),
17051cb0ef41Sopenharmony_ci      exception_(nullptr) {
17061cb0ef41Sopenharmony_ci  if (has_handler_) {
17071cb0ef41Sopenharmony_ci    assembler_->state()->PushExceptionHandler(label);
17081cb0ef41Sopenharmony_ci  }
17091cb0ef41Sopenharmony_ci}
17101cb0ef41Sopenharmony_ci
17111cb0ef41Sopenharmony_ciScopedExceptionHandler::ScopedExceptionHandler(
17121cb0ef41Sopenharmony_ci    CodeAssembler* assembler, CodeAssemblerLabel* label,
17131cb0ef41Sopenharmony_ci    TypedCodeAssemblerVariable<Object>* exception)
17141cb0ef41Sopenharmony_ci    : has_handler_(label != nullptr),
17151cb0ef41Sopenharmony_ci      assembler_(assembler),
17161cb0ef41Sopenharmony_ci      compatibility_label_(label),
17171cb0ef41Sopenharmony_ci      exception_(exception) {
17181cb0ef41Sopenharmony_ci  if (has_handler_) {
17191cb0ef41Sopenharmony_ci    label_ = std::make_unique<CodeAssemblerExceptionHandlerLabel>(
17201cb0ef41Sopenharmony_ci        assembler, CodeAssemblerLabel::kDeferred);
17211cb0ef41Sopenharmony_ci    assembler_->state()->PushExceptionHandler(label_.get());
17221cb0ef41Sopenharmony_ci  }
17231cb0ef41Sopenharmony_ci}
17241cb0ef41Sopenharmony_ci
17251cb0ef41Sopenharmony_ciScopedExceptionHandler::~ScopedExceptionHandler() {
17261cb0ef41Sopenharmony_ci  if (has_handler_) {
17271cb0ef41Sopenharmony_ci    assembler_->state()->PopExceptionHandler();
17281cb0ef41Sopenharmony_ci  }
17291cb0ef41Sopenharmony_ci  if (label_ && label_->is_used()) {
17301cb0ef41Sopenharmony_ci    CodeAssembler::Label skip(assembler_);
17311cb0ef41Sopenharmony_ci    bool inside_block = assembler_->state()->InsideBlock();
17321cb0ef41Sopenharmony_ci    if (inside_block) {
17331cb0ef41Sopenharmony_ci      assembler_->Goto(&skip);
17341cb0ef41Sopenharmony_ci    }
17351cb0ef41Sopenharmony_ci    TNode<Object> e;
17361cb0ef41Sopenharmony_ci    assembler_->Bind(label_.get(), &e);
17371cb0ef41Sopenharmony_ci    if (exception_ != nullptr) *exception_ = e;
17381cb0ef41Sopenharmony_ci    assembler_->Goto(compatibility_label_);
17391cb0ef41Sopenharmony_ci    if (inside_block) {
17401cb0ef41Sopenharmony_ci      assembler_->Bind(&skip);
17411cb0ef41Sopenharmony_ci    }
17421cb0ef41Sopenharmony_ci  }
17431cb0ef41Sopenharmony_ci}
17441cb0ef41Sopenharmony_ci
17451cb0ef41Sopenharmony_ci}  // namespace compiler
17461cb0ef41Sopenharmony_ci
17471cb0ef41Sopenharmony_ci}  // namespace internal
17481cb0ef41Sopenharmony_ci}  // namespace v8
1749