11cb0ef41Sopenharmony_ci// Copyright 2014 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_ 61cb0ef41Sopenharmony_ci#define V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <initializer_list> 91cb0ef41Sopenharmony_ci#include <type_traits> 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#include "src/codegen/assembler.h" 121cb0ef41Sopenharmony_ci#include "src/common/globals.h" 131cb0ef41Sopenharmony_ci#include "src/compiler/access-builder.h" 141cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h" 151cb0ef41Sopenharmony_ci#include "src/compiler/graph.h" 161cb0ef41Sopenharmony_ci#include "src/compiler/linkage.h" 171cb0ef41Sopenharmony_ci#include "src/compiler/machine-operator.h" 181cb0ef41Sopenharmony_ci#include "src/compiler/node-matchers.h" 191cb0ef41Sopenharmony_ci#include "src/compiler/node.h" 201cb0ef41Sopenharmony_ci#include "src/compiler/operator.h" 211cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator.h" 221cb0ef41Sopenharmony_ci#include "src/compiler/write-barrier-kind.h" 231cb0ef41Sopenharmony_ci#include "src/execution/isolate.h" 241cb0ef41Sopenharmony_ci#include "src/heap/factory.h" 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_cinamespace v8 { 271cb0ef41Sopenharmony_cinamespace internal { 281cb0ef41Sopenharmony_cinamespace compiler { 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciclass BasicBlock; 311cb0ef41Sopenharmony_ciclass RawMachineLabel; 321cb0ef41Sopenharmony_ciclass Schedule; 331cb0ef41Sopenharmony_ciclass SourcePositionTable; 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci// The RawMachineAssembler produces a low-level IR graph. All nodes are wired 361cb0ef41Sopenharmony_ci// into a graph and also placed into a schedule immediately, hence subsequent 371cb0ef41Sopenharmony_ci// code generation can happen without the need for scheduling. 381cb0ef41Sopenharmony_ci// 391cb0ef41Sopenharmony_ci// In order to create a schedule on-the-fly, the assembler keeps track of basic 401cb0ef41Sopenharmony_ci// blocks by having one current basic block being populated and by referencing 411cb0ef41Sopenharmony_ci// other basic blocks through the use of labels. 421cb0ef41Sopenharmony_ci// 431cb0ef41Sopenharmony_ci// Also note that the generated graph is only valid together with the generated 441cb0ef41Sopenharmony_ci// schedule, using one without the other is invalid as the graph is inherently 451cb0ef41Sopenharmony_ci// non-schedulable due to missing control and effect dependencies. 461cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE RawMachineAssembler { 471cb0ef41Sopenharmony_ci public: 481cb0ef41Sopenharmony_ci RawMachineAssembler( 491cb0ef41Sopenharmony_ci Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor, 501cb0ef41Sopenharmony_ci MachineRepresentation word = MachineType::PointerRepresentation(), 511cb0ef41Sopenharmony_ci MachineOperatorBuilder::Flags flags = 521cb0ef41Sopenharmony_ci MachineOperatorBuilder::Flag::kNoFlags, 531cb0ef41Sopenharmony_ci MachineOperatorBuilder::AlignmentRequirements alignment_requirements = 541cb0ef41Sopenharmony_ci MachineOperatorBuilder::AlignmentRequirements:: 551cb0ef41Sopenharmony_ci FullUnalignedAccessSupport()); 561cb0ef41Sopenharmony_ci ~RawMachineAssembler() = default; 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci RawMachineAssembler(const RawMachineAssembler&) = delete; 591cb0ef41Sopenharmony_ci RawMachineAssembler& operator=(const RawMachineAssembler&) = delete; 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ci Isolate* isolate() const { return isolate_; } 621cb0ef41Sopenharmony_ci Graph* graph() const { return graph_; } 631cb0ef41Sopenharmony_ci Zone* zone() const { return graph()->zone(); } 641cb0ef41Sopenharmony_ci MachineOperatorBuilder* machine() { return &machine_; } 651cb0ef41Sopenharmony_ci CommonOperatorBuilder* common() { return &common_; } 661cb0ef41Sopenharmony_ci SimplifiedOperatorBuilder* simplified() { return &simplified_; } 671cb0ef41Sopenharmony_ci CallDescriptor* call_descriptor() const { return call_descriptor_; } 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci // Only used for tests: Finalizes the schedule and exports it to be used for 701cb0ef41Sopenharmony_ci // code generation. Note that this RawMachineAssembler becomes invalid after 711cb0ef41Sopenharmony_ci // export. 721cb0ef41Sopenharmony_ci Schedule* ExportForTest(); 731cb0ef41Sopenharmony_ci // Finalizes the schedule and transforms it into a graph that's suitable for 741cb0ef41Sopenharmony_ci // it to be used for Turbofan optimization and re-scheduling. Note that this 751cb0ef41Sopenharmony_ci // RawMachineAssembler becomes invalid after export. 761cb0ef41Sopenharmony_ci Graph* ExportForOptimization(); 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci // =========================================================================== 791cb0ef41Sopenharmony_ci // The following utility methods create new nodes with specific operators and 801cb0ef41Sopenharmony_ci // place them into the current basic block. They don't perform control flow, 811cb0ef41Sopenharmony_ci // hence will not switch the current basic block. 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci Node* NullConstant(); 841cb0ef41Sopenharmony_ci Node* UndefinedConstant(); 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci // Constants. 871cb0ef41Sopenharmony_ci Node* PointerConstant(void* value) { 881cb0ef41Sopenharmony_ci return IntPtrConstant(reinterpret_cast<intptr_t>(value)); 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci Node* IntPtrConstant(intptr_t value) { 911cb0ef41Sopenharmony_ci // TODO(dcarney): mark generated code as unserializable if value != 0. 921cb0ef41Sopenharmony_ci return kSystemPointerSize == 8 ? Int64Constant(value) 931cb0ef41Sopenharmony_ci : Int32Constant(static_cast<int>(value)); 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode); 961cb0ef41Sopenharmony_ci Node* Int32Constant(int32_t value) { 971cb0ef41Sopenharmony_ci return AddNode(common()->Int32Constant(value)); 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci Node* StackSlot(MachineRepresentation rep, int alignment = 0) { 1001cb0ef41Sopenharmony_ci return AddNode(machine()->StackSlot(rep, alignment)); 1011cb0ef41Sopenharmony_ci } 1021cb0ef41Sopenharmony_ci Node* Int64Constant(int64_t value) { 1031cb0ef41Sopenharmony_ci return AddNode(common()->Int64Constant(value)); 1041cb0ef41Sopenharmony_ci } 1051cb0ef41Sopenharmony_ci Node* NumberConstant(double value) { 1061cb0ef41Sopenharmony_ci return AddNode(common()->NumberConstant(value)); 1071cb0ef41Sopenharmony_ci } 1081cb0ef41Sopenharmony_ci Node* Float32Constant(float value) { 1091cb0ef41Sopenharmony_ci return AddNode(common()->Float32Constant(value)); 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci Node* Float64Constant(double value) { 1121cb0ef41Sopenharmony_ci return AddNode(common()->Float64Constant(value)); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci Node* HeapConstant(Handle<HeapObject> object) { 1151cb0ef41Sopenharmony_ci return AddNode(common()->HeapConstant(object)); 1161cb0ef41Sopenharmony_ci } 1171cb0ef41Sopenharmony_ci Node* ExternalConstant(ExternalReference address) { 1181cb0ef41Sopenharmony_ci return AddNode(common()->ExternalConstant(address)); 1191cb0ef41Sopenharmony_ci } 1201cb0ef41Sopenharmony_ci Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) { 1211cb0ef41Sopenharmony_ci return AddNode(common()->RelocatableInt32Constant(value, rmode)); 1221cb0ef41Sopenharmony_ci } 1231cb0ef41Sopenharmony_ci Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) { 1241cb0ef41Sopenharmony_ci return AddNode(common()->RelocatableInt64Constant(value, rmode)); 1251cb0ef41Sopenharmony_ci } 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci Node* Projection(int index, Node* a) { 1281cb0ef41Sopenharmony_ci return AddNode(common()->Projection(index), a); 1291cb0ef41Sopenharmony_ci } 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci // Memory Operations. 1321cb0ef41Sopenharmony_ci Node* Load(MachineType type, Node* base) { 1331cb0ef41Sopenharmony_ci return Load(type, base, IntPtrConstant(0)); 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci Node* Load(MachineType type, Node* base, Node* index) { 1361cb0ef41Sopenharmony_ci const Operator* op = machine()->Load(type); 1371cb0ef41Sopenharmony_ci Node* load = AddNode(op, base, index); 1381cb0ef41Sopenharmony_ci return load; 1391cb0ef41Sopenharmony_ci } 1401cb0ef41Sopenharmony_ci Node* LoadImmutable(MachineType type, Node* base) { 1411cb0ef41Sopenharmony_ci return LoadImmutable(type, base, IntPtrConstant(0)); 1421cb0ef41Sopenharmony_ci } 1431cb0ef41Sopenharmony_ci Node* LoadImmutable(MachineType type, Node* base, Node* index) { 1441cb0ef41Sopenharmony_ci const Operator* op = machine()->LoadImmutable(type); 1451cb0ef41Sopenharmony_ci return AddNode(op, base, index); 1461cb0ef41Sopenharmony_ci } 1471cb0ef41Sopenharmony_ci bool IsMapOffsetConstant(Node* node) { 1481cb0ef41Sopenharmony_ci Int64Matcher m(node); 1491cb0ef41Sopenharmony_ci if (m.Is(HeapObject::kMapOffset)) return true; 1501cb0ef41Sopenharmony_ci // Test if `node` is a `Phi(Int64Constant(0))` 1511cb0ef41Sopenharmony_ci if (node->opcode() == IrOpcode::kPhi) { 1521cb0ef41Sopenharmony_ci for (Node* input : node->inputs()) { 1531cb0ef41Sopenharmony_ci if (!Int64Matcher(input).Is(HeapObject::kMapOffset)) return false; 1541cb0ef41Sopenharmony_ci } 1551cb0ef41Sopenharmony_ci return true; 1561cb0ef41Sopenharmony_ci } 1571cb0ef41Sopenharmony_ci return false; 1581cb0ef41Sopenharmony_ci } 1591cb0ef41Sopenharmony_ci bool IsMapOffsetConstantMinusTag(Node* node) { 1601cb0ef41Sopenharmony_ci Int64Matcher m(node); 1611cb0ef41Sopenharmony_ci return m.Is(HeapObject::kMapOffset - kHeapObjectTag); 1621cb0ef41Sopenharmony_ci } 1631cb0ef41Sopenharmony_ci bool IsMapOffsetConstantMinusTag(int offset) { 1641cb0ef41Sopenharmony_ci return offset == HeapObject::kMapOffset - kHeapObjectTag; 1651cb0ef41Sopenharmony_ci } 1661cb0ef41Sopenharmony_ci Node* LoadFromObject(MachineType type, Node* base, Node* offset) { 1671cb0ef41Sopenharmony_ci DCHECK_IMPLIES(V8_MAP_PACKING_BOOL && IsMapOffsetConstantMinusTag(offset), 1681cb0ef41Sopenharmony_ci type == MachineType::MapInHeader()); 1691cb0ef41Sopenharmony_ci ObjectAccess access = {type, WriteBarrierKind::kNoWriteBarrier}; 1701cb0ef41Sopenharmony_ci Node* load = AddNode(simplified()->LoadFromObject(access), base, offset); 1711cb0ef41Sopenharmony_ci return load; 1721cb0ef41Sopenharmony_ci } 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_ci Node* Store(MachineRepresentation rep, Node* base, Node* value, 1751cb0ef41Sopenharmony_ci WriteBarrierKind write_barrier) { 1761cb0ef41Sopenharmony_ci return Store(rep, base, IntPtrConstant(0), value, write_barrier); 1771cb0ef41Sopenharmony_ci } 1781cb0ef41Sopenharmony_ci Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value, 1791cb0ef41Sopenharmony_ci WriteBarrierKind write_barrier) { 1801cb0ef41Sopenharmony_ci return AddNode(machine()->Store(StoreRepresentation(rep, write_barrier)), 1811cb0ef41Sopenharmony_ci base, index, value); 1821cb0ef41Sopenharmony_ci } 1831cb0ef41Sopenharmony_ci void StoreToObject(MachineRepresentation rep, Node* object, Node* offset, 1841cb0ef41Sopenharmony_ci Node* value, WriteBarrierKind write_barrier) { 1851cb0ef41Sopenharmony_ci ObjectAccess access = {MachineType::TypeForRepresentation(rep), 1861cb0ef41Sopenharmony_ci write_barrier}; 1871cb0ef41Sopenharmony_ci DCHECK(!IsMapOffsetConstantMinusTag(offset)); 1881cb0ef41Sopenharmony_ci AddNode(simplified()->StoreToObject(access), object, offset, value); 1891cb0ef41Sopenharmony_ci } 1901cb0ef41Sopenharmony_ci void OptimizedStoreField(MachineRepresentation rep, Node* object, int offset, 1911cb0ef41Sopenharmony_ci Node* value, WriteBarrierKind write_barrier) { 1921cb0ef41Sopenharmony_ci DCHECK(!IsMapOffsetConstantMinusTag(offset)); 1931cb0ef41Sopenharmony_ci AddNode(simplified()->StoreField(FieldAccess( 1941cb0ef41Sopenharmony_ci BaseTaggedness::kTaggedBase, offset, MaybeHandle<Name>(), 1951cb0ef41Sopenharmony_ci MaybeHandle<Map>(), Type::Any(), 1961cb0ef41Sopenharmony_ci MachineType::TypeForRepresentation(rep), write_barrier)), 1971cb0ef41Sopenharmony_ci object, value); 1981cb0ef41Sopenharmony_ci } 1991cb0ef41Sopenharmony_ci void OptimizedStoreMap(Node* object, Node* value, 2001cb0ef41Sopenharmony_ci WriteBarrierKind write_barrier = kMapWriteBarrier) { 2011cb0ef41Sopenharmony_ci AddNode(simplified()->StoreField(AccessBuilder::ForMap(write_barrier)), 2021cb0ef41Sopenharmony_ci object, value); 2031cb0ef41Sopenharmony_ci } 2041cb0ef41Sopenharmony_ci Node* Retain(Node* value) { return AddNode(common()->Retain(), value); } 2051cb0ef41Sopenharmony_ci 2061cb0ef41Sopenharmony_ci Node* OptimizedAllocate(Node* size, AllocationType allocation, 2071cb0ef41Sopenharmony_ci AllowLargeObjects allow_large_objects); 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci // Unaligned memory operations 2101cb0ef41Sopenharmony_ci Node* UnalignedLoad(MachineType type, Node* base) { 2111cb0ef41Sopenharmony_ci return UnalignedLoad(type, base, IntPtrConstant(0)); 2121cb0ef41Sopenharmony_ci } 2131cb0ef41Sopenharmony_ci Node* UnalignedLoad(MachineType type, Node* base, Node* index) { 2141cb0ef41Sopenharmony_ci MachineRepresentation rep = type.representation(); 2151cb0ef41Sopenharmony_ci // Tagged or compressed should never be unaligned 2161cb0ef41Sopenharmony_ci DCHECK(!(IsAnyTagged(rep) || IsAnyCompressed(rep))); 2171cb0ef41Sopenharmony_ci if (machine()->UnalignedLoadSupported(rep)) { 2181cb0ef41Sopenharmony_ci return AddNode(machine()->Load(type), base, index); 2191cb0ef41Sopenharmony_ci } else { 2201cb0ef41Sopenharmony_ci return AddNode(machine()->UnalignedLoad(type), base, index); 2211cb0ef41Sopenharmony_ci } 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci Node* UnalignedStore(MachineRepresentation rep, Node* base, Node* value) { 2241cb0ef41Sopenharmony_ci return UnalignedStore(rep, base, IntPtrConstant(0), value); 2251cb0ef41Sopenharmony_ci } 2261cb0ef41Sopenharmony_ci Node* UnalignedStore(MachineRepresentation rep, Node* base, Node* index, 2271cb0ef41Sopenharmony_ci Node* value) { 2281cb0ef41Sopenharmony_ci // Tagged or compressed should never be unaligned 2291cb0ef41Sopenharmony_ci DCHECK(!(IsAnyTagged(rep) || IsAnyCompressed(rep))); 2301cb0ef41Sopenharmony_ci if (machine()->UnalignedStoreSupported(rep)) { 2311cb0ef41Sopenharmony_ci return AddNode(machine()->Store(StoreRepresentation( 2321cb0ef41Sopenharmony_ci rep, WriteBarrierKind::kNoWriteBarrier)), 2331cb0ef41Sopenharmony_ci base, index, value); 2341cb0ef41Sopenharmony_ci } else { 2351cb0ef41Sopenharmony_ci return AddNode( 2361cb0ef41Sopenharmony_ci machine()->UnalignedStore(UnalignedStoreRepresentation(rep)), base, 2371cb0ef41Sopenharmony_ci index, value); 2381cb0ef41Sopenharmony_ci } 2391cb0ef41Sopenharmony_ci } 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci // Atomic memory operations. 2421cb0ef41Sopenharmony_ci Node* AtomicLoad(AtomicLoadParameters rep, Node* base, Node* index) { 2431cb0ef41Sopenharmony_ci DCHECK_NE(rep.representation().representation(), 2441cb0ef41Sopenharmony_ci MachineRepresentation::kWord64); 2451cb0ef41Sopenharmony_ci return AddNode(machine()->Word32AtomicLoad(rep), base, index); 2461cb0ef41Sopenharmony_ci } 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci Node* AtomicLoad64(AtomicLoadParameters rep, Node* base, Node* index) { 2491cb0ef41Sopenharmony_ci if (machine()->Is64()) { 2501cb0ef41Sopenharmony_ci // This uses Uint64() intentionally: AtomicLoad is not implemented for 2511cb0ef41Sopenharmony_ci // Int64(), which is fine because the machine instruction only cares 2521cb0ef41Sopenharmony_ci // about words. 2531cb0ef41Sopenharmony_ci return AddNode(machine()->Word64AtomicLoad(rep), base, index); 2541cb0ef41Sopenharmony_ci } else { 2551cb0ef41Sopenharmony_ci return AddNode(machine()->Word32AtomicPairLoad(rep.order()), base, index); 2561cb0ef41Sopenharmony_ci } 2571cb0ef41Sopenharmony_ci } 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci#if defined(V8_TARGET_BIG_ENDIAN) 2601cb0ef41Sopenharmony_ci#define VALUE_HALVES value_high, value 2611cb0ef41Sopenharmony_ci#else 2621cb0ef41Sopenharmony_ci#define VALUE_HALVES value, value_high 2631cb0ef41Sopenharmony_ci#endif 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ci Node* AtomicStore(AtomicStoreParameters params, Node* base, Node* index, 2661cb0ef41Sopenharmony_ci Node* value) { 2671cb0ef41Sopenharmony_ci DCHECK(!IsMapOffsetConstantMinusTag(index)); 2681cb0ef41Sopenharmony_ci DCHECK_NE(params.representation(), MachineRepresentation::kWord64); 2691cb0ef41Sopenharmony_ci return AddNode(machine()->Word32AtomicStore(params), base, index, value); 2701cb0ef41Sopenharmony_ci } 2711cb0ef41Sopenharmony_ci 2721cb0ef41Sopenharmony_ci Node* AtomicStore64(AtomicStoreParameters params, Node* base, Node* index, 2731cb0ef41Sopenharmony_ci Node* value, Node* value_high) { 2741cb0ef41Sopenharmony_ci if (machine()->Is64()) { 2751cb0ef41Sopenharmony_ci DCHECK_NULL(value_high); 2761cb0ef41Sopenharmony_ci return AddNode(machine()->Word64AtomicStore(params), base, index, value); 2771cb0ef41Sopenharmony_ci } else { 2781cb0ef41Sopenharmony_ci DCHECK(params.representation() != MachineRepresentation::kTaggedPointer && 2791cb0ef41Sopenharmony_ci params.representation() != MachineRepresentation::kTaggedSigned && 2801cb0ef41Sopenharmony_ci params.representation() != MachineRepresentation::kTagged); 2811cb0ef41Sopenharmony_ci return AddNode(machine()->Word32AtomicPairStore(params.order()), base, 2821cb0ef41Sopenharmony_ci index, VALUE_HALVES); 2831cb0ef41Sopenharmony_ci } 2841cb0ef41Sopenharmony_ci } 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci#define ATOMIC_FUNCTION(name) \ 2871cb0ef41Sopenharmony_ci Node* Atomic##name(MachineType type, Node* base, Node* index, Node* value) { \ 2881cb0ef41Sopenharmony_ci DCHECK_NE(type.representation(), MachineRepresentation::kWord64); \ 2891cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Atomic##name(type), base, index, value); \ 2901cb0ef41Sopenharmony_ci } \ 2911cb0ef41Sopenharmony_ci Node* Atomic##name##64(Node * base, Node * index, Node * value, \ 2921cb0ef41Sopenharmony_ci Node * value_high) { \ 2931cb0ef41Sopenharmony_ci if (machine()->Is64()) { \ 2941cb0ef41Sopenharmony_ci DCHECK_NULL(value_high); \ 2951cb0ef41Sopenharmony_ci /* This uses Uint64() intentionally: Atomic operations are not */ \ 2961cb0ef41Sopenharmony_ci /* implemented for Int64(), which is fine because the machine */ \ 2971cb0ef41Sopenharmony_ci /* instruction only cares about words. */ \ 2981cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Atomic##name(MachineType::Uint64()), \ 2991cb0ef41Sopenharmony_ci base, index, value); \ 3001cb0ef41Sopenharmony_ci } else { \ 3011cb0ef41Sopenharmony_ci return AddNode(machine()->Word32AtomicPair##name(), base, index, \ 3021cb0ef41Sopenharmony_ci VALUE_HALVES); \ 3031cb0ef41Sopenharmony_ci } \ 3041cb0ef41Sopenharmony_ci } 3051cb0ef41Sopenharmony_ci ATOMIC_FUNCTION(Exchange) 3061cb0ef41Sopenharmony_ci ATOMIC_FUNCTION(Add) 3071cb0ef41Sopenharmony_ci ATOMIC_FUNCTION(Sub) 3081cb0ef41Sopenharmony_ci ATOMIC_FUNCTION(And) 3091cb0ef41Sopenharmony_ci ATOMIC_FUNCTION(Or) 3101cb0ef41Sopenharmony_ci ATOMIC_FUNCTION(Xor) 3111cb0ef41Sopenharmony_ci#undef ATOMIC_FUNCTION 3121cb0ef41Sopenharmony_ci#undef VALUE_HALVES 3131cb0ef41Sopenharmony_ci 3141cb0ef41Sopenharmony_ci Node* AtomicCompareExchange(MachineType type, Node* base, Node* index, 3151cb0ef41Sopenharmony_ci Node* old_value, Node* new_value) { 3161cb0ef41Sopenharmony_ci DCHECK_NE(type.representation(), MachineRepresentation::kWord64); 3171cb0ef41Sopenharmony_ci return AddNode(machine()->Word32AtomicCompareExchange(type), base, index, 3181cb0ef41Sopenharmony_ci old_value, new_value); 3191cb0ef41Sopenharmony_ci } 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_ci Node* AtomicCompareExchange64(Node* base, Node* index, Node* old_value, 3221cb0ef41Sopenharmony_ci Node* old_value_high, Node* new_value, 3231cb0ef41Sopenharmony_ci Node* new_value_high) { 3241cb0ef41Sopenharmony_ci if (machine()->Is64()) { 3251cb0ef41Sopenharmony_ci DCHECK_NULL(old_value_high); 3261cb0ef41Sopenharmony_ci DCHECK_NULL(new_value_high); 3271cb0ef41Sopenharmony_ci // This uses Uint64() intentionally: AtomicCompareExchange is not 3281cb0ef41Sopenharmony_ci // implemented for Int64(), which is fine because the machine instruction 3291cb0ef41Sopenharmony_ci // only cares about words. 3301cb0ef41Sopenharmony_ci return AddNode( 3311cb0ef41Sopenharmony_ci machine()->Word64AtomicCompareExchange(MachineType::Uint64()), base, 3321cb0ef41Sopenharmony_ci index, old_value, new_value); 3331cb0ef41Sopenharmony_ci } else { 3341cb0ef41Sopenharmony_ci return AddNode(machine()->Word32AtomicPairCompareExchange(), base, index, 3351cb0ef41Sopenharmony_ci old_value, old_value_high, new_value, new_value_high); 3361cb0ef41Sopenharmony_ci } 3371cb0ef41Sopenharmony_ci } 3381cb0ef41Sopenharmony_ci 3391cb0ef41Sopenharmony_ci // Arithmetic Operations. 3401cb0ef41Sopenharmony_ci Node* WordAnd(Node* a, Node* b) { 3411cb0ef41Sopenharmony_ci return AddNode(machine()->WordAnd(), a, b); 3421cb0ef41Sopenharmony_ci } 3431cb0ef41Sopenharmony_ci Node* WordOr(Node* a, Node* b) { return AddNode(machine()->WordOr(), a, b); } 3441cb0ef41Sopenharmony_ci Node* WordXor(Node* a, Node* b) { 3451cb0ef41Sopenharmony_ci return AddNode(machine()->WordXor(), a, b); 3461cb0ef41Sopenharmony_ci } 3471cb0ef41Sopenharmony_ci Node* WordShl(Node* a, Node* b) { 3481cb0ef41Sopenharmony_ci return AddNode(machine()->WordShl(), a, b); 3491cb0ef41Sopenharmony_ci } 3501cb0ef41Sopenharmony_ci Node* WordShr(Node* a, Node* b) { 3511cb0ef41Sopenharmony_ci return AddNode(machine()->WordShr(), a, b); 3521cb0ef41Sopenharmony_ci } 3531cb0ef41Sopenharmony_ci Node* WordSar(Node* a, Node* b) { 3541cb0ef41Sopenharmony_ci return AddNode(machine()->WordSar(), a, b); 3551cb0ef41Sopenharmony_ci } 3561cb0ef41Sopenharmony_ci Node* WordSarShiftOutZeros(Node* a, Node* b) { 3571cb0ef41Sopenharmony_ci return AddNode(machine()->WordSarShiftOutZeros(), a, b); 3581cb0ef41Sopenharmony_ci } 3591cb0ef41Sopenharmony_ci Node* WordRor(Node* a, Node* b) { 3601cb0ef41Sopenharmony_ci return AddNode(machine()->WordRor(), a, b); 3611cb0ef41Sopenharmony_ci } 3621cb0ef41Sopenharmony_ci Node* WordEqual(Node* a, Node* b) { 3631cb0ef41Sopenharmony_ci return AddNode(machine()->WordEqual(), a, b); 3641cb0ef41Sopenharmony_ci } 3651cb0ef41Sopenharmony_ci Node* WordNotEqual(Node* a, Node* b) { 3661cb0ef41Sopenharmony_ci return Word32BinaryNot(WordEqual(a, b)); 3671cb0ef41Sopenharmony_ci } 3681cb0ef41Sopenharmony_ci Node* WordNot(Node* a) { 3691cb0ef41Sopenharmony_ci if (machine()->Is32()) { 3701cb0ef41Sopenharmony_ci return Word32BitwiseNot(a); 3711cb0ef41Sopenharmony_ci } else { 3721cb0ef41Sopenharmony_ci return Word64Not(a); 3731cb0ef41Sopenharmony_ci } 3741cb0ef41Sopenharmony_ci } 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_ci Node* Word32And(Node* a, Node* b) { 3771cb0ef41Sopenharmony_ci return AddNode(machine()->Word32And(), a, b); 3781cb0ef41Sopenharmony_ci } 3791cb0ef41Sopenharmony_ci Node* Word32Or(Node* a, Node* b) { 3801cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Or(), a, b); 3811cb0ef41Sopenharmony_ci } 3821cb0ef41Sopenharmony_ci Node* Word32Xor(Node* a, Node* b) { 3831cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Xor(), a, b); 3841cb0ef41Sopenharmony_ci } 3851cb0ef41Sopenharmony_ci Node* Word32Shl(Node* a, Node* b) { 3861cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Shl(), a, b); 3871cb0ef41Sopenharmony_ci } 3881cb0ef41Sopenharmony_ci Node* Word32Shr(Node* a, Node* b) { 3891cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Shr(), a, b); 3901cb0ef41Sopenharmony_ci } 3911cb0ef41Sopenharmony_ci Node* Word32Sar(Node* a, Node* b) { 3921cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Sar(), a, b); 3931cb0ef41Sopenharmony_ci } 3941cb0ef41Sopenharmony_ci Node* Word32SarShiftOutZeros(Node* a, Node* b) { 3951cb0ef41Sopenharmony_ci return AddNode(machine()->Word32SarShiftOutZeros(), a, b); 3961cb0ef41Sopenharmony_ci } 3971cb0ef41Sopenharmony_ci Node* Word32Ror(Node* a, Node* b) { 3981cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Ror(), a, b); 3991cb0ef41Sopenharmony_ci } 4001cb0ef41Sopenharmony_ci Node* Word32Clz(Node* a) { return AddNode(machine()->Word32Clz(), a); } 4011cb0ef41Sopenharmony_ci Node* Word32Equal(Node* a, Node* b) { 4021cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Equal(), a, b); 4031cb0ef41Sopenharmony_ci } 4041cb0ef41Sopenharmony_ci Node* Word32NotEqual(Node* a, Node* b) { 4051cb0ef41Sopenharmony_ci return Word32BinaryNot(Word32Equal(a, b)); 4061cb0ef41Sopenharmony_ci } 4071cb0ef41Sopenharmony_ci Node* Word32BitwiseNot(Node* a) { return Word32Xor(a, Int32Constant(-1)); } 4081cb0ef41Sopenharmony_ci Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); } 4091cb0ef41Sopenharmony_ci 4101cb0ef41Sopenharmony_ci Node* Word64And(Node* a, Node* b) { 4111cb0ef41Sopenharmony_ci return AddNode(machine()->Word64And(), a, b); 4121cb0ef41Sopenharmony_ci } 4131cb0ef41Sopenharmony_ci Node* Word64Or(Node* a, Node* b) { 4141cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Or(), a, b); 4151cb0ef41Sopenharmony_ci } 4161cb0ef41Sopenharmony_ci Node* Word64Xor(Node* a, Node* b) { 4171cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Xor(), a, b); 4181cb0ef41Sopenharmony_ci } 4191cb0ef41Sopenharmony_ci Node* Word64Shl(Node* a, Node* b) { 4201cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Shl(), a, b); 4211cb0ef41Sopenharmony_ci } 4221cb0ef41Sopenharmony_ci Node* Word64Shr(Node* a, Node* b) { 4231cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Shr(), a, b); 4241cb0ef41Sopenharmony_ci } 4251cb0ef41Sopenharmony_ci Node* Word64Sar(Node* a, Node* b) { 4261cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Sar(), a, b); 4271cb0ef41Sopenharmony_ci } 4281cb0ef41Sopenharmony_ci Node* Word64Ror(Node* a, Node* b) { 4291cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Ror(), a, b); 4301cb0ef41Sopenharmony_ci } 4311cb0ef41Sopenharmony_ci Node* Word64Clz(Node* a) { return AddNode(machine()->Word64Clz(), a); } 4321cb0ef41Sopenharmony_ci Node* Word64Equal(Node* a, Node* b) { 4331cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Equal(), a, b); 4341cb0ef41Sopenharmony_ci } 4351cb0ef41Sopenharmony_ci Node* Word64NotEqual(Node* a, Node* b) { 4361cb0ef41Sopenharmony_ci return Word32BinaryNot(Word64Equal(a, b)); 4371cb0ef41Sopenharmony_ci } 4381cb0ef41Sopenharmony_ci Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); } 4391cb0ef41Sopenharmony_ci 4401cb0ef41Sopenharmony_ci Node* Int32Add(Node* a, Node* b) { 4411cb0ef41Sopenharmony_ci return AddNode(machine()->Int32Add(), a, b); 4421cb0ef41Sopenharmony_ci } 4431cb0ef41Sopenharmony_ci Node* Int32AddWithOverflow(Node* a, Node* b) { 4441cb0ef41Sopenharmony_ci return AddNode(machine()->Int32AddWithOverflow(), a, b); 4451cb0ef41Sopenharmony_ci } 4461cb0ef41Sopenharmony_ci Node* Int32Sub(Node* a, Node* b) { 4471cb0ef41Sopenharmony_ci return AddNode(machine()->Int32Sub(), a, b); 4481cb0ef41Sopenharmony_ci } 4491cb0ef41Sopenharmony_ci Node* Int32SubWithOverflow(Node* a, Node* b) { 4501cb0ef41Sopenharmony_ci return AddNode(machine()->Int32SubWithOverflow(), a, b); 4511cb0ef41Sopenharmony_ci } 4521cb0ef41Sopenharmony_ci Node* Int32Mul(Node* a, Node* b) { 4531cb0ef41Sopenharmony_ci return AddNode(machine()->Int32Mul(), a, b); 4541cb0ef41Sopenharmony_ci } 4551cb0ef41Sopenharmony_ci Node* Int32MulHigh(Node* a, Node* b) { 4561cb0ef41Sopenharmony_ci return AddNode(machine()->Int32MulHigh(), a, b); 4571cb0ef41Sopenharmony_ci } 4581cb0ef41Sopenharmony_ci Node* Int32MulWithOverflow(Node* a, Node* b) { 4591cb0ef41Sopenharmony_ci return AddNode(machine()->Int32MulWithOverflow(), a, b); 4601cb0ef41Sopenharmony_ci } 4611cb0ef41Sopenharmony_ci Node* Int32Div(Node* a, Node* b) { 4621cb0ef41Sopenharmony_ci return AddNode(machine()->Int32Div(), a, b); 4631cb0ef41Sopenharmony_ci } 4641cb0ef41Sopenharmony_ci Node* Int32Mod(Node* a, Node* b) { 4651cb0ef41Sopenharmony_ci return AddNode(machine()->Int32Mod(), a, b); 4661cb0ef41Sopenharmony_ci } 4671cb0ef41Sopenharmony_ci Node* Int32LessThan(Node* a, Node* b) { 4681cb0ef41Sopenharmony_ci return AddNode(machine()->Int32LessThan(), a, b); 4691cb0ef41Sopenharmony_ci } 4701cb0ef41Sopenharmony_ci Node* Int32LessThanOrEqual(Node* a, Node* b) { 4711cb0ef41Sopenharmony_ci return AddNode(machine()->Int32LessThanOrEqual(), a, b); 4721cb0ef41Sopenharmony_ci } 4731cb0ef41Sopenharmony_ci Node* Uint32Div(Node* a, Node* b) { 4741cb0ef41Sopenharmony_ci return AddNode(machine()->Uint32Div(), a, b); 4751cb0ef41Sopenharmony_ci } 4761cb0ef41Sopenharmony_ci Node* Uint32LessThan(Node* a, Node* b) { 4771cb0ef41Sopenharmony_ci return AddNode(machine()->Uint32LessThan(), a, b); 4781cb0ef41Sopenharmony_ci } 4791cb0ef41Sopenharmony_ci Node* Uint32LessThanOrEqual(Node* a, Node* b) { 4801cb0ef41Sopenharmony_ci return AddNode(machine()->Uint32LessThanOrEqual(), a, b); 4811cb0ef41Sopenharmony_ci } 4821cb0ef41Sopenharmony_ci Node* Uint32Mod(Node* a, Node* b) { 4831cb0ef41Sopenharmony_ci return AddNode(machine()->Uint32Mod(), a, b); 4841cb0ef41Sopenharmony_ci } 4851cb0ef41Sopenharmony_ci Node* Uint32MulHigh(Node* a, Node* b) { 4861cb0ef41Sopenharmony_ci return AddNode(machine()->Uint32MulHigh(), a, b); 4871cb0ef41Sopenharmony_ci } 4881cb0ef41Sopenharmony_ci Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); } 4891cb0ef41Sopenharmony_ci Node* Int32GreaterThanOrEqual(Node* a, Node* b) { 4901cb0ef41Sopenharmony_ci return Int32LessThanOrEqual(b, a); 4911cb0ef41Sopenharmony_ci } 4921cb0ef41Sopenharmony_ci Node* Uint32GreaterThan(Node* a, Node* b) { return Uint32LessThan(b, a); } 4931cb0ef41Sopenharmony_ci Node* Uint32GreaterThanOrEqual(Node* a, Node* b) { 4941cb0ef41Sopenharmony_ci return Uint32LessThanOrEqual(b, a); 4951cb0ef41Sopenharmony_ci } 4961cb0ef41Sopenharmony_ci Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); } 4971cb0ef41Sopenharmony_ci 4981cb0ef41Sopenharmony_ci Node* Int64Add(Node* a, Node* b) { 4991cb0ef41Sopenharmony_ci return AddNode(machine()->Int64Add(), a, b); 5001cb0ef41Sopenharmony_ci } 5011cb0ef41Sopenharmony_ci Node* Int64AddWithOverflow(Node* a, Node* b) { 5021cb0ef41Sopenharmony_ci return AddNode(machine()->Int64AddWithOverflow(), a, b); 5031cb0ef41Sopenharmony_ci } 5041cb0ef41Sopenharmony_ci Node* Int64Sub(Node* a, Node* b) { 5051cb0ef41Sopenharmony_ci return AddNode(machine()->Int64Sub(), a, b); 5061cb0ef41Sopenharmony_ci } 5071cb0ef41Sopenharmony_ci Node* Int64SubWithOverflow(Node* a, Node* b) { 5081cb0ef41Sopenharmony_ci return AddNode(machine()->Int64SubWithOverflow(), a, b); 5091cb0ef41Sopenharmony_ci } 5101cb0ef41Sopenharmony_ci Node* Int64Mul(Node* a, Node* b) { 5111cb0ef41Sopenharmony_ci return AddNode(machine()->Int64Mul(), a, b); 5121cb0ef41Sopenharmony_ci } 5131cb0ef41Sopenharmony_ci Node* Int64Div(Node* a, Node* b) { 5141cb0ef41Sopenharmony_ci return AddNode(machine()->Int64Div(), a, b); 5151cb0ef41Sopenharmony_ci } 5161cb0ef41Sopenharmony_ci Node* Int64Mod(Node* a, Node* b) { 5171cb0ef41Sopenharmony_ci return AddNode(machine()->Int64Mod(), a, b); 5181cb0ef41Sopenharmony_ci } 5191cb0ef41Sopenharmony_ci Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); } 5201cb0ef41Sopenharmony_ci Node* Int64LessThan(Node* a, Node* b) { 5211cb0ef41Sopenharmony_ci return AddNode(machine()->Int64LessThan(), a, b); 5221cb0ef41Sopenharmony_ci } 5231cb0ef41Sopenharmony_ci Node* Int64LessThanOrEqual(Node* a, Node* b) { 5241cb0ef41Sopenharmony_ci return AddNode(machine()->Int64LessThanOrEqual(), a, b); 5251cb0ef41Sopenharmony_ci } 5261cb0ef41Sopenharmony_ci Node* Uint64LessThan(Node* a, Node* b) { 5271cb0ef41Sopenharmony_ci return AddNode(machine()->Uint64LessThan(), a, b); 5281cb0ef41Sopenharmony_ci } 5291cb0ef41Sopenharmony_ci Node* Uint64LessThanOrEqual(Node* a, Node* b) { 5301cb0ef41Sopenharmony_ci return AddNode(machine()->Uint64LessThanOrEqual(), a, b); 5311cb0ef41Sopenharmony_ci } 5321cb0ef41Sopenharmony_ci Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); } 5331cb0ef41Sopenharmony_ci Node* Int64GreaterThanOrEqual(Node* a, Node* b) { 5341cb0ef41Sopenharmony_ci return Int64LessThanOrEqual(b, a); 5351cb0ef41Sopenharmony_ci } 5361cb0ef41Sopenharmony_ci Node* Uint64GreaterThan(Node* a, Node* b) { return Uint64LessThan(b, a); } 5371cb0ef41Sopenharmony_ci Node* Uint64GreaterThanOrEqual(Node* a, Node* b) { 5381cb0ef41Sopenharmony_ci return Uint64LessThanOrEqual(b, a); 5391cb0ef41Sopenharmony_ci } 5401cb0ef41Sopenharmony_ci Node* Uint64Div(Node* a, Node* b) { 5411cb0ef41Sopenharmony_ci return AddNode(machine()->Uint64Div(), a, b); 5421cb0ef41Sopenharmony_ci } 5431cb0ef41Sopenharmony_ci Node* Uint64Mod(Node* a, Node* b) { 5441cb0ef41Sopenharmony_ci return AddNode(machine()->Uint64Mod(), a, b); 5451cb0ef41Sopenharmony_ci } 5461cb0ef41Sopenharmony_ci Node* Int32PairAdd(Node* a_low, Node* a_high, Node* b_low, Node* b_high) { 5471cb0ef41Sopenharmony_ci return AddNode(machine()->Int32PairAdd(), a_low, a_high, b_low, b_high); 5481cb0ef41Sopenharmony_ci } 5491cb0ef41Sopenharmony_ci Node* Int32PairSub(Node* a_low, Node* a_high, Node* b_low, Node* b_high) { 5501cb0ef41Sopenharmony_ci return AddNode(machine()->Int32PairSub(), a_low, a_high, b_low, b_high); 5511cb0ef41Sopenharmony_ci } 5521cb0ef41Sopenharmony_ci Node* Int32PairMul(Node* a_low, Node* a_high, Node* b_low, Node* b_high) { 5531cb0ef41Sopenharmony_ci return AddNode(machine()->Int32PairMul(), a_low, a_high, b_low, b_high); 5541cb0ef41Sopenharmony_ci } 5551cb0ef41Sopenharmony_ci Node* Word32PairShl(Node* low_word, Node* high_word, Node* shift) { 5561cb0ef41Sopenharmony_ci return AddNode(machine()->Word32PairShl(), low_word, high_word, shift); 5571cb0ef41Sopenharmony_ci } 5581cb0ef41Sopenharmony_ci Node* Word32PairShr(Node* low_word, Node* high_word, Node* shift) { 5591cb0ef41Sopenharmony_ci return AddNode(machine()->Word32PairShr(), low_word, high_word, shift); 5601cb0ef41Sopenharmony_ci } 5611cb0ef41Sopenharmony_ci Node* Word32PairSar(Node* low_word, Node* high_word, Node* shift) { 5621cb0ef41Sopenharmony_ci return AddNode(machine()->Word32PairSar(), low_word, high_word, shift); 5631cb0ef41Sopenharmony_ci } 5641cb0ef41Sopenharmony_ci Node* Word32Popcnt(Node* a) { 5651cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Popcnt().op(), a); 5661cb0ef41Sopenharmony_ci } 5671cb0ef41Sopenharmony_ci Node* Word64Popcnt(Node* a) { 5681cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Popcnt().op(), a); 5691cb0ef41Sopenharmony_ci } 5701cb0ef41Sopenharmony_ci Node* Word32Ctz(Node* a) { return AddNode(machine()->Word32Ctz().op(), a); } 5711cb0ef41Sopenharmony_ci Node* Word64Ctz(Node* a) { return AddNode(machine()->Word64Ctz().op(), a); } 5721cb0ef41Sopenharmony_ci 5731cb0ef41Sopenharmony_ci Node* Word32Select(Node* condition, Node* b, Node* c) { 5741cb0ef41Sopenharmony_ci return AddNode(machine()->Word32Select().op(), condition, b, c); 5751cb0ef41Sopenharmony_ci } 5761cb0ef41Sopenharmony_ci 5771cb0ef41Sopenharmony_ci Node* Word64Select(Node* condition, Node* b, Node* c) { 5781cb0ef41Sopenharmony_ci return AddNode(machine()->Word64Select().op(), condition, b, c); 5791cb0ef41Sopenharmony_ci } 5801cb0ef41Sopenharmony_ci 5811cb0ef41Sopenharmony_ci Node* StackPointerGreaterThan(Node* value) { 5821cb0ef41Sopenharmony_ci return AddNode( 5831cb0ef41Sopenharmony_ci machine()->StackPointerGreaterThan(StackCheckKind::kCodeStubAssembler), 5841cb0ef41Sopenharmony_ci value); 5851cb0ef41Sopenharmony_ci } 5861cb0ef41Sopenharmony_ci 5871cb0ef41Sopenharmony_ci#define INTPTR_BINOP(prefix, name) \ 5881cb0ef41Sopenharmony_ci Node* IntPtr##name(Node* a, Node* b) { \ 5891cb0ef41Sopenharmony_ci return kSystemPointerSize == 8 ? prefix##64##name(a, b) \ 5901cb0ef41Sopenharmony_ci : prefix##32##name(a, b); \ 5911cb0ef41Sopenharmony_ci } 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, Add) 5941cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, AddWithOverflow) 5951cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, Sub) 5961cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, SubWithOverflow) 5971cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, Mul) 5981cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, Div) 5991cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, LessThan) 6001cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, LessThanOrEqual) 6011cb0ef41Sopenharmony_ci INTPTR_BINOP(Word, Equal) 6021cb0ef41Sopenharmony_ci INTPTR_BINOP(Word, NotEqual) 6031cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, GreaterThanOrEqual) 6041cb0ef41Sopenharmony_ci INTPTR_BINOP(Int, GreaterThan) 6051cb0ef41Sopenharmony_ci 6061cb0ef41Sopenharmony_ci#undef INTPTR_BINOP 6071cb0ef41Sopenharmony_ci 6081cb0ef41Sopenharmony_ci#define UINTPTR_BINOP(prefix, name) \ 6091cb0ef41Sopenharmony_ci Node* UintPtr##name(Node* a, Node* b) { \ 6101cb0ef41Sopenharmony_ci return kSystemPointerSize == 8 ? prefix##64##name(a, b) \ 6111cb0ef41Sopenharmony_ci : prefix##32##name(a, b); \ 6121cb0ef41Sopenharmony_ci } 6131cb0ef41Sopenharmony_ci 6141cb0ef41Sopenharmony_ci UINTPTR_BINOP(Uint, LessThan) 6151cb0ef41Sopenharmony_ci UINTPTR_BINOP(Uint, LessThanOrEqual) 6161cb0ef41Sopenharmony_ci UINTPTR_BINOP(Uint, GreaterThanOrEqual) 6171cb0ef41Sopenharmony_ci UINTPTR_BINOP(Uint, GreaterThan) 6181cb0ef41Sopenharmony_ci 6191cb0ef41Sopenharmony_ci#undef UINTPTR_BINOP 6201cb0ef41Sopenharmony_ci 6211cb0ef41Sopenharmony_ci Node* Int32AbsWithOverflow(Node* a) { 6221cb0ef41Sopenharmony_ci return AddNode(machine()->Int32AbsWithOverflow().op(), a); 6231cb0ef41Sopenharmony_ci } 6241cb0ef41Sopenharmony_ci 6251cb0ef41Sopenharmony_ci Node* Int64AbsWithOverflow(Node* a) { 6261cb0ef41Sopenharmony_ci return AddNode(machine()->Int64AbsWithOverflow().op(), a); 6271cb0ef41Sopenharmony_ci } 6281cb0ef41Sopenharmony_ci 6291cb0ef41Sopenharmony_ci Node* IntPtrAbsWithOverflow(Node* a) { 6301cb0ef41Sopenharmony_ci return kSystemPointerSize == 8 ? Int64AbsWithOverflow(a) 6311cb0ef41Sopenharmony_ci : Int32AbsWithOverflow(a); 6321cb0ef41Sopenharmony_ci } 6331cb0ef41Sopenharmony_ci 6341cb0ef41Sopenharmony_ci Node* Float32Add(Node* a, Node* b) { 6351cb0ef41Sopenharmony_ci return AddNode(machine()->Float32Add(), a, b); 6361cb0ef41Sopenharmony_ci } 6371cb0ef41Sopenharmony_ci Node* Float32Sub(Node* a, Node* b) { 6381cb0ef41Sopenharmony_ci return AddNode(machine()->Float32Sub(), a, b); 6391cb0ef41Sopenharmony_ci } 6401cb0ef41Sopenharmony_ci Node* Float32Mul(Node* a, Node* b) { 6411cb0ef41Sopenharmony_ci return AddNode(machine()->Float32Mul(), a, b); 6421cb0ef41Sopenharmony_ci } 6431cb0ef41Sopenharmony_ci Node* Float32Div(Node* a, Node* b) { 6441cb0ef41Sopenharmony_ci return AddNode(machine()->Float32Div(), a, b); 6451cb0ef41Sopenharmony_ci } 6461cb0ef41Sopenharmony_ci Node* Float32Abs(Node* a) { return AddNode(machine()->Float32Abs(), a); } 6471cb0ef41Sopenharmony_ci Node* Float32Neg(Node* a) { return AddNode(machine()->Float32Neg(), a); } 6481cb0ef41Sopenharmony_ci Node* Float32Sqrt(Node* a) { return AddNode(machine()->Float32Sqrt(), a); } 6491cb0ef41Sopenharmony_ci Node* Float32Equal(Node* a, Node* b) { 6501cb0ef41Sopenharmony_ci return AddNode(machine()->Float32Equal(), a, b); 6511cb0ef41Sopenharmony_ci } 6521cb0ef41Sopenharmony_ci Node* Float32NotEqual(Node* a, Node* b) { 6531cb0ef41Sopenharmony_ci return Word32BinaryNot(Float32Equal(a, b)); 6541cb0ef41Sopenharmony_ci } 6551cb0ef41Sopenharmony_ci Node* Float32LessThan(Node* a, Node* b) { 6561cb0ef41Sopenharmony_ci return AddNode(machine()->Float32LessThan(), a, b); 6571cb0ef41Sopenharmony_ci } 6581cb0ef41Sopenharmony_ci Node* Float32LessThanOrEqual(Node* a, Node* b) { 6591cb0ef41Sopenharmony_ci return AddNode(machine()->Float32LessThanOrEqual(), a, b); 6601cb0ef41Sopenharmony_ci } 6611cb0ef41Sopenharmony_ci Node* Float32GreaterThan(Node* a, Node* b) { return Float32LessThan(b, a); } 6621cb0ef41Sopenharmony_ci Node* Float32GreaterThanOrEqual(Node* a, Node* b) { 6631cb0ef41Sopenharmony_ci return Float32LessThanOrEqual(b, a); 6641cb0ef41Sopenharmony_ci } 6651cb0ef41Sopenharmony_ci Node* Float32Max(Node* a, Node* b) { 6661cb0ef41Sopenharmony_ci return AddNode(machine()->Float32Max(), a, b); 6671cb0ef41Sopenharmony_ci } 6681cb0ef41Sopenharmony_ci Node* Float32Min(Node* a, Node* b) { 6691cb0ef41Sopenharmony_ci return AddNode(machine()->Float32Min(), a, b); 6701cb0ef41Sopenharmony_ci } 6711cb0ef41Sopenharmony_ci Node* Float64Add(Node* a, Node* b) { 6721cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Add(), a, b); 6731cb0ef41Sopenharmony_ci } 6741cb0ef41Sopenharmony_ci Node* Float64Sub(Node* a, Node* b) { 6751cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Sub(), a, b); 6761cb0ef41Sopenharmony_ci } 6771cb0ef41Sopenharmony_ci Node* Float64Mul(Node* a, Node* b) { 6781cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Mul(), a, b); 6791cb0ef41Sopenharmony_ci } 6801cb0ef41Sopenharmony_ci Node* Float64Div(Node* a, Node* b) { 6811cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Div(), a, b); 6821cb0ef41Sopenharmony_ci } 6831cb0ef41Sopenharmony_ci Node* Float64Mod(Node* a, Node* b) { 6841cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Mod(), a, b); 6851cb0ef41Sopenharmony_ci } 6861cb0ef41Sopenharmony_ci Node* Float64Max(Node* a, Node* b) { 6871cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Max(), a, b); 6881cb0ef41Sopenharmony_ci } 6891cb0ef41Sopenharmony_ci Node* Float64Min(Node* a, Node* b) { 6901cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Min(), a, b); 6911cb0ef41Sopenharmony_ci } 6921cb0ef41Sopenharmony_ci Node* Float64Abs(Node* a) { return AddNode(machine()->Float64Abs(), a); } 6931cb0ef41Sopenharmony_ci Node* Float64Neg(Node* a) { return AddNode(machine()->Float64Neg(), a); } 6941cb0ef41Sopenharmony_ci Node* Float64Acos(Node* a) { return AddNode(machine()->Float64Acos(), a); } 6951cb0ef41Sopenharmony_ci Node* Float64Acosh(Node* a) { return AddNode(machine()->Float64Acosh(), a); } 6961cb0ef41Sopenharmony_ci Node* Float64Asin(Node* a) { return AddNode(machine()->Float64Asin(), a); } 6971cb0ef41Sopenharmony_ci Node* Float64Asinh(Node* a) { return AddNode(machine()->Float64Asinh(), a); } 6981cb0ef41Sopenharmony_ci Node* Float64Atan(Node* a) { return AddNode(machine()->Float64Atan(), a); } 6991cb0ef41Sopenharmony_ci Node* Float64Atanh(Node* a) { return AddNode(machine()->Float64Atanh(), a); } 7001cb0ef41Sopenharmony_ci Node* Float64Atan2(Node* a, Node* b) { 7011cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Atan2(), a, b); 7021cb0ef41Sopenharmony_ci } 7031cb0ef41Sopenharmony_ci Node* Float64Cbrt(Node* a) { return AddNode(machine()->Float64Cbrt(), a); } 7041cb0ef41Sopenharmony_ci Node* Float64Cos(Node* a) { return AddNode(machine()->Float64Cos(), a); } 7051cb0ef41Sopenharmony_ci Node* Float64Cosh(Node* a) { return AddNode(machine()->Float64Cosh(), a); } 7061cb0ef41Sopenharmony_ci Node* Float64Exp(Node* a) { return AddNode(machine()->Float64Exp(), a); } 7071cb0ef41Sopenharmony_ci Node* Float64Expm1(Node* a) { return AddNode(machine()->Float64Expm1(), a); } 7081cb0ef41Sopenharmony_ci Node* Float64Log(Node* a) { return AddNode(machine()->Float64Log(), a); } 7091cb0ef41Sopenharmony_ci Node* Float64Log1p(Node* a) { return AddNode(machine()->Float64Log1p(), a); } 7101cb0ef41Sopenharmony_ci Node* Float64Log10(Node* a) { return AddNode(machine()->Float64Log10(), a); } 7111cb0ef41Sopenharmony_ci Node* Float64Log2(Node* a) { return AddNode(machine()->Float64Log2(), a); } 7121cb0ef41Sopenharmony_ci Node* Float64Pow(Node* a, Node* b) { 7131cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Pow(), a, b); 7141cb0ef41Sopenharmony_ci } 7151cb0ef41Sopenharmony_ci Node* Float64Sin(Node* a) { return AddNode(machine()->Float64Sin(), a); } 7161cb0ef41Sopenharmony_ci Node* Float64Sinh(Node* a) { return AddNode(machine()->Float64Sinh(), a); } 7171cb0ef41Sopenharmony_ci Node* Float64Sqrt(Node* a) { return AddNode(machine()->Float64Sqrt(), a); } 7181cb0ef41Sopenharmony_ci Node* Float64Tan(Node* a) { return AddNode(machine()->Float64Tan(), a); } 7191cb0ef41Sopenharmony_ci Node* Float64Tanh(Node* a) { return AddNode(machine()->Float64Tanh(), a); } 7201cb0ef41Sopenharmony_ci Node* Float64Equal(Node* a, Node* b) { 7211cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Equal(), a, b); 7221cb0ef41Sopenharmony_ci } 7231cb0ef41Sopenharmony_ci Node* Float64NotEqual(Node* a, Node* b) { 7241cb0ef41Sopenharmony_ci return Word32BinaryNot(Float64Equal(a, b)); 7251cb0ef41Sopenharmony_ci } 7261cb0ef41Sopenharmony_ci Node* Float64LessThan(Node* a, Node* b) { 7271cb0ef41Sopenharmony_ci return AddNode(machine()->Float64LessThan(), a, b); 7281cb0ef41Sopenharmony_ci } 7291cb0ef41Sopenharmony_ci Node* Float64LessThanOrEqual(Node* a, Node* b) { 7301cb0ef41Sopenharmony_ci return AddNode(machine()->Float64LessThanOrEqual(), a, b); 7311cb0ef41Sopenharmony_ci } 7321cb0ef41Sopenharmony_ci Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); } 7331cb0ef41Sopenharmony_ci Node* Float64GreaterThanOrEqual(Node* a, Node* b) { 7341cb0ef41Sopenharmony_ci return Float64LessThanOrEqual(b, a); 7351cb0ef41Sopenharmony_ci } 7361cb0ef41Sopenharmony_ci Node* Float32Select(Node* condition, Node* b, Node* c) { 7371cb0ef41Sopenharmony_ci return AddNode(machine()->Float32Select().op(), condition, b, c); 7381cb0ef41Sopenharmony_ci } 7391cb0ef41Sopenharmony_ci Node* Float64Select(Node* condition, Node* b, Node* c) { 7401cb0ef41Sopenharmony_ci return AddNode(machine()->Float64Select().op(), condition, b, c); 7411cb0ef41Sopenharmony_ci } 7421cb0ef41Sopenharmony_ci 7431cb0ef41Sopenharmony_ci // Conversions. 7441cb0ef41Sopenharmony_ci Node* BitcastTaggedToWord(Node* a) { 7451cb0ef41Sopenharmony_ci return AddNode(machine()->BitcastTaggedToWord(), a); 7461cb0ef41Sopenharmony_ci } 7471cb0ef41Sopenharmony_ci Node* BitcastTaggedToWordForTagAndSmiBits(Node* a) { 7481cb0ef41Sopenharmony_ci return AddNode(machine()->BitcastTaggedToWordForTagAndSmiBits(), a); 7491cb0ef41Sopenharmony_ci } 7501cb0ef41Sopenharmony_ci Node* BitcastMaybeObjectToWord(Node* a) { 7511cb0ef41Sopenharmony_ci return AddNode(machine()->BitcastMaybeObjectToWord(), a); 7521cb0ef41Sopenharmony_ci } 7531cb0ef41Sopenharmony_ci Node* BitcastWordToTagged(Node* a) { 7541cb0ef41Sopenharmony_ci return AddNode(machine()->BitcastWordToTagged(), a); 7551cb0ef41Sopenharmony_ci } 7561cb0ef41Sopenharmony_ci Node* BitcastWordToTaggedSigned(Node* a) { 7571cb0ef41Sopenharmony_ci return AddNode(machine()->BitcastWordToTaggedSigned(), a); 7581cb0ef41Sopenharmony_ci } 7591cb0ef41Sopenharmony_ci Node* TruncateFloat64ToWord32(Node* a) { 7601cb0ef41Sopenharmony_ci return AddNode(machine()->TruncateFloat64ToWord32(), a); 7611cb0ef41Sopenharmony_ci } 7621cb0ef41Sopenharmony_ci Node* ChangeFloat32ToFloat64(Node* a) { 7631cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeFloat32ToFloat64(), a); 7641cb0ef41Sopenharmony_ci } 7651cb0ef41Sopenharmony_ci Node* ChangeInt32ToFloat64(Node* a) { 7661cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeInt32ToFloat64(), a); 7671cb0ef41Sopenharmony_ci } 7681cb0ef41Sopenharmony_ci Node* ChangeInt64ToFloat64(Node* a) { 7691cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeInt64ToFloat64(), a); 7701cb0ef41Sopenharmony_ci } 7711cb0ef41Sopenharmony_ci Node* ChangeUint32ToFloat64(Node* a) { 7721cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeUint32ToFloat64(), a); 7731cb0ef41Sopenharmony_ci } 7741cb0ef41Sopenharmony_ci Node* ChangeFloat64ToInt32(Node* a) { 7751cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeFloat64ToInt32(), a); 7761cb0ef41Sopenharmony_ci } 7771cb0ef41Sopenharmony_ci Node* ChangeFloat64ToInt64(Node* a) { 7781cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeFloat64ToInt64(), a); 7791cb0ef41Sopenharmony_ci } 7801cb0ef41Sopenharmony_ci Node* ChangeFloat64ToUint32(Node* a) { 7811cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeFloat64ToUint32(), a); 7821cb0ef41Sopenharmony_ci } 7831cb0ef41Sopenharmony_ci Node* ChangeFloat64ToUint64(Node* a) { 7841cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeFloat64ToUint64(), a); 7851cb0ef41Sopenharmony_ci } 7861cb0ef41Sopenharmony_ci Node* TruncateFloat64ToUint32(Node* a) { 7871cb0ef41Sopenharmony_ci return AddNode(machine()->TruncateFloat64ToUint32(), a); 7881cb0ef41Sopenharmony_ci } 7891cb0ef41Sopenharmony_ci Node* TruncateFloat32ToInt32(Node* a, TruncateKind kind) { 7901cb0ef41Sopenharmony_ci return AddNode(machine()->TruncateFloat32ToInt32(kind), a); 7911cb0ef41Sopenharmony_ci } 7921cb0ef41Sopenharmony_ci Node* TruncateFloat32ToUint32(Node* a, TruncateKind kind) { 7931cb0ef41Sopenharmony_ci return AddNode(machine()->TruncateFloat32ToUint32(kind), a); 7941cb0ef41Sopenharmony_ci } 7951cb0ef41Sopenharmony_ci Node* TryTruncateFloat32ToInt64(Node* a) { 7961cb0ef41Sopenharmony_ci return AddNode(machine()->TryTruncateFloat32ToInt64(), a); 7971cb0ef41Sopenharmony_ci } 7981cb0ef41Sopenharmony_ci Node* TryTruncateFloat64ToInt64(Node* a) { 7991cb0ef41Sopenharmony_ci return AddNode(machine()->TryTruncateFloat64ToInt64(), a); 8001cb0ef41Sopenharmony_ci } 8011cb0ef41Sopenharmony_ci Node* TryTruncateFloat32ToUint64(Node* a) { 8021cb0ef41Sopenharmony_ci return AddNode(machine()->TryTruncateFloat32ToUint64(), a); 8031cb0ef41Sopenharmony_ci } 8041cb0ef41Sopenharmony_ci Node* TryTruncateFloat64ToUint64(Node* a) { 8051cb0ef41Sopenharmony_ci return AddNode(machine()->TryTruncateFloat64ToUint64(), a); 8061cb0ef41Sopenharmony_ci } 8071cb0ef41Sopenharmony_ci Node* ChangeInt32ToInt64(Node* a) { 8081cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeInt32ToInt64(), a); 8091cb0ef41Sopenharmony_ci } 8101cb0ef41Sopenharmony_ci Node* ChangeUint32ToUint64(Node* a) { 8111cb0ef41Sopenharmony_ci return AddNode(machine()->ChangeUint32ToUint64(), a); 8121cb0ef41Sopenharmony_ci } 8131cb0ef41Sopenharmony_ci Node* TruncateFloat64ToFloat32(Node* a) { 8141cb0ef41Sopenharmony_ci return AddNode(machine()->TruncateFloat64ToFloat32(), a); 8151cb0ef41Sopenharmony_ci } 8161cb0ef41Sopenharmony_ci Node* TruncateInt64ToInt32(Node* a) { 8171cb0ef41Sopenharmony_ci return AddNode(machine()->TruncateInt64ToInt32(), a); 8181cb0ef41Sopenharmony_ci } 8191cb0ef41Sopenharmony_ci Node* RoundFloat64ToInt32(Node* a) { 8201cb0ef41Sopenharmony_ci return AddNode(machine()->RoundFloat64ToInt32(), a); 8211cb0ef41Sopenharmony_ci } 8221cb0ef41Sopenharmony_ci Node* RoundInt32ToFloat32(Node* a) { 8231cb0ef41Sopenharmony_ci return AddNode(machine()->RoundInt32ToFloat32(), a); 8241cb0ef41Sopenharmony_ci } 8251cb0ef41Sopenharmony_ci Node* RoundInt64ToFloat32(Node* a) { 8261cb0ef41Sopenharmony_ci return AddNode(machine()->RoundInt64ToFloat32(), a); 8271cb0ef41Sopenharmony_ci } 8281cb0ef41Sopenharmony_ci Node* RoundInt64ToFloat64(Node* a) { 8291cb0ef41Sopenharmony_ci return AddNode(machine()->RoundInt64ToFloat64(), a); 8301cb0ef41Sopenharmony_ci } 8311cb0ef41Sopenharmony_ci Node* RoundUint32ToFloat32(Node* a) { 8321cb0ef41Sopenharmony_ci return AddNode(machine()->RoundUint32ToFloat32(), a); 8331cb0ef41Sopenharmony_ci } 8341cb0ef41Sopenharmony_ci Node* RoundUint64ToFloat32(Node* a) { 8351cb0ef41Sopenharmony_ci return AddNode(machine()->RoundUint64ToFloat32(), a); 8361cb0ef41Sopenharmony_ci } 8371cb0ef41Sopenharmony_ci Node* RoundUint64ToFloat64(Node* a) { 8381cb0ef41Sopenharmony_ci return AddNode(machine()->RoundUint64ToFloat64(), a); 8391cb0ef41Sopenharmony_ci } 8401cb0ef41Sopenharmony_ci Node* BitcastFloat32ToInt32(Node* a) { 8411cb0ef41Sopenharmony_ci return AddNode(machine()->BitcastFloat32ToInt32(), a); 8421cb0ef41Sopenharmony_ci } 8431cb0ef41Sopenharmony_ci Node* BitcastFloat64ToInt64(Node* a) { 8441cb0ef41Sopenharmony_ci return AddNode(machine()->BitcastFloat64ToInt64(), a); 8451cb0ef41Sopenharmony_ci } 8461cb0ef41Sopenharmony_ci Node* BitcastInt32ToFloat32(Node* a) { 8471cb0ef41Sopenharmony_ci return AddNode(machine()->BitcastInt32ToFloat32(), a); 8481cb0ef41Sopenharmony_ci } 8491cb0ef41Sopenharmony_ci Node* BitcastInt64ToFloat64(Node* a) { 8501cb0ef41Sopenharmony_ci return AddNode(machine()->BitcastInt64ToFloat64(), a); 8511cb0ef41Sopenharmony_ci } 8521cb0ef41Sopenharmony_ci Node* Float32RoundDown(Node* a) { 8531cb0ef41Sopenharmony_ci return AddNode(machine()->Float32RoundDown().op(), a); 8541cb0ef41Sopenharmony_ci } 8551cb0ef41Sopenharmony_ci Node* Float64RoundDown(Node* a) { 8561cb0ef41Sopenharmony_ci return AddNode(machine()->Float64RoundDown().op(), a); 8571cb0ef41Sopenharmony_ci } 8581cb0ef41Sopenharmony_ci Node* Float32RoundUp(Node* a) { 8591cb0ef41Sopenharmony_ci return AddNode(machine()->Float32RoundUp().op(), a); 8601cb0ef41Sopenharmony_ci } 8611cb0ef41Sopenharmony_ci Node* Float64RoundUp(Node* a) { 8621cb0ef41Sopenharmony_ci return AddNode(machine()->Float64RoundUp().op(), a); 8631cb0ef41Sopenharmony_ci } 8641cb0ef41Sopenharmony_ci Node* Float32RoundTruncate(Node* a) { 8651cb0ef41Sopenharmony_ci return AddNode(machine()->Float32RoundTruncate().op(), a); 8661cb0ef41Sopenharmony_ci } 8671cb0ef41Sopenharmony_ci Node* Float64RoundTruncate(Node* a) { 8681cb0ef41Sopenharmony_ci return AddNode(machine()->Float64RoundTruncate().op(), a); 8691cb0ef41Sopenharmony_ci } 8701cb0ef41Sopenharmony_ci Node* Float64RoundTiesAway(Node* a) { 8711cb0ef41Sopenharmony_ci return AddNode(machine()->Float64RoundTiesAway().op(), a); 8721cb0ef41Sopenharmony_ci } 8731cb0ef41Sopenharmony_ci Node* Float32RoundTiesEven(Node* a) { 8741cb0ef41Sopenharmony_ci return AddNode(machine()->Float32RoundTiesEven().op(), a); 8751cb0ef41Sopenharmony_ci } 8761cb0ef41Sopenharmony_ci Node* Float64RoundTiesEven(Node* a) { 8771cb0ef41Sopenharmony_ci return AddNode(machine()->Float64RoundTiesEven().op(), a); 8781cb0ef41Sopenharmony_ci } 8791cb0ef41Sopenharmony_ci Node* Word32ReverseBytes(Node* a) { 8801cb0ef41Sopenharmony_ci return AddNode(machine()->Word32ReverseBytes(), a); 8811cb0ef41Sopenharmony_ci } 8821cb0ef41Sopenharmony_ci Node* Word64ReverseBytes(Node* a) { 8831cb0ef41Sopenharmony_ci return AddNode(machine()->Word64ReverseBytes(), a); 8841cb0ef41Sopenharmony_ci } 8851cb0ef41Sopenharmony_ci 8861cb0ef41Sopenharmony_ci // Float64 bit operations. 8871cb0ef41Sopenharmony_ci Node* Float64ExtractLowWord32(Node* a) { 8881cb0ef41Sopenharmony_ci return AddNode(machine()->Float64ExtractLowWord32(), a); 8891cb0ef41Sopenharmony_ci } 8901cb0ef41Sopenharmony_ci Node* Float64ExtractHighWord32(Node* a) { 8911cb0ef41Sopenharmony_ci return AddNode(machine()->Float64ExtractHighWord32(), a); 8921cb0ef41Sopenharmony_ci } 8931cb0ef41Sopenharmony_ci Node* Float64InsertLowWord32(Node* a, Node* b) { 8941cb0ef41Sopenharmony_ci return AddNode(machine()->Float64InsertLowWord32(), a, b); 8951cb0ef41Sopenharmony_ci } 8961cb0ef41Sopenharmony_ci Node* Float64InsertHighWord32(Node* a, Node* b) { 8971cb0ef41Sopenharmony_ci return AddNode(machine()->Float64InsertHighWord32(), a, b); 8981cb0ef41Sopenharmony_ci } 8991cb0ef41Sopenharmony_ci Node* Float64SilenceNaN(Node* a) { 9001cb0ef41Sopenharmony_ci return AddNode(machine()->Float64SilenceNaN(), a); 9011cb0ef41Sopenharmony_ci } 9021cb0ef41Sopenharmony_ci 9031cb0ef41Sopenharmony_ci // SIMD operations. 9041cb0ef41Sopenharmony_ci Node* S128Const(const uint8_t value[16]) { 9051cb0ef41Sopenharmony_ci return AddNode(machine()->S128Const(value)); 9061cb0ef41Sopenharmony_ci } 9071cb0ef41Sopenharmony_ci Node* I64x2Splat(Node* a) { return AddNode(machine()->I64x2Splat(), a); } 9081cb0ef41Sopenharmony_ci Node* I64x2SplatI32Pair(Node* a, Node* b) { 9091cb0ef41Sopenharmony_ci return AddNode(machine()->I64x2SplatI32Pair(), a, b); 9101cb0ef41Sopenharmony_ci } 9111cb0ef41Sopenharmony_ci Node* I32x4Splat(Node* a) { return AddNode(machine()->I32x4Splat(), a); } 9121cb0ef41Sopenharmony_ci Node* I16x8Splat(Node* a) { return AddNode(machine()->I16x8Splat(), a); } 9131cb0ef41Sopenharmony_ci Node* I8x16Splat(Node* a) { return AddNode(machine()->I8x16Splat(), a); } 9141cb0ef41Sopenharmony_ci 9151cb0ef41Sopenharmony_ci Node* I8x16BitMask(Node* a) { return AddNode(machine()->I8x16BitMask(), a); } 9161cb0ef41Sopenharmony_ci 9171cb0ef41Sopenharmony_ci Node* I8x16Eq(Node* a, Node* b) { 9181cb0ef41Sopenharmony_ci return AddNode(machine()->I8x16Eq(), a, b); 9191cb0ef41Sopenharmony_ci } 9201cb0ef41Sopenharmony_ci 9211cb0ef41Sopenharmony_ci // Stack operations. 9221cb0ef41Sopenharmony_ci Node* LoadFramePointer() { return AddNode(machine()->LoadFramePointer()); } 9231cb0ef41Sopenharmony_ci Node* LoadParentFramePointer() { 9241cb0ef41Sopenharmony_ci return AddNode(machine()->LoadParentFramePointer()); 9251cb0ef41Sopenharmony_ci } 9261cb0ef41Sopenharmony_ci 9271cb0ef41Sopenharmony_ci // Parameters. 9281cb0ef41Sopenharmony_ci Node* TargetParameter(); 9291cb0ef41Sopenharmony_ci Node* Parameter(size_t index); 9301cb0ef41Sopenharmony_ci 9311cb0ef41Sopenharmony_ci // Pointer utilities. 9321cb0ef41Sopenharmony_ci Node* LoadFromPointer(void* address, MachineType type, int32_t offset = 0) { 9331cb0ef41Sopenharmony_ci return Load(type, PointerConstant(address), Int32Constant(offset)); 9341cb0ef41Sopenharmony_ci } 9351cb0ef41Sopenharmony_ci Node* StoreToPointer(void* address, MachineRepresentation rep, Node* node) { 9361cb0ef41Sopenharmony_ci return Store(rep, PointerConstant(address), node, kNoWriteBarrier); 9371cb0ef41Sopenharmony_ci } 9381cb0ef41Sopenharmony_ci Node* UnalignedLoadFromPointer(void* address, MachineType type, 9391cb0ef41Sopenharmony_ci int32_t offset = 0) { 9401cb0ef41Sopenharmony_ci return UnalignedLoad(type, PointerConstant(address), Int32Constant(offset)); 9411cb0ef41Sopenharmony_ci } 9421cb0ef41Sopenharmony_ci Node* UnalignedStoreToPointer(void* address, MachineRepresentation rep, 9431cb0ef41Sopenharmony_ci Node* node) { 9441cb0ef41Sopenharmony_ci return UnalignedStore(rep, PointerConstant(address), node); 9451cb0ef41Sopenharmony_ci } 9461cb0ef41Sopenharmony_ci Node* StringConstant(const char* string) { 9471cb0ef41Sopenharmony_ci return HeapConstant(isolate()->factory()->InternalizeUtf8String(string)); 9481cb0ef41Sopenharmony_ci } 9491cb0ef41Sopenharmony_ci 9501cb0ef41Sopenharmony_ci // Call a given call descriptor and the given arguments. 9511cb0ef41Sopenharmony_ci // The call target is passed as part of the {inputs} array. 9521cb0ef41Sopenharmony_ci Node* CallN(CallDescriptor* call_descriptor, int input_count, 9531cb0ef41Sopenharmony_ci Node* const* inputs); 9541cb0ef41Sopenharmony_ci 9551cb0ef41Sopenharmony_ci // Call a given call descriptor and the given arguments and frame-state. 9561cb0ef41Sopenharmony_ci // The call target and frame state are passed as part of the {inputs} array. 9571cb0ef41Sopenharmony_ci Node* CallNWithFrameState(CallDescriptor* call_descriptor, int input_count, 9581cb0ef41Sopenharmony_ci Node* const* inputs); 9591cb0ef41Sopenharmony_ci 9601cb0ef41Sopenharmony_ci // Tail call a given call descriptor and the given arguments. 9611cb0ef41Sopenharmony_ci // The call target is passed as part of the {inputs} array. 9621cb0ef41Sopenharmony_ci void TailCallN(CallDescriptor* call_descriptor, int input_count, 9631cb0ef41Sopenharmony_ci Node* const* inputs); 9641cb0ef41Sopenharmony_ci 9651cb0ef41Sopenharmony_ci // Type representing C function argument with type info. 9661cb0ef41Sopenharmony_ci using CFunctionArg = std::pair<MachineType, Node*>; 9671cb0ef41Sopenharmony_ci 9681cb0ef41Sopenharmony_ci // Call to a C function. 9691cb0ef41Sopenharmony_ci template <class... CArgs> 9701cb0ef41Sopenharmony_ci Node* CallCFunction(Node* function, base::Optional<MachineType> return_type, 9711cb0ef41Sopenharmony_ci CArgs... cargs) { 9721cb0ef41Sopenharmony_ci static_assert( 9731cb0ef41Sopenharmony_ci std::conjunction_v<std::is_convertible<CArgs, CFunctionArg>...>, 9741cb0ef41Sopenharmony_ci "invalid argument types"); 9751cb0ef41Sopenharmony_ci return CallCFunction(function, return_type, {cargs...}); 9761cb0ef41Sopenharmony_ci } 9771cb0ef41Sopenharmony_ci 9781cb0ef41Sopenharmony_ci Node* CallCFunction(Node* function, base::Optional<MachineType> return_type, 9791cb0ef41Sopenharmony_ci std::initializer_list<CFunctionArg> args); 9801cb0ef41Sopenharmony_ci 9811cb0ef41Sopenharmony_ci // Call to a C function without a function discriptor on AIX. 9821cb0ef41Sopenharmony_ci template <class... CArgs> 9831cb0ef41Sopenharmony_ci Node* CallCFunctionWithoutFunctionDescriptor(Node* function, 9841cb0ef41Sopenharmony_ci MachineType return_type, 9851cb0ef41Sopenharmony_ci CArgs... cargs) { 9861cb0ef41Sopenharmony_ci static_assert( 9871cb0ef41Sopenharmony_ci std::conjunction_v<std::is_convertible<CArgs, CFunctionArg>...>, 9881cb0ef41Sopenharmony_ci "invalid argument types"); 9891cb0ef41Sopenharmony_ci return CallCFunctionWithoutFunctionDescriptor(function, return_type, 9901cb0ef41Sopenharmony_ci {cargs...}); 9911cb0ef41Sopenharmony_ci } 9921cb0ef41Sopenharmony_ci 9931cb0ef41Sopenharmony_ci Node* CallCFunctionWithoutFunctionDescriptor( 9941cb0ef41Sopenharmony_ci Node* function, MachineType return_type, 9951cb0ef41Sopenharmony_ci std::initializer_list<CFunctionArg> args); 9961cb0ef41Sopenharmony_ci 9971cb0ef41Sopenharmony_ci // Call to a C function, while saving/restoring caller registers. 9981cb0ef41Sopenharmony_ci template <class... CArgs> 9991cb0ef41Sopenharmony_ci Node* CallCFunctionWithCallerSavedRegisters(Node* function, 10001cb0ef41Sopenharmony_ci MachineType return_type, 10011cb0ef41Sopenharmony_ci SaveFPRegsMode mode, 10021cb0ef41Sopenharmony_ci CArgs... cargs) { 10031cb0ef41Sopenharmony_ci static_assert( 10041cb0ef41Sopenharmony_ci std::conjunction_v<std::is_convertible<CArgs, CFunctionArg>...>, 10051cb0ef41Sopenharmony_ci "invalid argument types"); 10061cb0ef41Sopenharmony_ci return CallCFunctionWithCallerSavedRegisters(function, return_type, mode, 10071cb0ef41Sopenharmony_ci {cargs...}); 10081cb0ef41Sopenharmony_ci } 10091cb0ef41Sopenharmony_ci 10101cb0ef41Sopenharmony_ci Node* CallCFunctionWithCallerSavedRegisters( 10111cb0ef41Sopenharmony_ci Node* function, MachineType return_type, SaveFPRegsMode mode, 10121cb0ef41Sopenharmony_ci std::initializer_list<CFunctionArg> args); 10131cb0ef41Sopenharmony_ci 10141cb0ef41Sopenharmony_ci // =========================================================================== 10151cb0ef41Sopenharmony_ci // The following utility methods deal with control flow, hence might switch 10161cb0ef41Sopenharmony_ci // the current basic block or create new basic blocks for labels. 10171cb0ef41Sopenharmony_ci 10181cb0ef41Sopenharmony_ci // Control flow. 10191cb0ef41Sopenharmony_ci void Goto(RawMachineLabel* label); 10201cb0ef41Sopenharmony_ci void Branch(Node* condition, RawMachineLabel* true_val, 10211cb0ef41Sopenharmony_ci RawMachineLabel* false_val); 10221cb0ef41Sopenharmony_ci void Switch(Node* index, RawMachineLabel* default_label, 10231cb0ef41Sopenharmony_ci const int32_t* case_values, RawMachineLabel** case_labels, 10241cb0ef41Sopenharmony_ci size_t case_count); 10251cb0ef41Sopenharmony_ci void Return(Node* value); 10261cb0ef41Sopenharmony_ci void Return(Node* v1, Node* v2); 10271cb0ef41Sopenharmony_ci void Return(Node* v1, Node* v2, Node* v3); 10281cb0ef41Sopenharmony_ci void Return(Node* v1, Node* v2, Node* v3, Node* v4); 10291cb0ef41Sopenharmony_ci void Return(int count, Node* v[]); 10301cb0ef41Sopenharmony_ci void PopAndReturn(Node* pop, Node* value); 10311cb0ef41Sopenharmony_ci void PopAndReturn(Node* pop, Node* v1, Node* v2); 10321cb0ef41Sopenharmony_ci void PopAndReturn(Node* pop, Node* v1, Node* v2, Node* v3); 10331cb0ef41Sopenharmony_ci void PopAndReturn(Node* pop, Node* v1, Node* v2, Node* v3, Node* v4); 10341cb0ef41Sopenharmony_ci void Bind(RawMachineLabel* label); 10351cb0ef41Sopenharmony_ci void Deoptimize(Node* state); 10361cb0ef41Sopenharmony_ci void AbortCSADcheck(Node* message); 10371cb0ef41Sopenharmony_ci void DebugBreak(); 10381cb0ef41Sopenharmony_ci void Unreachable(); 10391cb0ef41Sopenharmony_ci void Comment(const std::string& msg); 10401cb0ef41Sopenharmony_ci void StaticAssert(Node* value, const char* source); 10411cb0ef41Sopenharmony_ci 10421cb0ef41Sopenharmony_ci#if DEBUG 10431cb0ef41Sopenharmony_ci void Bind(RawMachineLabel* label, AssemblerDebugInfo info); 10441cb0ef41Sopenharmony_ci void SetInitialDebugInformation(AssemblerDebugInfo info); 10451cb0ef41Sopenharmony_ci void PrintCurrentBlock(std::ostream& os); 10461cb0ef41Sopenharmony_ci#endif // DEBUG 10471cb0ef41Sopenharmony_ci bool InsideBlock(); 10481cb0ef41Sopenharmony_ci 10491cb0ef41Sopenharmony_ci // Add success / exception successor blocks and ends the current block ending 10501cb0ef41Sopenharmony_ci // in a potentially throwing call node. 10511cb0ef41Sopenharmony_ci void Continuations(Node* call, RawMachineLabel* if_success, 10521cb0ef41Sopenharmony_ci RawMachineLabel* if_exception); 10531cb0ef41Sopenharmony_ci 10541cb0ef41Sopenharmony_ci // Variables. 10551cb0ef41Sopenharmony_ci Node* Phi(MachineRepresentation rep, Node* n1, Node* n2) { 10561cb0ef41Sopenharmony_ci return AddNode(common()->Phi(rep, 2), n1, n2, graph()->start()); 10571cb0ef41Sopenharmony_ci } 10581cb0ef41Sopenharmony_ci Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3) { 10591cb0ef41Sopenharmony_ci return AddNode(common()->Phi(rep, 3), n1, n2, n3, graph()->start()); 10601cb0ef41Sopenharmony_ci } 10611cb0ef41Sopenharmony_ci Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3, Node* n4) { 10621cb0ef41Sopenharmony_ci return AddNode(common()->Phi(rep, 4), n1, n2, n3, n4, graph()->start()); 10631cb0ef41Sopenharmony_ci } 10641cb0ef41Sopenharmony_ci Node* Phi(MachineRepresentation rep, int input_count, Node* const* inputs); 10651cb0ef41Sopenharmony_ci void AppendPhiInput(Node* phi, Node* new_input); 10661cb0ef41Sopenharmony_ci 10671cb0ef41Sopenharmony_ci // =========================================================================== 10681cb0ef41Sopenharmony_ci // The following generic node creation methods can be used for operators that 10691cb0ef41Sopenharmony_ci // are not covered by the above utility methods. There should rarely be a need 10701cb0ef41Sopenharmony_ci // to do that outside of testing though. 10711cb0ef41Sopenharmony_ci 10721cb0ef41Sopenharmony_ci Node* AddNode(const Operator* op, int input_count, Node* const* inputs); 10731cb0ef41Sopenharmony_ci 10741cb0ef41Sopenharmony_ci Node* AddNode(const Operator* op) { 10751cb0ef41Sopenharmony_ci return AddNode(op, 0, static_cast<Node* const*>(nullptr)); 10761cb0ef41Sopenharmony_ci } 10771cb0ef41Sopenharmony_ci 10781cb0ef41Sopenharmony_ci template <class... TArgs> 10791cb0ef41Sopenharmony_ci Node* AddNode(const Operator* op, Node* n1, TArgs... args) { 10801cb0ef41Sopenharmony_ci Node* buffer[] = {n1, args...}; 10811cb0ef41Sopenharmony_ci return AddNode(op, sizeof...(args) + 1, buffer); 10821cb0ef41Sopenharmony_ci } 10831cb0ef41Sopenharmony_ci 10841cb0ef41Sopenharmony_ci void SetCurrentExternalSourcePosition(FileAndLine file_and_line); 10851cb0ef41Sopenharmony_ci FileAndLine GetCurrentExternalSourcePosition() const; 10861cb0ef41Sopenharmony_ci SourcePositionTable* source_positions() { return source_positions_; } 10871cb0ef41Sopenharmony_ci 10881cb0ef41Sopenharmony_ci private: 10891cb0ef41Sopenharmony_ci Node* MakeNode(const Operator* op, int input_count, Node* const* inputs); 10901cb0ef41Sopenharmony_ci BasicBlock* Use(RawMachineLabel* label); 10911cb0ef41Sopenharmony_ci BasicBlock* EnsureBlock(RawMachineLabel* label); 10921cb0ef41Sopenharmony_ci BasicBlock* CurrentBlock(); 10931cb0ef41Sopenharmony_ci 10941cb0ef41Sopenharmony_ci // A post-processing pass to add effect and control edges so that the graph 10951cb0ef41Sopenharmony_ci // can be optimized and re-scheduled. 10961cb0ef41Sopenharmony_ci // TODO(turbofan): Move this to a separate class. 10971cb0ef41Sopenharmony_ci void MakeReschedulable(); 10981cb0ef41Sopenharmony_ci Node* CreateNodeFromPredecessors(const std::vector<BasicBlock*>& predecessors, 10991cb0ef41Sopenharmony_ci const std::vector<Node*>& sidetable, 11001cb0ef41Sopenharmony_ci const Operator* op, 11011cb0ef41Sopenharmony_ci const std::vector<Node*>& additional_inputs); 11021cb0ef41Sopenharmony_ci void MakePhiBinary(Node* phi, int split_point, Node* left_control, 11031cb0ef41Sopenharmony_ci Node* right_control); 11041cb0ef41Sopenharmony_ci void MarkControlDeferred(Node* control_input); 11051cb0ef41Sopenharmony_ci 11061cb0ef41Sopenharmony_ci Schedule* schedule() { return schedule_; } 11071cb0ef41Sopenharmony_ci size_t parameter_count() const { return call_descriptor_->ParameterCount(); } 11081cb0ef41Sopenharmony_ci 11091cb0ef41Sopenharmony_ci static void OptimizeControlFlow(Schedule* schedule, Graph* graph, 11101cb0ef41Sopenharmony_ci CommonOperatorBuilder* common); 11111cb0ef41Sopenharmony_ci 11121cb0ef41Sopenharmony_ci Isolate* isolate_; 11131cb0ef41Sopenharmony_ci 11141cb0ef41Sopenharmony_ci Graph* graph_; 11151cb0ef41Sopenharmony_ci Schedule* schedule_; 11161cb0ef41Sopenharmony_ci SourcePositionTable* source_positions_; 11171cb0ef41Sopenharmony_ci MachineOperatorBuilder machine_; 11181cb0ef41Sopenharmony_ci CommonOperatorBuilder common_; 11191cb0ef41Sopenharmony_ci SimplifiedOperatorBuilder simplified_; 11201cb0ef41Sopenharmony_ci CallDescriptor* call_descriptor_; 11211cb0ef41Sopenharmony_ci Node* target_parameter_; 11221cb0ef41Sopenharmony_ci NodeVector parameters_; 11231cb0ef41Sopenharmony_ci BasicBlock* current_block_; 11241cb0ef41Sopenharmony_ci}; 11251cb0ef41Sopenharmony_ci 11261cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE RawMachineLabel final { 11271cb0ef41Sopenharmony_ci public: 11281cb0ef41Sopenharmony_ci enum Type { kDeferred, kNonDeferred }; 11291cb0ef41Sopenharmony_ci 11301cb0ef41Sopenharmony_ci explicit RawMachineLabel(Type type = kNonDeferred) 11311cb0ef41Sopenharmony_ci : deferred_(type == kDeferred) {} 11321cb0ef41Sopenharmony_ci ~RawMachineLabel(); 11331cb0ef41Sopenharmony_ci RawMachineLabel(const RawMachineLabel&) = delete; 11341cb0ef41Sopenharmony_ci RawMachineLabel& operator=(const RawMachineLabel&) = delete; 11351cb0ef41Sopenharmony_ci 11361cb0ef41Sopenharmony_ci BasicBlock* block() const { return block_; } 11371cb0ef41Sopenharmony_ci 11381cb0ef41Sopenharmony_ci private: 11391cb0ef41Sopenharmony_ci BasicBlock* block_ = nullptr; 11401cb0ef41Sopenharmony_ci bool used_ = false; 11411cb0ef41Sopenharmony_ci bool bound_ = false; 11421cb0ef41Sopenharmony_ci bool deferred_; 11431cb0ef41Sopenharmony_ci friend class RawMachineAssembler; 11441cb0ef41Sopenharmony_ci}; 11451cb0ef41Sopenharmony_ci 11461cb0ef41Sopenharmony_ci} // namespace compiler 11471cb0ef41Sopenharmony_ci} // namespace internal 11481cb0ef41Sopenharmony_ci} // namespace v8 11491cb0ef41Sopenharmony_ci 11501cb0ef41Sopenharmony_ci#endif // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_ 1151