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#ifndef V8_COMPILER_CODE_ASSEMBLER_H_ 61cb0ef41Sopenharmony_ci#define V8_COMPILER_CODE_ASSEMBLER_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include <initializer_list> 91cb0ef41Sopenharmony_ci#include <map> 101cb0ef41Sopenharmony_ci#include <memory> 111cb0ef41Sopenharmony_ci#include <sstream> 121cb0ef41Sopenharmony_ci#include <type_traits> 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci// Clients of this interface shouldn't depend on lots of compiler internals. 151cb0ef41Sopenharmony_ci// Do not include anything from src/compiler here! 161cb0ef41Sopenharmony_ci#include "include/cppgc/source-location.h" 171cb0ef41Sopenharmony_ci#include "src/base/macros.h" 181cb0ef41Sopenharmony_ci#include "src/base/optional.h" 191cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h" 201cb0ef41Sopenharmony_ci#include "src/codegen/atomic-memory-order.h" 211cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h" 221cb0ef41Sopenharmony_ci#include "src/codegen/machine-type.h" 231cb0ef41Sopenharmony_ci#include "src/codegen/source-position.h" 241cb0ef41Sopenharmony_ci#include "src/codegen/tnode.h" 251cb0ef41Sopenharmony_ci#include "src/heap/heap.h" 261cb0ef41Sopenharmony_ci#include "src/objects/arguments.h" 271cb0ef41Sopenharmony_ci#include "src/objects/data-handler.h" 281cb0ef41Sopenharmony_ci#include "src/objects/heap-number.h" 291cb0ef41Sopenharmony_ci#include "src/objects/js-array-buffer.h" 301cb0ef41Sopenharmony_ci#include "src/objects/js-collection.h" 311cb0ef41Sopenharmony_ci#include "src/objects/js-proxy.h" 321cb0ef41Sopenharmony_ci#include "src/objects/map.h" 331cb0ef41Sopenharmony_ci#include "src/objects/maybe-object.h" 341cb0ef41Sopenharmony_ci#include "src/objects/object-type.h" 351cb0ef41Sopenharmony_ci#include "src/objects/objects.h" 361cb0ef41Sopenharmony_ci#include "src/objects/oddball.h" 371cb0ef41Sopenharmony_ci#include "src/objects/smi.h" 381cb0ef41Sopenharmony_ci#include "src/objects/tagged-index.h" 391cb0ef41Sopenharmony_ci#include "src/runtime/runtime.h" 401cb0ef41Sopenharmony_ci#include "src/utils/allocation.h" 411cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h" 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_cinamespace v8 { 441cb0ef41Sopenharmony_cinamespace internal { 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci// Forward declarations. 471cb0ef41Sopenharmony_ciclass AsmWasmData; 481cb0ef41Sopenharmony_ciclass AsyncGeneratorRequest; 491cb0ef41Sopenharmony_cistruct AssemblerOptions; 501cb0ef41Sopenharmony_ciclass BigInt; 511cb0ef41Sopenharmony_ciclass CallInterfaceDescriptor; 521cb0ef41Sopenharmony_ciclass Callable; 531cb0ef41Sopenharmony_ciclass Factory; 541cb0ef41Sopenharmony_ciclass InterpreterData; 551cb0ef41Sopenharmony_ciclass Isolate; 561cb0ef41Sopenharmony_ciclass JSAsyncFunctionObject; 571cb0ef41Sopenharmony_ciclass JSAsyncGeneratorObject; 581cb0ef41Sopenharmony_ciclass JSCollator; 591cb0ef41Sopenharmony_ciclass JSCollection; 601cb0ef41Sopenharmony_ciclass JSDateTimeFormat; 611cb0ef41Sopenharmony_ciclass JSDisplayNames; 621cb0ef41Sopenharmony_ciclass JSListFormat; 631cb0ef41Sopenharmony_ciclass JSLocale; 641cb0ef41Sopenharmony_ciclass JSNumberFormat; 651cb0ef41Sopenharmony_ciclass JSPluralRules; 661cb0ef41Sopenharmony_ciclass JSRegExpStringIterator; 671cb0ef41Sopenharmony_ciclass JSRelativeTimeFormat; 681cb0ef41Sopenharmony_ciclass JSSegmentIterator; 691cb0ef41Sopenharmony_ciclass JSSegmenter; 701cb0ef41Sopenharmony_ciclass JSSegments; 711cb0ef41Sopenharmony_ciclass JSV8BreakIterator; 721cb0ef41Sopenharmony_ciclass JSWeakCollection; 731cb0ef41Sopenharmony_ciclass JSFinalizationRegistry; 741cb0ef41Sopenharmony_ciclass JSWeakMap; 751cb0ef41Sopenharmony_ciclass JSWeakRef; 761cb0ef41Sopenharmony_ciclass JSWeakSet; 771cb0ef41Sopenharmony_ciclass ProfileDataFromFile; 781cb0ef41Sopenharmony_ciclass PromiseCapability; 791cb0ef41Sopenharmony_ciclass PromiseFulfillReactionJobTask; 801cb0ef41Sopenharmony_ciclass PromiseReaction; 811cb0ef41Sopenharmony_ciclass PromiseReactionJobTask; 821cb0ef41Sopenharmony_ciclass PromiseRejectReactionJobTask; 831cb0ef41Sopenharmony_ciclass Zone; 841cb0ef41Sopenharmony_ci#define MAKE_FORWARD_DECLARATION(Name) class Name; 851cb0ef41Sopenharmony_ciTORQUE_DEFINED_CLASS_LIST(MAKE_FORWARD_DECLARATION) 861cb0ef41Sopenharmony_ci#undef MAKE_FORWARD_DECLARATION 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_citemplate <typename T> 891cb0ef41Sopenharmony_ciclass Signature; 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_cienum class CheckBounds { kAlways, kDebugOnly }; 921cb0ef41Sopenharmony_ciinline bool NeedsBoundsCheck(CheckBounds check_bounds) { 931cb0ef41Sopenharmony_ci switch (check_bounds) { 941cb0ef41Sopenharmony_ci case CheckBounds::kAlways: 951cb0ef41Sopenharmony_ci return true; 961cb0ef41Sopenharmony_ci case CheckBounds::kDebugOnly: 971cb0ef41Sopenharmony_ci return DEBUG_BOOL; 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci} 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_cienum class StoreToObjectWriteBarrier { kNone, kMap, kFull }; 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ciclass AccessCheckNeeded; 1041cb0ef41Sopenharmony_ciclass BigIntBase; 1051cb0ef41Sopenharmony_ciclass BigIntWrapper; 1061cb0ef41Sopenharmony_ciclass ClassBoilerplate; 1071cb0ef41Sopenharmony_ciclass BooleanWrapper; 1081cb0ef41Sopenharmony_ciclass CompilationCacheTable; 1091cb0ef41Sopenharmony_ciclass Constructor; 1101cb0ef41Sopenharmony_ciclass Filler; 1111cb0ef41Sopenharmony_ciclass FunctionTemplateRareData; 1121cb0ef41Sopenharmony_ciclass HeapNumber; 1131cb0ef41Sopenharmony_ciclass InternalizedString; 1141cb0ef41Sopenharmony_ciclass JSArgumentsObject; 1151cb0ef41Sopenharmony_ciclass JSArrayBufferView; 1161cb0ef41Sopenharmony_ciclass JSContextExtensionObject; 1171cb0ef41Sopenharmony_ciclass JSError; 1181cb0ef41Sopenharmony_ciclass JSSloppyArgumentsObject; 1191cb0ef41Sopenharmony_ciclass MapCache; 1201cb0ef41Sopenharmony_ciclass NativeContext; 1211cb0ef41Sopenharmony_ciclass NumberWrapper; 1221cb0ef41Sopenharmony_ciclass ScriptWrapper; 1231cb0ef41Sopenharmony_ciclass SloppyArgumentsElements; 1241cb0ef41Sopenharmony_ciclass StringWrapper; 1251cb0ef41Sopenharmony_ciclass SymbolWrapper; 1261cb0ef41Sopenharmony_ciclass Undetectable; 1271cb0ef41Sopenharmony_ciclass UniqueName; 1281cb0ef41Sopenharmony_ciclass WasmCapiFunctionData; 1291cb0ef41Sopenharmony_ciclass WasmTagObject; 1301cb0ef41Sopenharmony_ciclass WasmExceptionPackage; 1311cb0ef41Sopenharmony_ciclass WasmExceptionTag; 1321cb0ef41Sopenharmony_ciclass WasmExportedFunctionData; 1331cb0ef41Sopenharmony_ciclass WasmGlobalObject; 1341cb0ef41Sopenharmony_ciclass WasmIndirectFunctionTable; 1351cb0ef41Sopenharmony_ciclass WasmJSFunctionData; 1361cb0ef41Sopenharmony_ciclass WasmMemoryObject; 1371cb0ef41Sopenharmony_ciclass WasmModuleObject; 1381cb0ef41Sopenharmony_ciclass WasmTableObject; 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_citemplate <class T> 1411cb0ef41Sopenharmony_cistruct ObjectTypeOf {}; 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci#define OBJECT_TYPE_CASE(Name) \ 1441cb0ef41Sopenharmony_ci template <> \ 1451cb0ef41Sopenharmony_ci struct ObjectTypeOf<Name> { \ 1461cb0ef41Sopenharmony_ci static const ObjectType value = ObjectType::k##Name; \ 1471cb0ef41Sopenharmony_ci }; 1481cb0ef41Sopenharmony_ci#define OBJECT_TYPE_STRUCT_CASE(NAME, Name, name) \ 1491cb0ef41Sopenharmony_ci template <> \ 1501cb0ef41Sopenharmony_ci struct ObjectTypeOf<Name> { \ 1511cb0ef41Sopenharmony_ci static const ObjectType value = ObjectType::k##Name; \ 1521cb0ef41Sopenharmony_ci }; 1531cb0ef41Sopenharmony_ci#define OBJECT_TYPE_TEMPLATE_CASE(Name) \ 1541cb0ef41Sopenharmony_ci template <class... Args> \ 1551cb0ef41Sopenharmony_ci struct ObjectTypeOf<Name<Args...>> { \ 1561cb0ef41Sopenharmony_ci static const ObjectType value = ObjectType::k##Name; \ 1571cb0ef41Sopenharmony_ci }; 1581cb0ef41Sopenharmony_ciOBJECT_TYPE_CASE(Object) 1591cb0ef41Sopenharmony_ciOBJECT_TYPE_CASE(Smi) 1601cb0ef41Sopenharmony_ciOBJECT_TYPE_CASE(TaggedIndex) 1611cb0ef41Sopenharmony_ciOBJECT_TYPE_CASE(HeapObject) 1621cb0ef41Sopenharmony_ciOBJECT_TYPE_LIST(OBJECT_TYPE_CASE) 1631cb0ef41Sopenharmony_ciHEAP_OBJECT_ORDINARY_TYPE_LIST(OBJECT_TYPE_CASE) 1641cb0ef41Sopenharmony_ciSTRUCT_LIST(OBJECT_TYPE_STRUCT_CASE) 1651cb0ef41Sopenharmony_ciHEAP_OBJECT_TEMPLATE_TYPE_LIST(OBJECT_TYPE_TEMPLATE_CASE) 1661cb0ef41Sopenharmony_ci#undef OBJECT_TYPE_CASE 1671cb0ef41Sopenharmony_ci#undef OBJECT_TYPE_STRUCT_CASE 1681cb0ef41Sopenharmony_ci#undef OBJECT_TYPE_TEMPLATE_CASE 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci#if defined(V8_HOST_ARCH_32_BIT) 1711cb0ef41Sopenharmony_ci#define BINT_IS_SMI 1721cb0ef41Sopenharmony_ciusing BInt = Smi; 1731cb0ef41Sopenharmony_ciusing AtomicInt64 = PairT<IntPtrT, IntPtrT>; 1741cb0ef41Sopenharmony_ciusing AtomicUint64 = PairT<UintPtrT, UintPtrT>; 1751cb0ef41Sopenharmony_ci#elif defined(V8_HOST_ARCH_64_BIT) 1761cb0ef41Sopenharmony_ci#define BINT_IS_INTPTR 1771cb0ef41Sopenharmony_ciusing BInt = IntPtrT; 1781cb0ef41Sopenharmony_ciusing AtomicInt64 = IntPtrT; 1791cb0ef41Sopenharmony_ciusing AtomicUint64 = UintPtrT; 1801cb0ef41Sopenharmony_ci#else 1811cb0ef41Sopenharmony_ci#error Unknown architecture. 1821cb0ef41Sopenharmony_ci#endif 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_cinamespace compiler { 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ciclass CallDescriptor; 1871cb0ef41Sopenharmony_ciclass CodeAssemblerLabel; 1881cb0ef41Sopenharmony_ciclass CodeAssemblerVariable; 1891cb0ef41Sopenharmony_citemplate <class T> 1901cb0ef41Sopenharmony_ciclass TypedCodeAssemblerVariable; 1911cb0ef41Sopenharmony_ciclass CodeAssemblerState; 1921cb0ef41Sopenharmony_ciclass JSGraph; 1931cb0ef41Sopenharmony_ciclass Node; 1941cb0ef41Sopenharmony_ciclass RawMachineAssembler; 1951cb0ef41Sopenharmony_ciclass RawMachineLabel; 1961cb0ef41Sopenharmony_ciclass SourcePositionTable; 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ciusing CodeAssemblerVariableList = ZoneVector<CodeAssemblerVariable*>; 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ciusing CodeAssemblerCallback = std::function<void()>; 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_citemplate <class... Types> 2031cb0ef41Sopenharmony_ciclass CodeAssemblerParameterizedLabel; 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci// This macro alias allows to use PairT<T1, T2> as a macro argument. 2061cb0ef41Sopenharmony_ci#define PAIR_TYPE(T1, T2) PairT<T1, T2> 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci#define CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \ 2091cb0ef41Sopenharmony_ci V(Float32Equal, BoolT, Float32T, Float32T) \ 2101cb0ef41Sopenharmony_ci V(Float32LessThan, BoolT, Float32T, Float32T) \ 2111cb0ef41Sopenharmony_ci V(Float32LessThanOrEqual, BoolT, Float32T, Float32T) \ 2121cb0ef41Sopenharmony_ci V(Float32GreaterThan, BoolT, Float32T, Float32T) \ 2131cb0ef41Sopenharmony_ci V(Float32GreaterThanOrEqual, BoolT, Float32T, Float32T) \ 2141cb0ef41Sopenharmony_ci V(Float64Equal, BoolT, Float64T, Float64T) \ 2151cb0ef41Sopenharmony_ci V(Float64NotEqual, BoolT, Float64T, Float64T) \ 2161cb0ef41Sopenharmony_ci V(Float64LessThan, BoolT, Float64T, Float64T) \ 2171cb0ef41Sopenharmony_ci V(Float64LessThanOrEqual, BoolT, Float64T, Float64T) \ 2181cb0ef41Sopenharmony_ci V(Float64GreaterThan, BoolT, Float64T, Float64T) \ 2191cb0ef41Sopenharmony_ci V(Float64GreaterThanOrEqual, BoolT, Float64T, Float64T) \ 2201cb0ef41Sopenharmony_ci /* Use Word32Equal if you need Int32Equal */ \ 2211cb0ef41Sopenharmony_ci V(Int32GreaterThan, BoolT, Word32T, Word32T) \ 2221cb0ef41Sopenharmony_ci V(Int32GreaterThanOrEqual, BoolT, Word32T, Word32T) \ 2231cb0ef41Sopenharmony_ci V(Int32LessThan, BoolT, Word32T, Word32T) \ 2241cb0ef41Sopenharmony_ci V(Int32LessThanOrEqual, BoolT, Word32T, Word32T) \ 2251cb0ef41Sopenharmony_ci /* Use WordEqual if you need IntPtrEqual */ \ 2261cb0ef41Sopenharmony_ci V(IntPtrLessThan, BoolT, WordT, WordT) \ 2271cb0ef41Sopenharmony_ci V(IntPtrLessThanOrEqual, BoolT, WordT, WordT) \ 2281cb0ef41Sopenharmony_ci V(IntPtrGreaterThan, BoolT, WordT, WordT) \ 2291cb0ef41Sopenharmony_ci V(IntPtrGreaterThanOrEqual, BoolT, WordT, WordT) \ 2301cb0ef41Sopenharmony_ci /* Use Word32Equal if you need Uint32Equal */ \ 2311cb0ef41Sopenharmony_ci V(Uint32LessThan, BoolT, Word32T, Word32T) \ 2321cb0ef41Sopenharmony_ci V(Uint32LessThanOrEqual, BoolT, Word32T, Word32T) \ 2331cb0ef41Sopenharmony_ci V(Uint32GreaterThan, BoolT, Word32T, Word32T) \ 2341cb0ef41Sopenharmony_ci V(Uint32GreaterThanOrEqual, BoolT, Word32T, Word32T) \ 2351cb0ef41Sopenharmony_ci /* Use WordEqual if you need UintPtrEqual */ \ 2361cb0ef41Sopenharmony_ci V(UintPtrLessThan, BoolT, WordT, WordT) \ 2371cb0ef41Sopenharmony_ci V(UintPtrLessThanOrEqual, BoolT, WordT, WordT) \ 2381cb0ef41Sopenharmony_ci V(UintPtrGreaterThan, BoolT, WordT, WordT) \ 2391cb0ef41Sopenharmony_ci V(UintPtrGreaterThanOrEqual, BoolT, WordT, WordT) 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci#define CODE_ASSEMBLER_BINARY_OP_LIST(V) \ 2421cb0ef41Sopenharmony_ci CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \ 2431cb0ef41Sopenharmony_ci V(Float64Add, Float64T, Float64T, Float64T) \ 2441cb0ef41Sopenharmony_ci V(Float64Sub, Float64T, Float64T, Float64T) \ 2451cb0ef41Sopenharmony_ci V(Float64Mul, Float64T, Float64T, Float64T) \ 2461cb0ef41Sopenharmony_ci V(Float64Div, Float64T, Float64T, Float64T) \ 2471cb0ef41Sopenharmony_ci V(Float64Mod, Float64T, Float64T, Float64T) \ 2481cb0ef41Sopenharmony_ci V(Float64Atan2, Float64T, Float64T, Float64T) \ 2491cb0ef41Sopenharmony_ci V(Float64Pow, Float64T, Float64T, Float64T) \ 2501cb0ef41Sopenharmony_ci V(Float64Max, Float64T, Float64T, Float64T) \ 2511cb0ef41Sopenharmony_ci V(Float64Min, Float64T, Float64T, Float64T) \ 2521cb0ef41Sopenharmony_ci V(Float64InsertLowWord32, Float64T, Float64T, Word32T) \ 2531cb0ef41Sopenharmony_ci V(Float64InsertHighWord32, Float64T, Float64T, Word32T) \ 2541cb0ef41Sopenharmony_ci V(I8x16Eq, I8x16T, I8x16T, I8x16T) \ 2551cb0ef41Sopenharmony_ci V(IntPtrAdd, WordT, WordT, WordT) \ 2561cb0ef41Sopenharmony_ci V(IntPtrSub, WordT, WordT, WordT) \ 2571cb0ef41Sopenharmony_ci V(IntPtrMul, WordT, WordT, WordT) \ 2581cb0ef41Sopenharmony_ci V(IntPtrDiv, IntPtrT, IntPtrT, IntPtrT) \ 2591cb0ef41Sopenharmony_ci V(IntPtrAddWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT, IntPtrT) \ 2601cb0ef41Sopenharmony_ci V(IntPtrSubWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT, IntPtrT) \ 2611cb0ef41Sopenharmony_ci V(Int32Add, Word32T, Word32T, Word32T) \ 2621cb0ef41Sopenharmony_ci V(Int32AddWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T) \ 2631cb0ef41Sopenharmony_ci V(Int32Sub, Word32T, Word32T, Word32T) \ 2641cb0ef41Sopenharmony_ci V(Int32SubWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T) \ 2651cb0ef41Sopenharmony_ci V(Int32Mul, Word32T, Word32T, Word32T) \ 2661cb0ef41Sopenharmony_ci V(Int32MulWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T) \ 2671cb0ef41Sopenharmony_ci V(Int32Div, Int32T, Int32T, Int32T) \ 2681cb0ef41Sopenharmony_ci V(Int32Mod, Int32T, Int32T, Int32T) \ 2691cb0ef41Sopenharmony_ci V(Int64Add, Word64T, Word64T, Word64T) \ 2701cb0ef41Sopenharmony_ci V(Int64Sub, Word64T, Word64T, Word64T) \ 2711cb0ef41Sopenharmony_ci V(Int64SubWithOverflow, PAIR_TYPE(Int64T, BoolT), Int64T, Int64T) \ 2721cb0ef41Sopenharmony_ci V(Int64Mul, Word64T, Word64T, Word64T) \ 2731cb0ef41Sopenharmony_ci V(Int64Div, Int64T, Int64T, Int64T) \ 2741cb0ef41Sopenharmony_ci V(Int64Mod, Int64T, Int64T, Int64T) \ 2751cb0ef41Sopenharmony_ci V(WordOr, WordT, WordT, WordT) \ 2761cb0ef41Sopenharmony_ci V(WordAnd, WordT, WordT, WordT) \ 2771cb0ef41Sopenharmony_ci V(WordXor, WordT, WordT, WordT) \ 2781cb0ef41Sopenharmony_ci V(WordRor, WordT, WordT, IntegralT) \ 2791cb0ef41Sopenharmony_ci V(WordShl, WordT, WordT, IntegralT) \ 2801cb0ef41Sopenharmony_ci V(WordShr, WordT, WordT, IntegralT) \ 2811cb0ef41Sopenharmony_ci V(WordSar, WordT, WordT, IntegralT) \ 2821cb0ef41Sopenharmony_ci V(WordSarShiftOutZeros, WordT, WordT, IntegralT) \ 2831cb0ef41Sopenharmony_ci V(Word32Or, Word32T, Word32T, Word32T) \ 2841cb0ef41Sopenharmony_ci V(Word32And, Word32T, Word32T, Word32T) \ 2851cb0ef41Sopenharmony_ci V(Word32Xor, Word32T, Word32T, Word32T) \ 2861cb0ef41Sopenharmony_ci V(Word32Ror, Word32T, Word32T, Word32T) \ 2871cb0ef41Sopenharmony_ci V(Word32Shl, Word32T, Word32T, Word32T) \ 2881cb0ef41Sopenharmony_ci V(Word32Shr, Word32T, Word32T, Word32T) \ 2891cb0ef41Sopenharmony_ci V(Word32Sar, Word32T, Word32T, Word32T) \ 2901cb0ef41Sopenharmony_ci V(Word32SarShiftOutZeros, Word32T, Word32T, Word32T) \ 2911cb0ef41Sopenharmony_ci V(Word64And, Word64T, Word64T, Word64T) \ 2921cb0ef41Sopenharmony_ci V(Word64Or, Word64T, Word64T, Word64T) \ 2931cb0ef41Sopenharmony_ci V(Word64Xor, Word64T, Word64T, Word64T) \ 2941cb0ef41Sopenharmony_ci V(Word64Shl, Word64T, Word64T, Word64T) \ 2951cb0ef41Sopenharmony_ci V(Word64Shr, Word64T, Word64T, Word64T) \ 2961cb0ef41Sopenharmony_ci V(Word64Sar, Word64T, Word64T, Word64T) 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ciTNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b); 2991cb0ef41Sopenharmony_ci 3001cb0ef41Sopenharmony_ci#define CODE_ASSEMBLER_UNARY_OP_LIST(V) \ 3011cb0ef41Sopenharmony_ci V(Float64Abs, Float64T, Float64T) \ 3021cb0ef41Sopenharmony_ci V(Float64Acos, Float64T, Float64T) \ 3031cb0ef41Sopenharmony_ci V(Float64Acosh, Float64T, Float64T) \ 3041cb0ef41Sopenharmony_ci V(Float64Asin, Float64T, Float64T) \ 3051cb0ef41Sopenharmony_ci V(Float64Asinh, Float64T, Float64T) \ 3061cb0ef41Sopenharmony_ci V(Float64Atan, Float64T, Float64T) \ 3071cb0ef41Sopenharmony_ci V(Float64Atanh, Float64T, Float64T) \ 3081cb0ef41Sopenharmony_ci V(Float64Cos, Float64T, Float64T) \ 3091cb0ef41Sopenharmony_ci V(Float64Cosh, Float64T, Float64T) \ 3101cb0ef41Sopenharmony_ci V(Float64Exp, Float64T, Float64T) \ 3111cb0ef41Sopenharmony_ci V(Float64Expm1, Float64T, Float64T) \ 3121cb0ef41Sopenharmony_ci V(Float64Log, Float64T, Float64T) \ 3131cb0ef41Sopenharmony_ci V(Float64Log1p, Float64T, Float64T) \ 3141cb0ef41Sopenharmony_ci V(Float64Log2, Float64T, Float64T) \ 3151cb0ef41Sopenharmony_ci V(Float64Log10, Float64T, Float64T) \ 3161cb0ef41Sopenharmony_ci V(Float64Cbrt, Float64T, Float64T) \ 3171cb0ef41Sopenharmony_ci V(Float64Neg, Float64T, Float64T) \ 3181cb0ef41Sopenharmony_ci V(Float64Sin, Float64T, Float64T) \ 3191cb0ef41Sopenharmony_ci V(Float64Sinh, Float64T, Float64T) \ 3201cb0ef41Sopenharmony_ci V(Float64Sqrt, Float64T, Float64T) \ 3211cb0ef41Sopenharmony_ci V(Float64Tan, Float64T, Float64T) \ 3221cb0ef41Sopenharmony_ci V(Float64Tanh, Float64T, Float64T) \ 3231cb0ef41Sopenharmony_ci V(Float64ExtractLowWord32, Uint32T, Float64T) \ 3241cb0ef41Sopenharmony_ci V(Float64ExtractHighWord32, Uint32T, Float64T) \ 3251cb0ef41Sopenharmony_ci V(BitcastTaggedToWord, IntPtrT, Object) \ 3261cb0ef41Sopenharmony_ci V(BitcastTaggedToWordForTagAndSmiBits, IntPtrT, AnyTaggedT) \ 3271cb0ef41Sopenharmony_ci V(BitcastMaybeObjectToWord, IntPtrT, MaybeObject) \ 3281cb0ef41Sopenharmony_ci V(BitcastWordToTagged, Object, WordT) \ 3291cb0ef41Sopenharmony_ci V(BitcastWordToTaggedSigned, Smi, WordT) \ 3301cb0ef41Sopenharmony_ci V(TruncateFloat64ToFloat32, Float32T, Float64T) \ 3311cb0ef41Sopenharmony_ci V(TruncateFloat64ToWord32, Uint32T, Float64T) \ 3321cb0ef41Sopenharmony_ci V(TruncateInt64ToInt32, Int32T, Int64T) \ 3331cb0ef41Sopenharmony_ci V(ChangeFloat32ToFloat64, Float64T, Float32T) \ 3341cb0ef41Sopenharmony_ci V(ChangeFloat64ToUint32, Uint32T, Float64T) \ 3351cb0ef41Sopenharmony_ci V(ChangeFloat64ToUint64, Uint64T, Float64T) \ 3361cb0ef41Sopenharmony_ci V(ChangeInt32ToFloat64, Float64T, Int32T) \ 3371cb0ef41Sopenharmony_ci V(ChangeInt32ToInt64, Int64T, Int32T) \ 3381cb0ef41Sopenharmony_ci V(ChangeUint32ToFloat64, Float64T, Word32T) \ 3391cb0ef41Sopenharmony_ci V(ChangeUint32ToUint64, Uint64T, Word32T) \ 3401cb0ef41Sopenharmony_ci V(BitcastInt32ToFloat32, Float32T, Word32T) \ 3411cb0ef41Sopenharmony_ci V(BitcastFloat32ToInt32, Uint32T, Float32T) \ 3421cb0ef41Sopenharmony_ci V(RoundFloat64ToInt32, Int32T, Float64T) \ 3431cb0ef41Sopenharmony_ci V(RoundInt32ToFloat32, Float32T, Int32T) \ 3441cb0ef41Sopenharmony_ci V(Float64SilenceNaN, Float64T, Float64T) \ 3451cb0ef41Sopenharmony_ci V(Float64RoundDown, Float64T, Float64T) \ 3461cb0ef41Sopenharmony_ci V(Float64RoundUp, Float64T, Float64T) \ 3471cb0ef41Sopenharmony_ci V(Float64RoundTiesEven, Float64T, Float64T) \ 3481cb0ef41Sopenharmony_ci V(Float64RoundTruncate, Float64T, Float64T) \ 3491cb0ef41Sopenharmony_ci V(Word32Clz, Int32T, Word32T) \ 3501cb0ef41Sopenharmony_ci V(Word64Clz, Int64T, Word64T) \ 3511cb0ef41Sopenharmony_ci V(Word32Ctz, Int32T, Word32T) \ 3521cb0ef41Sopenharmony_ci V(Word64Ctz, Int64T, Word64T) \ 3531cb0ef41Sopenharmony_ci V(Word32Popcnt, Int32T, Word32T) \ 3541cb0ef41Sopenharmony_ci V(Word64Popcnt, Int64T, Word64T) \ 3551cb0ef41Sopenharmony_ci V(Word32BitwiseNot, Word32T, Word32T) \ 3561cb0ef41Sopenharmony_ci V(WordNot, WordT, WordT) \ 3571cb0ef41Sopenharmony_ci V(Word64Not, Word64T, Word64T) \ 3581cb0ef41Sopenharmony_ci V(I8x16BitMask, Int32T, I8x16T) \ 3591cb0ef41Sopenharmony_ci V(I8x16Splat, I8x16T, Int32T) \ 3601cb0ef41Sopenharmony_ci V(Int32AbsWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T) \ 3611cb0ef41Sopenharmony_ci V(Int64AbsWithOverflow, PAIR_TYPE(Int64T, BoolT), Int64T) \ 3621cb0ef41Sopenharmony_ci V(IntPtrAbsWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT) \ 3631cb0ef41Sopenharmony_ci V(Word32BinaryNot, BoolT, Word32T) \ 3641cb0ef41Sopenharmony_ci V(StackPointerGreaterThan, BoolT, WordT) 3651cb0ef41Sopenharmony_ci 3661cb0ef41Sopenharmony_ci// A "public" interface used by components outside of compiler directory to 3671cb0ef41Sopenharmony_ci// create code objects with TurboFan's backend. This class is mostly a thin 3681cb0ef41Sopenharmony_ci// shim around the RawMachineAssembler, and its primary job is to ensure that 3691cb0ef41Sopenharmony_ci// the innards of the RawMachineAssembler and other compiler implementation 3701cb0ef41Sopenharmony_ci// details don't leak outside of the the compiler directory.. 3711cb0ef41Sopenharmony_ci// 3721cb0ef41Sopenharmony_ci// V8 components that need to generate low-level code using this interface 3731cb0ef41Sopenharmony_ci// should include this header--and this header only--from the compiler 3741cb0ef41Sopenharmony_ci// directory (this is actually enforced). Since all interesting data 3751cb0ef41Sopenharmony_ci// structures are forward declared, it's not possible for clients to peek 3761cb0ef41Sopenharmony_ci// inside the compiler internals. 3771cb0ef41Sopenharmony_ci// 3781cb0ef41Sopenharmony_ci// In addition to providing isolation between TurboFan and code generation 3791cb0ef41Sopenharmony_ci// clients, CodeAssembler also provides an abstraction for creating variables 3801cb0ef41Sopenharmony_ci// and enhanced Label functionality to merge variable values along paths where 3811cb0ef41Sopenharmony_ci// they have differing values, including loops. 3821cb0ef41Sopenharmony_ci// 3831cb0ef41Sopenharmony_ci// The CodeAssembler itself is stateless (and instances are expected to be 3841cb0ef41Sopenharmony_ci// temporary-scoped and short-lived); all its state is encapsulated into 3851cb0ef41Sopenharmony_ci// a CodeAssemblerState instance. 3861cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CodeAssembler { 3871cb0ef41Sopenharmony_ci public: 3881cb0ef41Sopenharmony_ci explicit CodeAssembler(CodeAssemblerState* state) : state_(state) {} 3891cb0ef41Sopenharmony_ci ~CodeAssembler(); 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci CodeAssembler(const CodeAssembler&) = delete; 3921cb0ef41Sopenharmony_ci CodeAssembler& operator=(const CodeAssembler&) = delete; 3931cb0ef41Sopenharmony_ci 3941cb0ef41Sopenharmony_ci static Handle<Code> GenerateCode(CodeAssemblerState* state, 3951cb0ef41Sopenharmony_ci const AssemblerOptions& options, 3961cb0ef41Sopenharmony_ci const ProfileDataFromFile* profile_data); 3971cb0ef41Sopenharmony_ci bool Is64() const; 3981cb0ef41Sopenharmony_ci bool Is32() const; 3991cb0ef41Sopenharmony_ci bool IsFloat64RoundUpSupported() const; 4001cb0ef41Sopenharmony_ci bool IsFloat64RoundDownSupported() const; 4011cb0ef41Sopenharmony_ci bool IsFloat64RoundTiesEvenSupported() const; 4021cb0ef41Sopenharmony_ci bool IsFloat64RoundTruncateSupported() const; 4031cb0ef41Sopenharmony_ci bool IsInt32AbsWithOverflowSupported() const; 4041cb0ef41Sopenharmony_ci bool IsInt64AbsWithOverflowSupported() const; 4051cb0ef41Sopenharmony_ci bool IsIntPtrAbsWithOverflowSupported() const; 4061cb0ef41Sopenharmony_ci bool IsWord32PopcntSupported() const; 4071cb0ef41Sopenharmony_ci bool IsWord64PopcntSupported() const; 4081cb0ef41Sopenharmony_ci bool IsWord32CtzSupported() const; 4091cb0ef41Sopenharmony_ci bool IsWord64CtzSupported() const; 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ci // Shortened aliases for use in CodeAssembler subclasses. 4121cb0ef41Sopenharmony_ci using Label = CodeAssemblerLabel; 4131cb0ef41Sopenharmony_ci template <class T> 4141cb0ef41Sopenharmony_ci using TVariable = TypedCodeAssemblerVariable<T>; 4151cb0ef41Sopenharmony_ci using VariableList = CodeAssemblerVariableList; 4161cb0ef41Sopenharmony_ci 4171cb0ef41Sopenharmony_ci // =========================================================================== 4181cb0ef41Sopenharmony_ci // Base Assembler 4191cb0ef41Sopenharmony_ci // =========================================================================== 4201cb0ef41Sopenharmony_ci 4211cb0ef41Sopenharmony_ci template <class PreviousType, bool FromTyped> 4221cb0ef41Sopenharmony_ci class CheckedNode { 4231cb0ef41Sopenharmony_ci public: 4241cb0ef41Sopenharmony_ci#ifdef DEBUG 4251cb0ef41Sopenharmony_ci CheckedNode(Node* node, CodeAssembler* code_assembler, const char* location) 4261cb0ef41Sopenharmony_ci : node_(node), code_assembler_(code_assembler), location_(location) {} 4271cb0ef41Sopenharmony_ci#else 4281cb0ef41Sopenharmony_ci CheckedNode(compiler::Node* node, CodeAssembler*, const char*) 4291cb0ef41Sopenharmony_ci : node_(node) {} 4301cb0ef41Sopenharmony_ci#endif 4311cb0ef41Sopenharmony_ci 4321cb0ef41Sopenharmony_ci template <class A> 4331cb0ef41Sopenharmony_ci operator TNode<A>() { 4341cb0ef41Sopenharmony_ci static_assert( 4351cb0ef41Sopenharmony_ci !std::is_same<A, MaybeObject>::value, 4361cb0ef41Sopenharmony_ci "Can't cast to MaybeObject, use explicit conversion functions. "); 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ci static_assert(types_have_common_values<A, PreviousType>::value, 4391cb0ef41Sopenharmony_ci "Incompatible types: this cast can never succeed."); 4401cb0ef41Sopenharmony_ci static_assert(std::is_convertible<TNode<A>, TNode<Object>>::value, 4411cb0ef41Sopenharmony_ci "Coercion to untagged values cannot be " 4421cb0ef41Sopenharmony_ci "checked."); 4431cb0ef41Sopenharmony_ci static_assert( 4441cb0ef41Sopenharmony_ci !FromTyped || 4451cb0ef41Sopenharmony_ci !std::is_convertible<TNode<PreviousType>, TNode<A>>::value, 4461cb0ef41Sopenharmony_ci "Unnecessary CAST: types are convertible."); 4471cb0ef41Sopenharmony_ci#ifdef DEBUG 4481cb0ef41Sopenharmony_ci if (FLAG_debug_code) { 4491cb0ef41Sopenharmony_ci if (std::is_same<PreviousType, MaybeObject>::value) { 4501cb0ef41Sopenharmony_ci code_assembler_->GenerateCheckMaybeObjectIsObject( 4511cb0ef41Sopenharmony_ci TNode<MaybeObject>::UncheckedCast(node_), location_); 4521cb0ef41Sopenharmony_ci } 4531cb0ef41Sopenharmony_ci TNode<ExternalReference> function = code_assembler_->ExternalConstant( 4541cb0ef41Sopenharmony_ci ExternalReference::check_object_type()); 4551cb0ef41Sopenharmony_ci code_assembler_->CallCFunction( 4561cb0ef41Sopenharmony_ci function, MachineType::AnyTagged(), 4571cb0ef41Sopenharmony_ci std::make_pair(MachineType::AnyTagged(), node_), 4581cb0ef41Sopenharmony_ci std::make_pair(MachineType::TaggedSigned(), 4591cb0ef41Sopenharmony_ci code_assembler_->SmiConstant( 4601cb0ef41Sopenharmony_ci static_cast<int>(ObjectTypeOf<A>::value))), 4611cb0ef41Sopenharmony_ci std::make_pair(MachineType::AnyTagged(), 4621cb0ef41Sopenharmony_ci code_assembler_->StringConstant(location_))); 4631cb0ef41Sopenharmony_ci } 4641cb0ef41Sopenharmony_ci#endif 4651cb0ef41Sopenharmony_ci return TNode<A>::UncheckedCast(node_); 4661cb0ef41Sopenharmony_ci } 4671cb0ef41Sopenharmony_ci 4681cb0ef41Sopenharmony_ci Node* node() const { return node_; } 4691cb0ef41Sopenharmony_ci 4701cb0ef41Sopenharmony_ci private: 4711cb0ef41Sopenharmony_ci Node* node_; 4721cb0ef41Sopenharmony_ci#ifdef DEBUG 4731cb0ef41Sopenharmony_ci CodeAssembler* code_assembler_; 4741cb0ef41Sopenharmony_ci const char* location_; 4751cb0ef41Sopenharmony_ci#endif 4761cb0ef41Sopenharmony_ci }; 4771cb0ef41Sopenharmony_ci 4781cb0ef41Sopenharmony_ci template <class T> 4791cb0ef41Sopenharmony_ci TNode<T> UncheckedCast(Node* value) { 4801cb0ef41Sopenharmony_ci return TNode<T>::UncheckedCast(value); 4811cb0ef41Sopenharmony_ci } 4821cb0ef41Sopenharmony_ci template <class T, class U> 4831cb0ef41Sopenharmony_ci TNode<T> UncheckedCast(TNode<U> value) { 4841cb0ef41Sopenharmony_ci static_assert(types_have_common_values<T, U>::value, 4851cb0ef41Sopenharmony_ci "Incompatible types: this cast can never succeed."); 4861cb0ef41Sopenharmony_ci return TNode<T>::UncheckedCast(value); 4871cb0ef41Sopenharmony_ci } 4881cb0ef41Sopenharmony_ci 4891cb0ef41Sopenharmony_ci // ReinterpretCast<T>(v) has the power to cast even when the type of v is 4901cb0ef41Sopenharmony_ci // unrelated to T. Use with care. 4911cb0ef41Sopenharmony_ci template <class T> 4921cb0ef41Sopenharmony_ci TNode<T> ReinterpretCast(Node* value) { 4931cb0ef41Sopenharmony_ci return TNode<T>::UncheckedCast(value); 4941cb0ef41Sopenharmony_ci } 4951cb0ef41Sopenharmony_ci 4961cb0ef41Sopenharmony_ci CheckedNode<Object, false> Cast(Node* value, const char* location = "") { 4971cb0ef41Sopenharmony_ci return {value, this, location}; 4981cb0ef41Sopenharmony_ci } 4991cb0ef41Sopenharmony_ci 5001cb0ef41Sopenharmony_ci template <class T> 5011cb0ef41Sopenharmony_ci CheckedNode<T, true> Cast(TNode<T> value, const char* location = "") { 5021cb0ef41Sopenharmony_ci return {value, this, location}; 5031cb0ef41Sopenharmony_ci } 5041cb0ef41Sopenharmony_ci 5051cb0ef41Sopenharmony_ci#ifdef DEBUG 5061cb0ef41Sopenharmony_ci#define STRINGIFY(x) #x 5071cb0ef41Sopenharmony_ci#define TO_STRING_LITERAL(x) STRINGIFY(x) 5081cb0ef41Sopenharmony_ci#define CAST(x) \ 5091cb0ef41Sopenharmony_ci Cast(x, "CAST(" #x ") at " __FILE__ ":" TO_STRING_LITERAL(__LINE__)) 5101cb0ef41Sopenharmony_ci#define TORQUE_CAST(x) \ 5111cb0ef41Sopenharmony_ci ca_.Cast(x, "CAST(" #x ") at " __FILE__ ":" TO_STRING_LITERAL(__LINE__)) 5121cb0ef41Sopenharmony_ci#else 5131cb0ef41Sopenharmony_ci#define CAST(x) Cast(x) 5141cb0ef41Sopenharmony_ci#define TORQUE_CAST(x) ca_.Cast(x) 5151cb0ef41Sopenharmony_ci#endif 5161cb0ef41Sopenharmony_ci 5171cb0ef41Sopenharmony_ci#ifdef DEBUG 5181cb0ef41Sopenharmony_ci void GenerateCheckMaybeObjectIsObject(TNode<MaybeObject> node, 5191cb0ef41Sopenharmony_ci const char* location); 5201cb0ef41Sopenharmony_ci#endif 5211cb0ef41Sopenharmony_ci 5221cb0ef41Sopenharmony_ci // Constants. 5231cb0ef41Sopenharmony_ci TNode<Int32T> Int32Constant(int32_t value); 5241cb0ef41Sopenharmony_ci TNode<Int64T> Int64Constant(int64_t value); 5251cb0ef41Sopenharmony_ci TNode<Uint64T> Uint64Constant(uint64_t value) { 5261cb0ef41Sopenharmony_ci return Unsigned(Int64Constant(bit_cast<int64_t>(value))); 5271cb0ef41Sopenharmony_ci } 5281cb0ef41Sopenharmony_ci TNode<IntPtrT> IntPtrConstant(intptr_t value); 5291cb0ef41Sopenharmony_ci TNode<Uint32T> Uint32Constant(uint32_t value) { 5301cb0ef41Sopenharmony_ci return Unsigned(Int32Constant(bit_cast<int32_t>(value))); 5311cb0ef41Sopenharmony_ci } 5321cb0ef41Sopenharmony_ci TNode<UintPtrT> UintPtrConstant(uintptr_t value) { 5331cb0ef41Sopenharmony_ci return Unsigned(IntPtrConstant(bit_cast<intptr_t>(value))); 5341cb0ef41Sopenharmony_ci } 5351cb0ef41Sopenharmony_ci TNode<TaggedIndex> TaggedIndexConstant(intptr_t value); 5361cb0ef41Sopenharmony_ci TNode<RawPtrT> PointerConstant(void* value) { 5371cb0ef41Sopenharmony_ci return ReinterpretCast<RawPtrT>(IntPtrConstant(bit_cast<intptr_t>(value))); 5381cb0ef41Sopenharmony_ci } 5391cb0ef41Sopenharmony_ci TNode<Number> NumberConstant(double value); 5401cb0ef41Sopenharmony_ci TNode<Smi> SmiConstant(Smi value); 5411cb0ef41Sopenharmony_ci TNode<Smi> SmiConstant(int value); 5421cb0ef41Sopenharmony_ci template <typename E, 5431cb0ef41Sopenharmony_ci typename = typename std::enable_if<std::is_enum<E>::value>::type> 5441cb0ef41Sopenharmony_ci TNode<Smi> SmiConstant(E value) { 5451cb0ef41Sopenharmony_ci STATIC_ASSERT(sizeof(E) <= sizeof(int)); 5461cb0ef41Sopenharmony_ci return SmiConstant(static_cast<int>(value)); 5471cb0ef41Sopenharmony_ci } 5481cb0ef41Sopenharmony_ci TNode<HeapObject> UntypedHeapConstant(Handle<HeapObject> object); 5491cb0ef41Sopenharmony_ci template <class Type> 5501cb0ef41Sopenharmony_ci TNode<Type> HeapConstant(Handle<Type> object) { 5511cb0ef41Sopenharmony_ci return UncheckedCast<Type>(UntypedHeapConstant(object)); 5521cb0ef41Sopenharmony_ci } 5531cb0ef41Sopenharmony_ci TNode<String> StringConstant(const char* str); 5541cb0ef41Sopenharmony_ci TNode<Oddball> BooleanConstant(bool value); 5551cb0ef41Sopenharmony_ci TNode<ExternalReference> ExternalConstant(ExternalReference address); 5561cb0ef41Sopenharmony_ci TNode<Float32T> Float32Constant(double value); 5571cb0ef41Sopenharmony_ci TNode<Float64T> Float64Constant(double value); 5581cb0ef41Sopenharmony_ci TNode<BoolT> Int32TrueConstant() { 5591cb0ef41Sopenharmony_ci return ReinterpretCast<BoolT>(Int32Constant(1)); 5601cb0ef41Sopenharmony_ci } 5611cb0ef41Sopenharmony_ci TNode<BoolT> Int32FalseConstant() { 5621cb0ef41Sopenharmony_ci return ReinterpretCast<BoolT>(Int32Constant(0)); 5631cb0ef41Sopenharmony_ci } 5641cb0ef41Sopenharmony_ci TNode<BoolT> BoolConstant(bool value) { 5651cb0ef41Sopenharmony_ci return value ? Int32TrueConstant() : Int32FalseConstant(); 5661cb0ef41Sopenharmony_ci } 5671cb0ef41Sopenharmony_ci 5681cb0ef41Sopenharmony_ci bool IsMapOffsetConstant(Node* node); 5691cb0ef41Sopenharmony_ci 5701cb0ef41Sopenharmony_ci bool TryToInt32Constant(TNode<IntegralT> node, int32_t* out_value); 5711cb0ef41Sopenharmony_ci bool TryToInt64Constant(TNode<IntegralT> node, int64_t* out_value); 5721cb0ef41Sopenharmony_ci bool TryToIntPtrConstant(TNode<IntegralT> node, intptr_t* out_value); 5731cb0ef41Sopenharmony_ci bool TryToIntPtrConstant(TNode<Smi> tnode, intptr_t* out_value); 5741cb0ef41Sopenharmony_ci bool TryToSmiConstant(TNode<IntegralT> node, Smi* out_value); 5751cb0ef41Sopenharmony_ci bool TryToSmiConstant(TNode<Smi> node, Smi* out_value); 5761cb0ef41Sopenharmony_ci 5771cb0ef41Sopenharmony_ci bool IsUndefinedConstant(TNode<Object> node); 5781cb0ef41Sopenharmony_ci bool IsNullConstant(TNode<Object> node); 5791cb0ef41Sopenharmony_ci 5801cb0ef41Sopenharmony_ci TNode<Int32T> Signed(TNode<Word32T> x) { return UncheckedCast<Int32T>(x); } 5811cb0ef41Sopenharmony_ci TNode<Int64T> Signed(TNode<Word64T> x) { return UncheckedCast<Int64T>(x); } 5821cb0ef41Sopenharmony_ci TNode<IntPtrT> Signed(TNode<WordT> x) { return UncheckedCast<IntPtrT>(x); } 5831cb0ef41Sopenharmony_ci TNode<Uint32T> Unsigned(TNode<Word32T> x) { 5841cb0ef41Sopenharmony_ci return UncheckedCast<Uint32T>(x); 5851cb0ef41Sopenharmony_ci } 5861cb0ef41Sopenharmony_ci TNode<Uint64T> Unsigned(TNode<Word64T> x) { 5871cb0ef41Sopenharmony_ci return UncheckedCast<Uint64T>(x); 5881cb0ef41Sopenharmony_ci } 5891cb0ef41Sopenharmony_ci TNode<UintPtrT> Unsigned(TNode<WordT> x) { 5901cb0ef41Sopenharmony_ci return UncheckedCast<UintPtrT>(x); 5911cb0ef41Sopenharmony_ci } 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_ci static constexpr int kTargetParameterIndex = -1; 5941cb0ef41Sopenharmony_ci 5951cb0ef41Sopenharmony_ci template <class T> 5961cb0ef41Sopenharmony_ci TNode<T> Parameter( 5971cb0ef41Sopenharmony_ci int value, cppgc::SourceLocation loc = cppgc::SourceLocation::Current()) { 5981cb0ef41Sopenharmony_ci static_assert( 5991cb0ef41Sopenharmony_ci std::is_convertible<TNode<T>, TNode<Object>>::value, 6001cb0ef41Sopenharmony_ci "Parameter is only for tagged types. Use UncheckedParameter instead."); 6011cb0ef41Sopenharmony_ci std::stringstream message; 6021cb0ef41Sopenharmony_ci message << "Parameter " << value; 6031cb0ef41Sopenharmony_ci if (loc.FileName()) { 6041cb0ef41Sopenharmony_ci message << " at " << loc.FileName() << ":" << loc.Line(); 6051cb0ef41Sopenharmony_ci } 6061cb0ef41Sopenharmony_ci size_t buf_size = message.str().size() + 1; 6071cb0ef41Sopenharmony_ci char* message_dup = zone()->NewArray<char>(buf_size); 6081cb0ef41Sopenharmony_ci snprintf(message_dup, buf_size, "%s", message.str().c_str()); 6091cb0ef41Sopenharmony_ci 6101cb0ef41Sopenharmony_ci return Cast(UntypedParameter(value), message_dup); 6111cb0ef41Sopenharmony_ci } 6121cb0ef41Sopenharmony_ci 6131cb0ef41Sopenharmony_ci template <class T> 6141cb0ef41Sopenharmony_ci TNode<T> UncheckedParameter(int value) { 6151cb0ef41Sopenharmony_ci return UncheckedCast<T>(UntypedParameter(value)); 6161cb0ef41Sopenharmony_ci } 6171cb0ef41Sopenharmony_ci 6181cb0ef41Sopenharmony_ci Node* UntypedParameter(int value); 6191cb0ef41Sopenharmony_ci 6201cb0ef41Sopenharmony_ci TNode<Context> GetJSContextParameter(); 6211cb0ef41Sopenharmony_ci void Return(TNode<Object> value); 6221cb0ef41Sopenharmony_ci void Return(TNode<Object> value1, TNode<Object> value2); 6231cb0ef41Sopenharmony_ci void Return(TNode<Object> value1, TNode<Object> value2, TNode<Object> value3); 6241cb0ef41Sopenharmony_ci void Return(TNode<Int32T> value); 6251cb0ef41Sopenharmony_ci void Return(TNode<Uint32T> value); 6261cb0ef41Sopenharmony_ci void Return(TNode<WordT> value); 6271cb0ef41Sopenharmony_ci void Return(TNode<Float32T> value); 6281cb0ef41Sopenharmony_ci void Return(TNode<Float64T> value); 6291cb0ef41Sopenharmony_ci void Return(TNode<WordT> value1, TNode<WordT> value2); 6301cb0ef41Sopenharmony_ci void Return(TNode<WordT> value1, TNode<Object> value2); 6311cb0ef41Sopenharmony_ci void PopAndReturn(Node* pop, Node* value); 6321cb0ef41Sopenharmony_ci 6331cb0ef41Sopenharmony_ci void ReturnIf(TNode<BoolT> condition, TNode<Object> value); 6341cb0ef41Sopenharmony_ci 6351cb0ef41Sopenharmony_ci void AbortCSADcheck(Node* message); 6361cb0ef41Sopenharmony_ci void DebugBreak(); 6371cb0ef41Sopenharmony_ci void Unreachable(); 6381cb0ef41Sopenharmony_ci void Comment(const char* msg) { 6391cb0ef41Sopenharmony_ci if (!FLAG_code_comments) return; 6401cb0ef41Sopenharmony_ci Comment(std::string(msg)); 6411cb0ef41Sopenharmony_ci } 6421cb0ef41Sopenharmony_ci void Comment(std::string msg); 6431cb0ef41Sopenharmony_ci template <class... Args> 6441cb0ef41Sopenharmony_ci void Comment(Args&&... args) { 6451cb0ef41Sopenharmony_ci if (!FLAG_code_comments) return; 6461cb0ef41Sopenharmony_ci std::ostringstream s; 6471cb0ef41Sopenharmony_ci USE((s << std::forward<Args>(args))...); 6481cb0ef41Sopenharmony_ci Comment(s.str()); 6491cb0ef41Sopenharmony_ci } 6501cb0ef41Sopenharmony_ci 6511cb0ef41Sopenharmony_ci void StaticAssert(TNode<BoolT> value, 6521cb0ef41Sopenharmony_ci const char* source = "unknown position"); 6531cb0ef41Sopenharmony_ci 6541cb0ef41Sopenharmony_ci // The following methods refer to source positions in CSA or Torque code 6551cb0ef41Sopenharmony_ci // compiled during mksnapshot, not JS compiled at runtime. 6561cb0ef41Sopenharmony_ci void SetSourcePosition(const char* file, int line); 6571cb0ef41Sopenharmony_ci void PushSourcePosition(); 6581cb0ef41Sopenharmony_ci void PopSourcePosition(); 6591cb0ef41Sopenharmony_ci class V8_NODISCARD SourcePositionScope { 6601cb0ef41Sopenharmony_ci public: 6611cb0ef41Sopenharmony_ci explicit SourcePositionScope(CodeAssembler* ca) : ca_(ca) { 6621cb0ef41Sopenharmony_ci ca->PushSourcePosition(); 6631cb0ef41Sopenharmony_ci } 6641cb0ef41Sopenharmony_ci ~SourcePositionScope() { ca_->PopSourcePosition(); } 6651cb0ef41Sopenharmony_ci 6661cb0ef41Sopenharmony_ci private: 6671cb0ef41Sopenharmony_ci CodeAssembler* ca_; 6681cb0ef41Sopenharmony_ci }; 6691cb0ef41Sopenharmony_ci const std::vector<FileAndLine>& GetMacroSourcePositionStack() const; 6701cb0ef41Sopenharmony_ci 6711cb0ef41Sopenharmony_ci void Bind(Label* label); 6721cb0ef41Sopenharmony_ci#if DEBUG 6731cb0ef41Sopenharmony_ci void Bind(Label* label, AssemblerDebugInfo debug_info); 6741cb0ef41Sopenharmony_ci#endif // DEBUG 6751cb0ef41Sopenharmony_ci void Goto(Label* label); 6761cb0ef41Sopenharmony_ci void GotoIf(TNode<IntegralT> condition, Label* true_label); 6771cb0ef41Sopenharmony_ci void GotoIfNot(TNode<IntegralT> condition, Label* false_label); 6781cb0ef41Sopenharmony_ci void Branch(TNode<IntegralT> condition, Label* true_label, 6791cb0ef41Sopenharmony_ci Label* false_label); 6801cb0ef41Sopenharmony_ci 6811cb0ef41Sopenharmony_ci template <class T> 6821cb0ef41Sopenharmony_ci TNode<T> Uninitialized() { 6831cb0ef41Sopenharmony_ci return {}; 6841cb0ef41Sopenharmony_ci } 6851cb0ef41Sopenharmony_ci 6861cb0ef41Sopenharmony_ci template <class... T> 6871cb0ef41Sopenharmony_ci void Bind(CodeAssemblerParameterizedLabel<T...>* label, TNode<T>*... phis) { 6881cb0ef41Sopenharmony_ci Bind(label->plain_label()); 6891cb0ef41Sopenharmony_ci label->CreatePhis(phis...); 6901cb0ef41Sopenharmony_ci } 6911cb0ef41Sopenharmony_ci template <class... T, class... Args> 6921cb0ef41Sopenharmony_ci void Branch(TNode<BoolT> condition, 6931cb0ef41Sopenharmony_ci CodeAssemblerParameterizedLabel<T...>* if_true, 6941cb0ef41Sopenharmony_ci CodeAssemblerParameterizedLabel<T...>* if_false, Args... args) { 6951cb0ef41Sopenharmony_ci if_true->AddInputs(args...); 6961cb0ef41Sopenharmony_ci if_false->AddInputs(args...); 6971cb0ef41Sopenharmony_ci Branch(condition, if_true->plain_label(), if_false->plain_label()); 6981cb0ef41Sopenharmony_ci } 6991cb0ef41Sopenharmony_ci template <class... T, class... U> 7001cb0ef41Sopenharmony_ci void Branch(TNode<BoolT> condition, 7011cb0ef41Sopenharmony_ci CodeAssemblerParameterizedLabel<T...>* if_true, 7021cb0ef41Sopenharmony_ci std::vector<Node*> args_true, 7031cb0ef41Sopenharmony_ci CodeAssemblerParameterizedLabel<U...>* if_false, 7041cb0ef41Sopenharmony_ci std::vector<Node*> args_false) { 7051cb0ef41Sopenharmony_ci if_true->AddInputsVector(std::move(args_true)); 7061cb0ef41Sopenharmony_ci if_false->AddInputsVector(std::move(args_false)); 7071cb0ef41Sopenharmony_ci Branch(condition, if_true->plain_label(), if_false->plain_label()); 7081cb0ef41Sopenharmony_ci } 7091cb0ef41Sopenharmony_ci 7101cb0ef41Sopenharmony_ci template <class... T, class... Args> 7111cb0ef41Sopenharmony_ci void Goto(CodeAssemblerParameterizedLabel<T...>* label, Args... args) { 7121cb0ef41Sopenharmony_ci label->AddInputs(args...); 7131cb0ef41Sopenharmony_ci Goto(label->plain_label()); 7141cb0ef41Sopenharmony_ci } 7151cb0ef41Sopenharmony_ci 7161cb0ef41Sopenharmony_ci void Branch(TNode<BoolT> condition, const std::function<void()>& true_body, 7171cb0ef41Sopenharmony_ci const std::function<void()>& false_body); 7181cb0ef41Sopenharmony_ci void Branch(TNode<BoolT> condition, Label* true_label, 7191cb0ef41Sopenharmony_ci const std::function<void()>& false_body); 7201cb0ef41Sopenharmony_ci void Branch(TNode<BoolT> condition, const std::function<void()>& true_body, 7211cb0ef41Sopenharmony_ci Label* false_label); 7221cb0ef41Sopenharmony_ci 7231cb0ef41Sopenharmony_ci void Switch(Node* index, Label* default_label, const int32_t* case_values, 7241cb0ef41Sopenharmony_ci Label** case_labels, size_t case_count); 7251cb0ef41Sopenharmony_ci 7261cb0ef41Sopenharmony_ci // Access to the frame pointer 7271cb0ef41Sopenharmony_ci TNode<RawPtrT> LoadFramePointer(); 7281cb0ef41Sopenharmony_ci TNode<RawPtrT> LoadParentFramePointer(); 7291cb0ef41Sopenharmony_ci 7301cb0ef41Sopenharmony_ci // Load raw memory location. 7311cb0ef41Sopenharmony_ci Node* Load(MachineType type, Node* base); 7321cb0ef41Sopenharmony_ci template <class Type> 7331cb0ef41Sopenharmony_ci TNode<Type> Load(MachineType type, TNode<RawPtr<Type>> base) { 7341cb0ef41Sopenharmony_ci DCHECK( 7351cb0ef41Sopenharmony_ci IsSubtype(type.representation(), MachineRepresentationOf<Type>::value)); 7361cb0ef41Sopenharmony_ci return UncheckedCast<Type>(Load(type, static_cast<Node*>(base))); 7371cb0ef41Sopenharmony_ci } 7381cb0ef41Sopenharmony_ci Node* Load(MachineType type, Node* base, Node* offset); 7391cb0ef41Sopenharmony_ci template <class Type> 7401cb0ef41Sopenharmony_ci TNode<Type> Load(Node* base) { 7411cb0ef41Sopenharmony_ci return UncheckedCast<Type>(Load(MachineTypeOf<Type>::value, base)); 7421cb0ef41Sopenharmony_ci } 7431cb0ef41Sopenharmony_ci template <class Type> 7441cb0ef41Sopenharmony_ci TNode<Type> Load(Node* base, TNode<WordT> offset) { 7451cb0ef41Sopenharmony_ci return UncheckedCast<Type>(Load(MachineTypeOf<Type>::value, base, offset)); 7461cb0ef41Sopenharmony_ci } 7471cb0ef41Sopenharmony_ci template <class Type> 7481cb0ef41Sopenharmony_ci TNode<Type> AtomicLoad(AtomicMemoryOrder order, TNode<RawPtrT> base, 7491cb0ef41Sopenharmony_ci TNode<WordT> offset) { 7501cb0ef41Sopenharmony_ci return UncheckedCast<Type>( 7511cb0ef41Sopenharmony_ci AtomicLoad(MachineTypeOf<Type>::value, order, base, offset)); 7521cb0ef41Sopenharmony_ci } 7531cb0ef41Sopenharmony_ci template <class Type> 7541cb0ef41Sopenharmony_ci TNode<Type> AtomicLoad64(AtomicMemoryOrder order, TNode<RawPtrT> base, 7551cb0ef41Sopenharmony_ci TNode<WordT> offset); 7561cb0ef41Sopenharmony_ci // Load uncompressed tagged value from (most likely off JS heap) memory 7571cb0ef41Sopenharmony_ci // location. 7581cb0ef41Sopenharmony_ci TNode<Object> LoadFullTagged(Node* base); 7591cb0ef41Sopenharmony_ci TNode<Object> LoadFullTagged(Node* base, TNode<IntPtrT> offset); 7601cb0ef41Sopenharmony_ci 7611cb0ef41Sopenharmony_ci Node* LoadFromObject(MachineType type, TNode<Object> object, 7621cb0ef41Sopenharmony_ci TNode<IntPtrT> offset); 7631cb0ef41Sopenharmony_ci 7641cb0ef41Sopenharmony_ci#ifdef V8_MAP_PACKING 7651cb0ef41Sopenharmony_ci Node* PackMapWord(Node* value); 7661cb0ef41Sopenharmony_ci#endif 7671cb0ef41Sopenharmony_ci 7681cb0ef41Sopenharmony_ci // Load a value from the root array. 7691cb0ef41Sopenharmony_ci // If map packing is enabled, LoadRoot for a root map returns the unpacked map 7701cb0ef41Sopenharmony_ci // word (i.e., the map). Use LoadRootMapWord to obtain the packed map word 7711cb0ef41Sopenharmony_ci // instead. 7721cb0ef41Sopenharmony_ci TNode<Object> LoadRoot(RootIndex root_index); 7731cb0ef41Sopenharmony_ci TNode<AnyTaggedT> LoadRootMapWord(RootIndex root_index); 7741cb0ef41Sopenharmony_ci 7751cb0ef41Sopenharmony_ci template <typename Type> 7761cb0ef41Sopenharmony_ci TNode<Type> UnalignedLoad(TNode<RawPtrT> base, TNode<IntPtrT> offset) { 7771cb0ef41Sopenharmony_ci MachineType mt = MachineTypeOf<Type>::value; 7781cb0ef41Sopenharmony_ci return UncheckedCast<Type>(UnalignedLoad(mt, base, offset)); 7791cb0ef41Sopenharmony_ci } 7801cb0ef41Sopenharmony_ci 7811cb0ef41Sopenharmony_ci // Store value to raw memory location. 7821cb0ef41Sopenharmony_ci void Store(Node* base, Node* value); 7831cb0ef41Sopenharmony_ci void Store(Node* base, Node* offset, Node* value); 7841cb0ef41Sopenharmony_ci void StoreEphemeronKey(Node* base, Node* offset, Node* value); 7851cb0ef41Sopenharmony_ci void StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value); 7861cb0ef41Sopenharmony_ci void StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* offset, 7871cb0ef41Sopenharmony_ci Node* value); 7881cb0ef41Sopenharmony_ci void UnsafeStoreNoWriteBarrier(MachineRepresentation rep, Node* base, 7891cb0ef41Sopenharmony_ci Node* value); 7901cb0ef41Sopenharmony_ci void UnsafeStoreNoWriteBarrier(MachineRepresentation rep, Node* base, 7911cb0ef41Sopenharmony_ci Node* offset, Node* value); 7921cb0ef41Sopenharmony_ci 7931cb0ef41Sopenharmony_ci // Stores uncompressed tagged value to (most likely off JS heap) memory 7941cb0ef41Sopenharmony_ci // location without write barrier. 7951cb0ef41Sopenharmony_ci void StoreFullTaggedNoWriteBarrier(TNode<RawPtrT> base, 7961cb0ef41Sopenharmony_ci TNode<Object> tagged_value); 7971cb0ef41Sopenharmony_ci void StoreFullTaggedNoWriteBarrier(TNode<RawPtrT> base, TNode<IntPtrT> offset, 7981cb0ef41Sopenharmony_ci TNode<Object> tagged_value); 7991cb0ef41Sopenharmony_ci 8001cb0ef41Sopenharmony_ci // Optimized memory operations that map to Turbofan simplified nodes. 8011cb0ef41Sopenharmony_ci TNode<HeapObject> OptimizedAllocate(TNode<IntPtrT> size, 8021cb0ef41Sopenharmony_ci AllocationType allocation, 8031cb0ef41Sopenharmony_ci AllowLargeObjects allow_large_objects); 8041cb0ef41Sopenharmony_ci void StoreToObject(MachineRepresentation rep, TNode<Object> object, 8051cb0ef41Sopenharmony_ci TNode<IntPtrT> offset, Node* value, 8061cb0ef41Sopenharmony_ci StoreToObjectWriteBarrier write_barrier); 8071cb0ef41Sopenharmony_ci void OptimizedStoreField(MachineRepresentation rep, TNode<HeapObject> object, 8081cb0ef41Sopenharmony_ci int offset, Node* value); 8091cb0ef41Sopenharmony_ci void OptimizedStoreFieldAssertNoWriteBarrier(MachineRepresentation rep, 8101cb0ef41Sopenharmony_ci TNode<HeapObject> object, 8111cb0ef41Sopenharmony_ci int offset, Node* value); 8121cb0ef41Sopenharmony_ci void OptimizedStoreFieldUnsafeNoWriteBarrier(MachineRepresentation rep, 8131cb0ef41Sopenharmony_ci TNode<HeapObject> object, 8141cb0ef41Sopenharmony_ci int offset, Node* value); 8151cb0ef41Sopenharmony_ci void OptimizedStoreMap(TNode<HeapObject> object, TNode<Map>); 8161cb0ef41Sopenharmony_ci void AtomicStore(MachineRepresentation rep, AtomicMemoryOrder order, 8171cb0ef41Sopenharmony_ci TNode<RawPtrT> base, TNode<WordT> offset, 8181cb0ef41Sopenharmony_ci TNode<Word32T> value); 8191cb0ef41Sopenharmony_ci // {value_high} is used for 64-bit stores on 32-bit platforms, must be 8201cb0ef41Sopenharmony_ci // nullptr in other cases. 8211cb0ef41Sopenharmony_ci void AtomicStore64(AtomicMemoryOrder order, TNode<RawPtrT> base, 8221cb0ef41Sopenharmony_ci TNode<WordT> offset, TNode<UintPtrT> value, 8231cb0ef41Sopenharmony_ci TNode<UintPtrT> value_high); 8241cb0ef41Sopenharmony_ci 8251cb0ef41Sopenharmony_ci TNode<Word32T> AtomicAdd(MachineType type, TNode<RawPtrT> base, 8261cb0ef41Sopenharmony_ci TNode<UintPtrT> offset, TNode<Word32T> value); 8271cb0ef41Sopenharmony_ci template <class Type> 8281cb0ef41Sopenharmony_ci TNode<Type> AtomicAdd64(TNode<RawPtrT> base, TNode<UintPtrT> offset, 8291cb0ef41Sopenharmony_ci TNode<UintPtrT> value, TNode<UintPtrT> value_high); 8301cb0ef41Sopenharmony_ci 8311cb0ef41Sopenharmony_ci TNode<Word32T> AtomicSub(MachineType type, TNode<RawPtrT> base, 8321cb0ef41Sopenharmony_ci TNode<UintPtrT> offset, TNode<Word32T> value); 8331cb0ef41Sopenharmony_ci template <class Type> 8341cb0ef41Sopenharmony_ci TNode<Type> AtomicSub64(TNode<RawPtrT> base, TNode<UintPtrT> offset, 8351cb0ef41Sopenharmony_ci TNode<UintPtrT> value, TNode<UintPtrT> value_high); 8361cb0ef41Sopenharmony_ci 8371cb0ef41Sopenharmony_ci TNode<Word32T> AtomicAnd(MachineType type, TNode<RawPtrT> base, 8381cb0ef41Sopenharmony_ci TNode<UintPtrT> offset, TNode<Word32T> value); 8391cb0ef41Sopenharmony_ci template <class Type> 8401cb0ef41Sopenharmony_ci TNode<Type> AtomicAnd64(TNode<RawPtrT> base, TNode<UintPtrT> offset, 8411cb0ef41Sopenharmony_ci TNode<UintPtrT> value, TNode<UintPtrT> value_high); 8421cb0ef41Sopenharmony_ci 8431cb0ef41Sopenharmony_ci TNode<Word32T> AtomicOr(MachineType type, TNode<RawPtrT> base, 8441cb0ef41Sopenharmony_ci TNode<UintPtrT> offset, TNode<Word32T> value); 8451cb0ef41Sopenharmony_ci template <class Type> 8461cb0ef41Sopenharmony_ci TNode<Type> AtomicOr64(TNode<RawPtrT> base, TNode<UintPtrT> offset, 8471cb0ef41Sopenharmony_ci TNode<UintPtrT> value, TNode<UintPtrT> value_high); 8481cb0ef41Sopenharmony_ci 8491cb0ef41Sopenharmony_ci TNode<Word32T> AtomicXor(MachineType type, TNode<RawPtrT> base, 8501cb0ef41Sopenharmony_ci TNode<UintPtrT> offset, TNode<Word32T> value); 8511cb0ef41Sopenharmony_ci template <class Type> 8521cb0ef41Sopenharmony_ci TNode<Type> AtomicXor64(TNode<RawPtrT> base, TNode<UintPtrT> offset, 8531cb0ef41Sopenharmony_ci TNode<UintPtrT> value, TNode<UintPtrT> value_high); 8541cb0ef41Sopenharmony_ci 8551cb0ef41Sopenharmony_ci // Exchange value at raw memory location 8561cb0ef41Sopenharmony_ci TNode<Word32T> AtomicExchange(MachineType type, TNode<RawPtrT> base, 8571cb0ef41Sopenharmony_ci TNode<UintPtrT> offset, TNode<Word32T> value); 8581cb0ef41Sopenharmony_ci template <class Type> 8591cb0ef41Sopenharmony_ci TNode<Type> AtomicExchange64(TNode<RawPtrT> base, TNode<UintPtrT> offset, 8601cb0ef41Sopenharmony_ci TNode<UintPtrT> value, 8611cb0ef41Sopenharmony_ci TNode<UintPtrT> value_high); 8621cb0ef41Sopenharmony_ci 8631cb0ef41Sopenharmony_ci // Compare and Exchange value at raw memory location 8641cb0ef41Sopenharmony_ci TNode<Word32T> AtomicCompareExchange(MachineType type, TNode<RawPtrT> base, 8651cb0ef41Sopenharmony_ci TNode<WordT> offset, 8661cb0ef41Sopenharmony_ci TNode<Word32T> old_value, 8671cb0ef41Sopenharmony_ci TNode<Word32T> new_value); 8681cb0ef41Sopenharmony_ci 8691cb0ef41Sopenharmony_ci template <class Type> 8701cb0ef41Sopenharmony_ci TNode<Type> AtomicCompareExchange64(TNode<RawPtrT> base, TNode<WordT> offset, 8711cb0ef41Sopenharmony_ci TNode<UintPtrT> old_value, 8721cb0ef41Sopenharmony_ci TNode<UintPtrT> new_value, 8731cb0ef41Sopenharmony_ci TNode<UintPtrT> old_value_high, 8741cb0ef41Sopenharmony_ci TNode<UintPtrT> new_value_high); 8751cb0ef41Sopenharmony_ci 8761cb0ef41Sopenharmony_ci // Store a value to the root array. 8771cb0ef41Sopenharmony_ci void StoreRoot(RootIndex root_index, TNode<Object> value); 8781cb0ef41Sopenharmony_ci 8791cb0ef41Sopenharmony_ci// Basic arithmetic operations. 8801cb0ef41Sopenharmony_ci#define DECLARE_CODE_ASSEMBLER_BINARY_OP(name, ResType, Arg1Type, Arg2Type) \ 8811cb0ef41Sopenharmony_ci TNode<ResType> name(TNode<Arg1Type> a, TNode<Arg2Type> b); 8821cb0ef41Sopenharmony_ci CODE_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_ASSEMBLER_BINARY_OP) 8831cb0ef41Sopenharmony_ci#undef DECLARE_CODE_ASSEMBLER_BINARY_OP 8841cb0ef41Sopenharmony_ci 8851cb0ef41Sopenharmony_ci TNode<UintPtrT> WordShr(TNode<UintPtrT> left, TNode<IntegralT> right) { 8861cb0ef41Sopenharmony_ci return Unsigned(WordShr(static_cast<TNode<WordT>>(left), right)); 8871cb0ef41Sopenharmony_ci } 8881cb0ef41Sopenharmony_ci TNode<IntPtrT> WordSar(TNode<IntPtrT> left, TNode<IntegralT> right) { 8891cb0ef41Sopenharmony_ci return Signed(WordSar(static_cast<TNode<WordT>>(left), right)); 8901cb0ef41Sopenharmony_ci } 8911cb0ef41Sopenharmony_ci TNode<IntPtrT> WordShl(TNode<IntPtrT> left, TNode<IntegralT> right) { 8921cb0ef41Sopenharmony_ci return Signed(WordShl(static_cast<TNode<WordT>>(left), right)); 8931cb0ef41Sopenharmony_ci } 8941cb0ef41Sopenharmony_ci TNode<UintPtrT> WordShl(TNode<UintPtrT> left, TNode<IntegralT> right) { 8951cb0ef41Sopenharmony_ci return Unsigned(WordShl(static_cast<TNode<WordT>>(left), right)); 8961cb0ef41Sopenharmony_ci } 8971cb0ef41Sopenharmony_ci 8981cb0ef41Sopenharmony_ci TNode<Int32T> Word32Shl(TNode<Int32T> left, TNode<Int32T> right) { 8991cb0ef41Sopenharmony_ci return Signed(Word32Shl(static_cast<TNode<Word32T>>(left), right)); 9001cb0ef41Sopenharmony_ci } 9011cb0ef41Sopenharmony_ci TNode<Uint32T> Word32Shl(TNode<Uint32T> left, TNode<Uint32T> right) { 9021cb0ef41Sopenharmony_ci return Unsigned(Word32Shl(static_cast<TNode<Word32T>>(left), right)); 9031cb0ef41Sopenharmony_ci } 9041cb0ef41Sopenharmony_ci TNode<Uint32T> Word32Shr(TNode<Uint32T> left, TNode<Uint32T> right) { 9051cb0ef41Sopenharmony_ci return Unsigned(Word32Shr(static_cast<TNode<Word32T>>(left), right)); 9061cb0ef41Sopenharmony_ci } 9071cb0ef41Sopenharmony_ci TNode<Int32T> Word32Sar(TNode<Int32T> left, TNode<Int32T> right) { 9081cb0ef41Sopenharmony_ci return Signed(Word32Sar(static_cast<TNode<Word32T>>(left), right)); 9091cb0ef41Sopenharmony_ci } 9101cb0ef41Sopenharmony_ci 9111cb0ef41Sopenharmony_ci TNode<Int64T> Word64Shl(TNode<Int64T> left, TNode<Int64T> right) { 9121cb0ef41Sopenharmony_ci return Signed(Word64Shl(static_cast<TNode<Word64T>>(left), right)); 9131cb0ef41Sopenharmony_ci } 9141cb0ef41Sopenharmony_ci TNode<Uint64T> Word64Shl(TNode<Uint64T> left, TNode<Uint64T> right) { 9151cb0ef41Sopenharmony_ci return Unsigned(Word64Shl(static_cast<TNode<Word64T>>(left), right)); 9161cb0ef41Sopenharmony_ci } 9171cb0ef41Sopenharmony_ci TNode<Uint64T> Word64Shr(TNode<Uint64T> left, TNode<Uint64T> right) { 9181cb0ef41Sopenharmony_ci return Unsigned(Word64Shr(static_cast<TNode<Word64T>>(left), right)); 9191cb0ef41Sopenharmony_ci } 9201cb0ef41Sopenharmony_ci TNode<Int64T> Word64Sar(TNode<Int64T> left, TNode<Int64T> right) { 9211cb0ef41Sopenharmony_ci return Signed(Word64Sar(static_cast<TNode<Word64T>>(left), right)); 9221cb0ef41Sopenharmony_ci } 9231cb0ef41Sopenharmony_ci 9241cb0ef41Sopenharmony_ci TNode<Int64T> Word64And(TNode<Int64T> left, TNode<Int64T> right) { 9251cb0ef41Sopenharmony_ci return Signed(Word64And(static_cast<TNode<Word64T>>(left), right)); 9261cb0ef41Sopenharmony_ci } 9271cb0ef41Sopenharmony_ci TNode<Uint64T> Word64And(TNode<Uint64T> left, TNode<Uint64T> right) { 9281cb0ef41Sopenharmony_ci return Unsigned(Word64And(static_cast<TNode<Word64T>>(left), right)); 9291cb0ef41Sopenharmony_ci } 9301cb0ef41Sopenharmony_ci 9311cb0ef41Sopenharmony_ci TNode<Int64T> Word64Xor(TNode<Int64T> left, TNode<Int64T> right) { 9321cb0ef41Sopenharmony_ci return Signed(Word64Xor(static_cast<TNode<Word64T>>(left), right)); 9331cb0ef41Sopenharmony_ci } 9341cb0ef41Sopenharmony_ci TNode<Uint64T> Word64Xor(TNode<Uint64T> left, TNode<Uint64T> right) { 9351cb0ef41Sopenharmony_ci return Unsigned(Word64Xor(static_cast<TNode<Word64T>>(left), right)); 9361cb0ef41Sopenharmony_ci } 9371cb0ef41Sopenharmony_ci 9381cb0ef41Sopenharmony_ci TNode<Int64T> Word64Not(TNode<Int64T> value) { 9391cb0ef41Sopenharmony_ci return Signed(Word64Not(static_cast<TNode<Word64T>>(value))); 9401cb0ef41Sopenharmony_ci } 9411cb0ef41Sopenharmony_ci TNode<Uint64T> Word64Not(TNode<Uint64T> value) { 9421cb0ef41Sopenharmony_ci return Unsigned(Word64Not(static_cast<TNode<Word64T>>(value))); 9431cb0ef41Sopenharmony_ci } 9441cb0ef41Sopenharmony_ci 9451cb0ef41Sopenharmony_ci TNode<IntPtrT> WordAnd(TNode<IntPtrT> left, TNode<IntPtrT> right) { 9461cb0ef41Sopenharmony_ci return Signed(WordAnd(static_cast<TNode<WordT>>(left), 9471cb0ef41Sopenharmony_ci static_cast<TNode<WordT>>(right))); 9481cb0ef41Sopenharmony_ci } 9491cb0ef41Sopenharmony_ci TNode<UintPtrT> WordAnd(TNode<UintPtrT> left, TNode<UintPtrT> right) { 9501cb0ef41Sopenharmony_ci return Unsigned(WordAnd(static_cast<TNode<WordT>>(left), 9511cb0ef41Sopenharmony_ci static_cast<TNode<WordT>>(right))); 9521cb0ef41Sopenharmony_ci } 9531cb0ef41Sopenharmony_ci 9541cb0ef41Sopenharmony_ci TNode<Int32T> Word32And(TNode<Int32T> left, TNode<Int32T> right) { 9551cb0ef41Sopenharmony_ci return Signed(Word32And(static_cast<TNode<Word32T>>(left), 9561cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 9571cb0ef41Sopenharmony_ci } 9581cb0ef41Sopenharmony_ci TNode<Uint32T> Word32And(TNode<Uint32T> left, TNode<Uint32T> right) { 9591cb0ef41Sopenharmony_ci return Unsigned(Word32And(static_cast<TNode<Word32T>>(left), 9601cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 9611cb0ef41Sopenharmony_ci } 9621cb0ef41Sopenharmony_ci 9631cb0ef41Sopenharmony_ci TNode<IntPtrT> WordOr(TNode<IntPtrT> left, TNode<IntPtrT> right) { 9641cb0ef41Sopenharmony_ci return Signed(WordOr(static_cast<TNode<WordT>>(left), 9651cb0ef41Sopenharmony_ci static_cast<TNode<WordT>>(right))); 9661cb0ef41Sopenharmony_ci } 9671cb0ef41Sopenharmony_ci 9681cb0ef41Sopenharmony_ci TNode<Int32T> Word32Or(TNode<Int32T> left, TNode<Int32T> right) { 9691cb0ef41Sopenharmony_ci return Signed(Word32Or(static_cast<TNode<Word32T>>(left), 9701cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 9711cb0ef41Sopenharmony_ci } 9721cb0ef41Sopenharmony_ci TNode<Uint32T> Word32Or(TNode<Uint32T> left, TNode<Uint32T> right) { 9731cb0ef41Sopenharmony_ci return Unsigned(Word32Or(static_cast<TNode<Word32T>>(left), 9741cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 9751cb0ef41Sopenharmony_ci } 9761cb0ef41Sopenharmony_ci 9771cb0ef41Sopenharmony_ci TNode<BoolT> IntPtrEqual(TNode<WordT> left, TNode<WordT> right); 9781cb0ef41Sopenharmony_ci TNode<BoolT> WordEqual(TNode<WordT> left, TNode<WordT> right); 9791cb0ef41Sopenharmony_ci TNode<BoolT> WordNotEqual(TNode<WordT> left, TNode<WordT> right); 9801cb0ef41Sopenharmony_ci TNode<BoolT> Word32Equal(TNode<Word32T> left, TNode<Word32T> right); 9811cb0ef41Sopenharmony_ci TNode<BoolT> Word32NotEqual(TNode<Word32T> left, TNode<Word32T> right); 9821cb0ef41Sopenharmony_ci TNode<BoolT> Word64Equal(TNode<Word64T> left, TNode<Word64T> right); 9831cb0ef41Sopenharmony_ci TNode<BoolT> Word64NotEqual(TNode<Word64T> left, TNode<Word64T> right); 9841cb0ef41Sopenharmony_ci 9851cb0ef41Sopenharmony_ci TNode<IntPtrT> WordNot(TNode<IntPtrT> a) { 9861cb0ef41Sopenharmony_ci return Signed(WordNot(static_cast<TNode<WordT>>(a))); 9871cb0ef41Sopenharmony_ci } 9881cb0ef41Sopenharmony_ci TNode<BoolT> Word32Or(TNode<BoolT> left, TNode<BoolT> right) { 9891cb0ef41Sopenharmony_ci return UncheckedCast<BoolT>(Word32Or(static_cast<TNode<Word32T>>(left), 9901cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 9911cb0ef41Sopenharmony_ci } 9921cb0ef41Sopenharmony_ci TNode<BoolT> Word32And(TNode<BoolT> left, TNode<BoolT> right) { 9931cb0ef41Sopenharmony_ci return UncheckedCast<BoolT>(Word32And(static_cast<TNode<Word32T>>(left), 9941cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 9951cb0ef41Sopenharmony_ci } 9961cb0ef41Sopenharmony_ci 9971cb0ef41Sopenharmony_ci TNode<Int32T> Int32Add(TNode<Int32T> left, TNode<Int32T> right) { 9981cb0ef41Sopenharmony_ci return Signed(Int32Add(static_cast<TNode<Word32T>>(left), 9991cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 10001cb0ef41Sopenharmony_ci } 10011cb0ef41Sopenharmony_ci 10021cb0ef41Sopenharmony_ci TNode<Uint32T> Uint32Add(TNode<Uint32T> left, TNode<Uint32T> right) { 10031cb0ef41Sopenharmony_ci return Unsigned(Int32Add(static_cast<TNode<Word32T>>(left), 10041cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 10051cb0ef41Sopenharmony_ci } 10061cb0ef41Sopenharmony_ci 10071cb0ef41Sopenharmony_ci TNode<Uint32T> Uint32Sub(TNode<Uint32T> left, TNode<Uint32T> right) { 10081cb0ef41Sopenharmony_ci return Unsigned(Int32Sub(static_cast<TNode<Word32T>>(left), 10091cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 10101cb0ef41Sopenharmony_ci } 10111cb0ef41Sopenharmony_ci 10121cb0ef41Sopenharmony_ci TNode<Int32T> Int32Sub(TNode<Int32T> left, TNode<Int32T> right) { 10131cb0ef41Sopenharmony_ci return Signed(Int32Sub(static_cast<TNode<Word32T>>(left), 10141cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 10151cb0ef41Sopenharmony_ci } 10161cb0ef41Sopenharmony_ci 10171cb0ef41Sopenharmony_ci TNode<Int32T> Int32Mul(TNode<Int32T> left, TNode<Int32T> right) { 10181cb0ef41Sopenharmony_ci return Signed(Int32Mul(static_cast<TNode<Word32T>>(left), 10191cb0ef41Sopenharmony_ci static_cast<TNode<Word32T>>(right))); 10201cb0ef41Sopenharmony_ci } 10211cb0ef41Sopenharmony_ci 10221cb0ef41Sopenharmony_ci TNode<Int64T> Int64Add(TNode<Int64T> left, TNode<Int64T> right) { 10231cb0ef41Sopenharmony_ci return Signed(Int64Add(static_cast<TNode<Word64T>>(left), right)); 10241cb0ef41Sopenharmony_ci } 10251cb0ef41Sopenharmony_ci 10261cb0ef41Sopenharmony_ci TNode<Uint64T> Uint64Add(TNode<Uint64T> left, TNode<Uint64T> right) { 10271cb0ef41Sopenharmony_ci return Unsigned(Int64Add(static_cast<TNode<Word64T>>(left), right)); 10281cb0ef41Sopenharmony_ci } 10291cb0ef41Sopenharmony_ci 10301cb0ef41Sopenharmony_ci TNode<Int64T> Int64Sub(TNode<Int64T> left, TNode<Int64T> right) { 10311cb0ef41Sopenharmony_ci return Signed(Int64Sub(static_cast<TNode<Word64T>>(left), right)); 10321cb0ef41Sopenharmony_ci } 10331cb0ef41Sopenharmony_ci 10341cb0ef41Sopenharmony_ci TNode<Uint64T> Uint64Sub(TNode<Uint64T> left, TNode<Uint64T> right) { 10351cb0ef41Sopenharmony_ci return Unsigned(Int64Sub(static_cast<TNode<Word64T>>(left), right)); 10361cb0ef41Sopenharmony_ci } 10371cb0ef41Sopenharmony_ci 10381cb0ef41Sopenharmony_ci TNode<Int64T> Int64Mul(TNode<Int64T> left, TNode<Int64T> right) { 10391cb0ef41Sopenharmony_ci return Signed(Int64Mul(static_cast<TNode<Word64T>>(left), right)); 10401cb0ef41Sopenharmony_ci } 10411cb0ef41Sopenharmony_ci 10421cb0ef41Sopenharmony_ci TNode<Uint64T> Uint64Mul(TNode<Uint64T> left, TNode<Uint64T> right) { 10431cb0ef41Sopenharmony_ci return Unsigned(Int64Mul(static_cast<TNode<Word64T>>(left), right)); 10441cb0ef41Sopenharmony_ci } 10451cb0ef41Sopenharmony_ci 10461cb0ef41Sopenharmony_ci TNode<IntPtrT> IntPtrAdd(TNode<IntPtrT> left, TNode<IntPtrT> right) { 10471cb0ef41Sopenharmony_ci return Signed(IntPtrAdd(static_cast<TNode<WordT>>(left), 10481cb0ef41Sopenharmony_ci static_cast<TNode<WordT>>(right))); 10491cb0ef41Sopenharmony_ci } 10501cb0ef41Sopenharmony_ci TNode<IntPtrT> IntPtrSub(TNode<IntPtrT> left, TNode<IntPtrT> right) { 10511cb0ef41Sopenharmony_ci return Signed(IntPtrSub(static_cast<TNode<WordT>>(left), 10521cb0ef41Sopenharmony_ci static_cast<TNode<WordT>>(right))); 10531cb0ef41Sopenharmony_ci } 10541cb0ef41Sopenharmony_ci TNode<IntPtrT> IntPtrMul(TNode<IntPtrT> left, TNode<IntPtrT> right) { 10551cb0ef41Sopenharmony_ci return Signed(IntPtrMul(static_cast<TNode<WordT>>(left), 10561cb0ef41Sopenharmony_ci static_cast<TNode<WordT>>(right))); 10571cb0ef41Sopenharmony_ci } 10581cb0ef41Sopenharmony_ci TNode<UintPtrT> UintPtrAdd(TNode<UintPtrT> left, TNode<UintPtrT> right) { 10591cb0ef41Sopenharmony_ci return Unsigned(IntPtrAdd(static_cast<TNode<WordT>>(left), 10601cb0ef41Sopenharmony_ci static_cast<TNode<WordT>>(right))); 10611cb0ef41Sopenharmony_ci } 10621cb0ef41Sopenharmony_ci TNode<UintPtrT> UintPtrSub(TNode<UintPtrT> left, TNode<UintPtrT> right) { 10631cb0ef41Sopenharmony_ci return Unsigned(IntPtrSub(static_cast<TNode<WordT>>(left), 10641cb0ef41Sopenharmony_ci static_cast<TNode<WordT>>(right))); 10651cb0ef41Sopenharmony_ci } 10661cb0ef41Sopenharmony_ci TNode<RawPtrT> RawPtrAdd(TNode<RawPtrT> left, TNode<IntPtrT> right) { 10671cb0ef41Sopenharmony_ci return ReinterpretCast<RawPtrT>(IntPtrAdd(left, right)); 10681cb0ef41Sopenharmony_ci } 10691cb0ef41Sopenharmony_ci TNode<RawPtrT> RawPtrSub(TNode<RawPtrT> left, TNode<IntPtrT> right) { 10701cb0ef41Sopenharmony_ci return ReinterpretCast<RawPtrT>(IntPtrSub(left, right)); 10711cb0ef41Sopenharmony_ci } 10721cb0ef41Sopenharmony_ci TNode<IntPtrT> RawPtrSub(TNode<RawPtrT> left, TNode<RawPtrT> right) { 10731cb0ef41Sopenharmony_ci return Signed(IntPtrSub(static_cast<TNode<WordT>>(left), 10741cb0ef41Sopenharmony_ci static_cast<TNode<WordT>>(right))); 10751cb0ef41Sopenharmony_ci } 10761cb0ef41Sopenharmony_ci 10771cb0ef41Sopenharmony_ci TNode<WordT> WordShl(TNode<WordT> value, int shift); 10781cb0ef41Sopenharmony_ci TNode<WordT> WordShr(TNode<WordT> value, int shift); 10791cb0ef41Sopenharmony_ci TNode<WordT> WordSar(TNode<WordT> value, int shift); 10801cb0ef41Sopenharmony_ci TNode<IntPtrT> WordShr(TNode<IntPtrT> value, int shift) { 10811cb0ef41Sopenharmony_ci return UncheckedCast<IntPtrT>(WordShr(TNode<WordT>(value), shift)); 10821cb0ef41Sopenharmony_ci } 10831cb0ef41Sopenharmony_ci TNode<IntPtrT> WordSar(TNode<IntPtrT> value, int shift) { 10841cb0ef41Sopenharmony_ci return UncheckedCast<IntPtrT>(WordSar(TNode<WordT>(value), shift)); 10851cb0ef41Sopenharmony_ci } 10861cb0ef41Sopenharmony_ci TNode<Word32T> Word32Shr(TNode<Word32T> value, int shift); 10871cb0ef41Sopenharmony_ci TNode<Word32T> Word32Sar(TNode<Word32T> value, int shift); 10881cb0ef41Sopenharmony_ci 10891cb0ef41Sopenharmony_ci // Convenience overloads. 10901cb0ef41Sopenharmony_ci TNode<Int32T> Int32Sub(TNode<Int32T> left, int right) { 10911cb0ef41Sopenharmony_ci return Int32Sub(left, Int32Constant(right)); 10921cb0ef41Sopenharmony_ci } 10931cb0ef41Sopenharmony_ci TNode<Word32T> Word32And(TNode<Word32T> left, int right) { 10941cb0ef41Sopenharmony_ci return Word32And(left, Int32Constant(right)); 10951cb0ef41Sopenharmony_ci } 10961cb0ef41Sopenharmony_ci TNode<Int32T> Word32Shl(TNode<Int32T> left, int right) { 10971cb0ef41Sopenharmony_ci return Word32Shl(left, Int32Constant(right)); 10981cb0ef41Sopenharmony_ci } 10991cb0ef41Sopenharmony_ci TNode<BoolT> Word32Equal(TNode<Word32T> left, int right) { 11001cb0ef41Sopenharmony_ci return Word32Equal(left, Int32Constant(right)); 11011cb0ef41Sopenharmony_ci } 11021cb0ef41Sopenharmony_ci 11031cb0ef41Sopenharmony_ci// Unary 11041cb0ef41Sopenharmony_ci#define DECLARE_CODE_ASSEMBLER_UNARY_OP(name, ResType, ArgType) \ 11051cb0ef41Sopenharmony_ci TNode<ResType> name(TNode<ArgType> a); 11061cb0ef41Sopenharmony_ci CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP) 11071cb0ef41Sopenharmony_ci#undef DECLARE_CODE_ASSEMBLER_UNARY_OP 11081cb0ef41Sopenharmony_ci 11091cb0ef41Sopenharmony_ci template <class Dummy = void> 11101cb0ef41Sopenharmony_ci TNode<IntPtrT> BitcastTaggedToWord(TNode<Smi> node) { 11111cb0ef41Sopenharmony_ci static_assert(sizeof(Dummy) < 0, 11121cb0ef41Sopenharmony_ci "Should use BitcastTaggedToWordForTagAndSmiBits instead."); 11131cb0ef41Sopenharmony_ci } 11141cb0ef41Sopenharmony_ci 11151cb0ef41Sopenharmony_ci // Changes a double to an inptr_t for pointer arithmetic outside of Smi range. 11161cb0ef41Sopenharmony_ci // Assumes that the double can be exactly represented as an int. 11171cb0ef41Sopenharmony_ci TNode<IntPtrT> ChangeFloat64ToIntPtr(TNode<Float64T> value); 11181cb0ef41Sopenharmony_ci TNode<UintPtrT> ChangeFloat64ToUintPtr(TNode<Float64T> value); 11191cb0ef41Sopenharmony_ci // Same in the opposite direction. 11201cb0ef41Sopenharmony_ci TNode<Float64T> ChangeUintPtrToFloat64(TNode<UintPtrT> value); 11211cb0ef41Sopenharmony_ci 11221cb0ef41Sopenharmony_ci // Changes an intptr_t to a double, e.g. for storing an element index 11231cb0ef41Sopenharmony_ci // outside Smi range in a HeapNumber. Lossless on 32-bit, 11241cb0ef41Sopenharmony_ci // rounds on 64-bit (which doesn't affect valid element indices). 11251cb0ef41Sopenharmony_ci TNode<Float64T> RoundIntPtrToFloat64(Node* value); 11261cb0ef41Sopenharmony_ci // No-op on 32-bit, otherwise zero extend. 11271cb0ef41Sopenharmony_ci TNode<UintPtrT> ChangeUint32ToWord(TNode<Word32T> value); 11281cb0ef41Sopenharmony_ci // No-op on 32-bit, otherwise sign extend. 11291cb0ef41Sopenharmony_ci TNode<IntPtrT> ChangeInt32ToIntPtr(TNode<Word32T> value); 11301cb0ef41Sopenharmony_ci 11311cb0ef41Sopenharmony_ci // Truncates a float to a 32-bit integer. If the float is outside of 32-bit 11321cb0ef41Sopenharmony_ci // range, make sure that overflow detection is easy. In particular, return 11331cb0ef41Sopenharmony_ci // int_min instead of int_max on arm platforms by using parameter 11341cb0ef41Sopenharmony_ci // kSetOverflowToMin. 11351cb0ef41Sopenharmony_ci TNode<Int32T> TruncateFloat32ToInt32(TNode<Float32T> value); 11361cb0ef41Sopenharmony_ci 11371cb0ef41Sopenharmony_ci // Projections 11381cb0ef41Sopenharmony_ci template <int index, class T1, class T2> 11391cb0ef41Sopenharmony_ci TNode<typename std::tuple_element<index, std::tuple<T1, T2>>::type> 11401cb0ef41Sopenharmony_ci Projection(TNode<PairT<T1, T2>> value) { 11411cb0ef41Sopenharmony_ci return UncheckedCast< 11421cb0ef41Sopenharmony_ci typename std::tuple_element<index, std::tuple<T1, T2>>::type>( 11431cb0ef41Sopenharmony_ci Projection(index, value)); 11441cb0ef41Sopenharmony_ci } 11451cb0ef41Sopenharmony_ci 11461cb0ef41Sopenharmony_ci // Calls 11471cb0ef41Sopenharmony_ci template <class T = Object, class... TArgs> 11481cb0ef41Sopenharmony_ci TNode<T> CallRuntime(Runtime::FunctionId function, TNode<Object> context, 11491cb0ef41Sopenharmony_ci TArgs... args) { 11501cb0ef41Sopenharmony_ci return UncheckedCast<T>(CallRuntimeImpl( 11511cb0ef41Sopenharmony_ci function, context, {implicit_cast<TNode<Object>>(args)...})); 11521cb0ef41Sopenharmony_ci } 11531cb0ef41Sopenharmony_ci 11541cb0ef41Sopenharmony_ci template <class... TArgs> 11551cb0ef41Sopenharmony_ci void TailCallRuntime(Runtime::FunctionId function, TNode<Object> context, 11561cb0ef41Sopenharmony_ci TArgs... args) { 11571cb0ef41Sopenharmony_ci int argc = static_cast<int>(sizeof...(args)); 11581cb0ef41Sopenharmony_ci TNode<Int32T> arity = Int32Constant(argc); 11591cb0ef41Sopenharmony_ci return TailCallRuntimeImpl(function, arity, context, 11601cb0ef41Sopenharmony_ci {implicit_cast<TNode<Object>>(args)...}); 11611cb0ef41Sopenharmony_ci } 11621cb0ef41Sopenharmony_ci 11631cb0ef41Sopenharmony_ci template <class... TArgs> 11641cb0ef41Sopenharmony_ci void TailCallRuntime(Runtime::FunctionId function, TNode<Int32T> arity, 11651cb0ef41Sopenharmony_ci TNode<Object> context, TArgs... args) { 11661cb0ef41Sopenharmony_ci return TailCallRuntimeImpl(function, arity, context, 11671cb0ef41Sopenharmony_ci {implicit_cast<TNode<Object>>(args)...}); 11681cb0ef41Sopenharmony_ci } 11691cb0ef41Sopenharmony_ci 11701cb0ef41Sopenharmony_ci // 11711cb0ef41Sopenharmony_ci // If context passed to CallStub is nullptr, it won't be passed to the stub. 11721cb0ef41Sopenharmony_ci // 11731cb0ef41Sopenharmony_ci 11741cb0ef41Sopenharmony_ci template <class T = Object, class... TArgs> 11751cb0ef41Sopenharmony_ci TNode<T> CallStub(Callable const& callable, TNode<Object> context, 11761cb0ef41Sopenharmony_ci TArgs... args) { 11771cb0ef41Sopenharmony_ci TNode<CodeT> target = HeapConstant(callable.code()); 11781cb0ef41Sopenharmony_ci return CallStub<T>(callable.descriptor(), target, context, args...); 11791cb0ef41Sopenharmony_ci } 11801cb0ef41Sopenharmony_ci 11811cb0ef41Sopenharmony_ci template <class T = Object, class... TArgs> 11821cb0ef41Sopenharmony_ci TNode<T> CallStub(const CallInterfaceDescriptor& descriptor, 11831cb0ef41Sopenharmony_ci TNode<CodeT> target, TNode<Object> context, TArgs... args) { 11841cb0ef41Sopenharmony_ci return UncheckedCast<T>(CallStubR(StubCallMode::kCallCodeObject, descriptor, 11851cb0ef41Sopenharmony_ci target, context, args...)); 11861cb0ef41Sopenharmony_ci } 11871cb0ef41Sopenharmony_ci 11881cb0ef41Sopenharmony_ci template <class T = Object, class... TArgs> 11891cb0ef41Sopenharmony_ci TNode<T> CallBuiltinPointer(const CallInterfaceDescriptor& descriptor, 11901cb0ef41Sopenharmony_ci TNode<BuiltinPtr> target, TNode<Object> context, 11911cb0ef41Sopenharmony_ci TArgs... args) { 11921cb0ef41Sopenharmony_ci return UncheckedCast<T>(CallStubR(StubCallMode::kCallBuiltinPointer, 11931cb0ef41Sopenharmony_ci descriptor, target, context, args...)); 11941cb0ef41Sopenharmony_ci } 11951cb0ef41Sopenharmony_ci 11961cb0ef41Sopenharmony_ci template <class... TArgs> 11971cb0ef41Sopenharmony_ci void TailCallStub(Callable const& callable, TNode<Object> context, 11981cb0ef41Sopenharmony_ci TArgs... args) { 11991cb0ef41Sopenharmony_ci TNode<CodeT> target = HeapConstant(callable.code()); 12001cb0ef41Sopenharmony_ci TailCallStub(callable.descriptor(), target, context, args...); 12011cb0ef41Sopenharmony_ci } 12021cb0ef41Sopenharmony_ci 12031cb0ef41Sopenharmony_ci template <class... TArgs> 12041cb0ef41Sopenharmony_ci void TailCallStub(const CallInterfaceDescriptor& descriptor, 12051cb0ef41Sopenharmony_ci TNode<CodeT> target, TNode<Object> context, TArgs... args) { 12061cb0ef41Sopenharmony_ci TailCallStubImpl(descriptor, target, context, {args...}); 12071cb0ef41Sopenharmony_ci } 12081cb0ef41Sopenharmony_ci 12091cb0ef41Sopenharmony_ci template <class... TArgs> 12101cb0ef41Sopenharmony_ci void TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor, 12111cb0ef41Sopenharmony_ci TNode<RawPtrT> target, TArgs... args); 12121cb0ef41Sopenharmony_ci 12131cb0ef41Sopenharmony_ci template <class... TArgs> 12141cb0ef41Sopenharmony_ci void TailCallStubThenBytecodeDispatch( 12151cb0ef41Sopenharmony_ci const CallInterfaceDescriptor& descriptor, Node* target, Node* context, 12161cb0ef41Sopenharmony_ci TArgs... args) { 12171cb0ef41Sopenharmony_ci TailCallStubThenBytecodeDispatchImpl(descriptor, target, context, 12181cb0ef41Sopenharmony_ci {args...}); 12191cb0ef41Sopenharmony_ci } 12201cb0ef41Sopenharmony_ci 12211cb0ef41Sopenharmony_ci // Tailcalls to the given code object with JSCall linkage. The JS arguments 12221cb0ef41Sopenharmony_ci // (including receiver) are supposed to be already on the stack. 12231cb0ef41Sopenharmony_ci // This is a building block for implementing trampoline stubs that are 12241cb0ef41Sopenharmony_ci // installed instead of code objects with JSCall linkage. 12251cb0ef41Sopenharmony_ci // Note that no arguments adaption is going on here - all the JavaScript 12261cb0ef41Sopenharmony_ci // arguments are left on the stack unmodified. Therefore, this tail call can 12271cb0ef41Sopenharmony_ci // only be used after arguments adaptation has been performed already. 12281cb0ef41Sopenharmony_ci void TailCallJSCode(TNode<CodeT> code, TNode<Context> context, 12291cb0ef41Sopenharmony_ci TNode<JSFunction> function, TNode<Object> new_target, 12301cb0ef41Sopenharmony_ci TNode<Int32T> arg_count); 12311cb0ef41Sopenharmony_ci 12321cb0ef41Sopenharmony_ci template <class... TArgs> 12331cb0ef41Sopenharmony_ci TNode<Object> CallJS(Callable const& callable, Node* context, Node* function, 12341cb0ef41Sopenharmony_ci Node* receiver, TArgs... args) { 12351cb0ef41Sopenharmony_ci int argc = JSParameterCount(static_cast<int>(sizeof...(args))); 12361cb0ef41Sopenharmony_ci TNode<Int32T> arity = Int32Constant(argc); 12371cb0ef41Sopenharmony_ci TNode<CodeT> target = HeapConstant(callable.code()); 12381cb0ef41Sopenharmony_ci return CAST(CallJSStubImpl(callable.descriptor(), target, CAST(context), 12391cb0ef41Sopenharmony_ci CAST(function), {}, arity, {receiver, args...})); 12401cb0ef41Sopenharmony_ci } 12411cb0ef41Sopenharmony_ci 12421cb0ef41Sopenharmony_ci template <class... TArgs> 12431cb0ef41Sopenharmony_ci Node* ConstructJSWithTarget(Callable const& callable, Node* context, 12441cb0ef41Sopenharmony_ci Node* function, Node* new_target, TArgs... args) { 12451cb0ef41Sopenharmony_ci int argc = JSParameterCount(static_cast<int>(sizeof...(args))); 12461cb0ef41Sopenharmony_ci TNode<Int32T> arity = Int32Constant(argc); 12471cb0ef41Sopenharmony_ci TNode<Object> receiver = LoadRoot(RootIndex::kUndefinedValue); 12481cb0ef41Sopenharmony_ci TNode<CodeT> target = HeapConstant(callable.code()); 12491cb0ef41Sopenharmony_ci return CallJSStubImpl(callable.descriptor(), target, CAST(context), 12501cb0ef41Sopenharmony_ci CAST(function), CAST(new_target), arity, 12511cb0ef41Sopenharmony_ci {receiver, args...}); 12521cb0ef41Sopenharmony_ci } 12531cb0ef41Sopenharmony_ci template <class... TArgs> 12541cb0ef41Sopenharmony_ci Node* ConstructJS(Callable const& callable, Node* context, Node* new_target, 12551cb0ef41Sopenharmony_ci TArgs... args) { 12561cb0ef41Sopenharmony_ci return ConstructJSWithTarget(callable, context, new_target, new_target, 12571cb0ef41Sopenharmony_ci args...); 12581cb0ef41Sopenharmony_ci } 12591cb0ef41Sopenharmony_ci 12601cb0ef41Sopenharmony_ci Node* CallCFunctionN(Signature<MachineType>* signature, int input_count, 12611cb0ef41Sopenharmony_ci Node* const* inputs); 12621cb0ef41Sopenharmony_ci 12631cb0ef41Sopenharmony_ci // Type representing C function argument with type info. 12641cb0ef41Sopenharmony_ci using CFunctionArg = std::pair<MachineType, Node*>; 12651cb0ef41Sopenharmony_ci 12661cb0ef41Sopenharmony_ci // Call to a C function. 12671cb0ef41Sopenharmony_ci template <class... CArgs> 12681cb0ef41Sopenharmony_ci Node* CallCFunction(Node* function, base::Optional<MachineType> return_type, 12691cb0ef41Sopenharmony_ci CArgs... cargs) { 12701cb0ef41Sopenharmony_ci static_assert( 12711cb0ef41Sopenharmony_ci std::conjunction_v<std::is_convertible<CArgs, CFunctionArg>...>, 12721cb0ef41Sopenharmony_ci "invalid argument types"); 12731cb0ef41Sopenharmony_ci return CallCFunction(function, return_type, {cargs...}); 12741cb0ef41Sopenharmony_ci } 12751cb0ef41Sopenharmony_ci 12761cb0ef41Sopenharmony_ci // Call to a C function without a function discriptor on AIX. 12771cb0ef41Sopenharmony_ci template <class... CArgs> 12781cb0ef41Sopenharmony_ci Node* CallCFunctionWithoutFunctionDescriptor(Node* function, 12791cb0ef41Sopenharmony_ci MachineType return_type, 12801cb0ef41Sopenharmony_ci CArgs... cargs) { 12811cb0ef41Sopenharmony_ci static_assert( 12821cb0ef41Sopenharmony_ci std::conjunction_v<std::is_convertible<CArgs, CFunctionArg>...>, 12831cb0ef41Sopenharmony_ci "invalid argument types"); 12841cb0ef41Sopenharmony_ci return CallCFunctionWithoutFunctionDescriptor(function, return_type, 12851cb0ef41Sopenharmony_ci {cargs...}); 12861cb0ef41Sopenharmony_ci } 12871cb0ef41Sopenharmony_ci 12881cb0ef41Sopenharmony_ci // Call to a C function, while saving/restoring caller registers. 12891cb0ef41Sopenharmony_ci template <class... CArgs> 12901cb0ef41Sopenharmony_ci Node* CallCFunctionWithCallerSavedRegisters(Node* function, 12911cb0ef41Sopenharmony_ci MachineType return_type, 12921cb0ef41Sopenharmony_ci SaveFPRegsMode mode, 12931cb0ef41Sopenharmony_ci CArgs... cargs) { 12941cb0ef41Sopenharmony_ci static_assert( 12951cb0ef41Sopenharmony_ci std::conjunction_v<std::is_convertible<CArgs, CFunctionArg>...>, 12961cb0ef41Sopenharmony_ci "invalid argument types"); 12971cb0ef41Sopenharmony_ci return CallCFunctionWithCallerSavedRegisters(function, return_type, mode, 12981cb0ef41Sopenharmony_ci {cargs...}); 12991cb0ef41Sopenharmony_ci } 13001cb0ef41Sopenharmony_ci 13011cb0ef41Sopenharmony_ci // Helpers which delegate to RawMachineAssembler. 13021cb0ef41Sopenharmony_ci Factory* factory() const; 13031cb0ef41Sopenharmony_ci Isolate* isolate() const; 13041cb0ef41Sopenharmony_ci Zone* zone() const; 13051cb0ef41Sopenharmony_ci 13061cb0ef41Sopenharmony_ci CodeAssemblerState* state() { return state_; } 13071cb0ef41Sopenharmony_ci 13081cb0ef41Sopenharmony_ci void BreakOnNode(int node_id); 13091cb0ef41Sopenharmony_ci 13101cb0ef41Sopenharmony_ci bool UnalignedLoadSupported(MachineRepresentation rep) const; 13111cb0ef41Sopenharmony_ci bool UnalignedStoreSupported(MachineRepresentation rep) const; 13121cb0ef41Sopenharmony_ci 13131cb0ef41Sopenharmony_ci bool IsExceptionHandlerActive() const; 13141cb0ef41Sopenharmony_ci 13151cb0ef41Sopenharmony_ci protected: 13161cb0ef41Sopenharmony_ci void RegisterCallGenerationCallbacks( 13171cb0ef41Sopenharmony_ci const CodeAssemblerCallback& call_prologue, 13181cb0ef41Sopenharmony_ci const CodeAssemblerCallback& call_epilogue); 13191cb0ef41Sopenharmony_ci void UnregisterCallGenerationCallbacks(); 13201cb0ef41Sopenharmony_ci 13211cb0ef41Sopenharmony_ci bool Word32ShiftIsSafe() const; 13221cb0ef41Sopenharmony_ci 13231cb0ef41Sopenharmony_ci bool IsJSFunctionCall() const; 13241cb0ef41Sopenharmony_ci 13251cb0ef41Sopenharmony_ci private: 13261cb0ef41Sopenharmony_ci void HandleException(Node* result); 13271cb0ef41Sopenharmony_ci 13281cb0ef41Sopenharmony_ci Node* CallCFunction(Node* function, base::Optional<MachineType> return_type, 13291cb0ef41Sopenharmony_ci std::initializer_list<CFunctionArg> args); 13301cb0ef41Sopenharmony_ci 13311cb0ef41Sopenharmony_ci Node* CallCFunctionWithoutFunctionDescriptor( 13321cb0ef41Sopenharmony_ci Node* function, MachineType return_type, 13331cb0ef41Sopenharmony_ci std::initializer_list<CFunctionArg> args); 13341cb0ef41Sopenharmony_ci 13351cb0ef41Sopenharmony_ci Node* CallCFunctionWithCallerSavedRegisters( 13361cb0ef41Sopenharmony_ci Node* function, MachineType return_type, SaveFPRegsMode mode, 13371cb0ef41Sopenharmony_ci std::initializer_list<CFunctionArg> args); 13381cb0ef41Sopenharmony_ci 13391cb0ef41Sopenharmony_ci Node* CallRuntimeImpl(Runtime::FunctionId function, TNode<Object> context, 13401cb0ef41Sopenharmony_ci std::initializer_list<TNode<Object>> args); 13411cb0ef41Sopenharmony_ci 13421cb0ef41Sopenharmony_ci void TailCallRuntimeImpl(Runtime::FunctionId function, TNode<Int32T> arity, 13431cb0ef41Sopenharmony_ci TNode<Object> context, 13441cb0ef41Sopenharmony_ci std::initializer_list<TNode<Object>> args); 13451cb0ef41Sopenharmony_ci 13461cb0ef41Sopenharmony_ci void TailCallStubImpl(const CallInterfaceDescriptor& descriptor, 13471cb0ef41Sopenharmony_ci TNode<CodeT> target, TNode<Object> context, 13481cb0ef41Sopenharmony_ci std::initializer_list<Node*> args); 13491cb0ef41Sopenharmony_ci 13501cb0ef41Sopenharmony_ci void TailCallStubThenBytecodeDispatchImpl( 13511cb0ef41Sopenharmony_ci const CallInterfaceDescriptor& descriptor, Node* target, Node* context, 13521cb0ef41Sopenharmony_ci std::initializer_list<Node*> args); 13531cb0ef41Sopenharmony_ci 13541cb0ef41Sopenharmony_ci template <class... TArgs> 13551cb0ef41Sopenharmony_ci Node* CallStubR(StubCallMode call_mode, 13561cb0ef41Sopenharmony_ci const CallInterfaceDescriptor& descriptor, 13571cb0ef41Sopenharmony_ci TNode<Object> target, TNode<Object> context, TArgs... args) { 13581cb0ef41Sopenharmony_ci return CallStubRImpl(call_mode, descriptor, target, context, {args...}); 13591cb0ef41Sopenharmony_ci } 13601cb0ef41Sopenharmony_ci 13611cb0ef41Sopenharmony_ci Node* CallStubRImpl(StubCallMode call_mode, 13621cb0ef41Sopenharmony_ci const CallInterfaceDescriptor& descriptor, 13631cb0ef41Sopenharmony_ci TNode<Object> target, TNode<Object> context, 13641cb0ef41Sopenharmony_ci std::initializer_list<Node*> args); 13651cb0ef41Sopenharmony_ci 13661cb0ef41Sopenharmony_ci Node* CallJSStubImpl(const CallInterfaceDescriptor& descriptor, 13671cb0ef41Sopenharmony_ci TNode<Object> target, TNode<Object> context, 13681cb0ef41Sopenharmony_ci TNode<Object> function, 13691cb0ef41Sopenharmony_ci base::Optional<TNode<Object>> new_target, 13701cb0ef41Sopenharmony_ci TNode<Int32T> arity, std::initializer_list<Node*> args); 13711cb0ef41Sopenharmony_ci 13721cb0ef41Sopenharmony_ci Node* CallStubN(StubCallMode call_mode, 13731cb0ef41Sopenharmony_ci const CallInterfaceDescriptor& descriptor, int input_count, 13741cb0ef41Sopenharmony_ci Node* const* inputs); 13751cb0ef41Sopenharmony_ci 13761cb0ef41Sopenharmony_ci Node* AtomicLoad(MachineType type, AtomicMemoryOrder order, 13771cb0ef41Sopenharmony_ci TNode<RawPtrT> base, TNode<WordT> offset); 13781cb0ef41Sopenharmony_ci 13791cb0ef41Sopenharmony_ci Node* UnalignedLoad(MachineType type, TNode<RawPtrT> base, 13801cb0ef41Sopenharmony_ci TNode<WordT> offset); 13811cb0ef41Sopenharmony_ci 13821cb0ef41Sopenharmony_ci // These two don't have definitions and are here only for catching use cases 13831cb0ef41Sopenharmony_ci // where the cast is not necessary. 13841cb0ef41Sopenharmony_ci TNode<Int32T> Signed(TNode<Int32T> x); 13851cb0ef41Sopenharmony_ci TNode<Uint32T> Unsigned(TNode<Uint32T> x); 13861cb0ef41Sopenharmony_ci 13871cb0ef41Sopenharmony_ci Node* Projection(int index, Node* value); 13881cb0ef41Sopenharmony_ci 13891cb0ef41Sopenharmony_ci RawMachineAssembler* raw_assembler() const; 13901cb0ef41Sopenharmony_ci JSGraph* jsgraph() const; 13911cb0ef41Sopenharmony_ci 13921cb0ef41Sopenharmony_ci // Calls respective callback registered in the state. 13931cb0ef41Sopenharmony_ci void CallPrologue(); 13941cb0ef41Sopenharmony_ci void CallEpilogue(); 13951cb0ef41Sopenharmony_ci 13961cb0ef41Sopenharmony_ci CodeAssemblerState* state_; 13971cb0ef41Sopenharmony_ci}; 13981cb0ef41Sopenharmony_ci 13991cb0ef41Sopenharmony_ci// TODO(solanes, v8:6949): this class should be merged into 14001cb0ef41Sopenharmony_ci// TypedCodeAssemblerVariable. It's required to be separate for 14011cb0ef41Sopenharmony_ci// CodeAssemblerVariableLists. 14021cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CodeAssemblerVariable { 14031cb0ef41Sopenharmony_ci public: 14041cb0ef41Sopenharmony_ci CodeAssemblerVariable(const CodeAssemblerVariable&) = delete; 14051cb0ef41Sopenharmony_ci CodeAssemblerVariable& operator=(const CodeAssemblerVariable&) = delete; 14061cb0ef41Sopenharmony_ci 14071cb0ef41Sopenharmony_ci Node* value() const; 14081cb0ef41Sopenharmony_ci MachineRepresentation rep() const; 14091cb0ef41Sopenharmony_ci bool IsBound() const; 14101cb0ef41Sopenharmony_ci 14111cb0ef41Sopenharmony_ci protected: 14121cb0ef41Sopenharmony_ci explicit CodeAssemblerVariable(CodeAssembler* assembler, 14131cb0ef41Sopenharmony_ci MachineRepresentation rep); 14141cb0ef41Sopenharmony_ci CodeAssemblerVariable(CodeAssembler* assembler, MachineRepresentation rep, 14151cb0ef41Sopenharmony_ci Node* initial_value); 14161cb0ef41Sopenharmony_ci#if DEBUG 14171cb0ef41Sopenharmony_ci CodeAssemblerVariable(CodeAssembler* assembler, AssemblerDebugInfo debug_info, 14181cb0ef41Sopenharmony_ci MachineRepresentation rep); 14191cb0ef41Sopenharmony_ci CodeAssemblerVariable(CodeAssembler* assembler, AssemblerDebugInfo debug_info, 14201cb0ef41Sopenharmony_ci MachineRepresentation rep, Node* initial_value); 14211cb0ef41Sopenharmony_ci#endif // DEBUG 14221cb0ef41Sopenharmony_ci 14231cb0ef41Sopenharmony_ci ~CodeAssemblerVariable(); 14241cb0ef41Sopenharmony_ci void Bind(Node* value); 14251cb0ef41Sopenharmony_ci 14261cb0ef41Sopenharmony_ci private: 14271cb0ef41Sopenharmony_ci class Impl; 14281cb0ef41Sopenharmony_ci friend class CodeAssemblerLabel; 14291cb0ef41Sopenharmony_ci friend class CodeAssemblerState; 14301cb0ef41Sopenharmony_ci friend std::ostream& operator<<(std::ostream&, const Impl&); 14311cb0ef41Sopenharmony_ci friend std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable&); 14321cb0ef41Sopenharmony_ci struct ImplComparator { 14331cb0ef41Sopenharmony_ci bool operator()(const CodeAssemblerVariable::Impl* a, 14341cb0ef41Sopenharmony_ci const CodeAssemblerVariable::Impl* b) const; 14351cb0ef41Sopenharmony_ci }; 14361cb0ef41Sopenharmony_ci Impl* impl_; 14371cb0ef41Sopenharmony_ci CodeAssemblerState* state_; 14381cb0ef41Sopenharmony_ci}; 14391cb0ef41Sopenharmony_ci 14401cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, const CodeAssemblerVariable&); 14411cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, const CodeAssemblerVariable::Impl&); 14421cb0ef41Sopenharmony_ci 14431cb0ef41Sopenharmony_citemplate <class T> 14441cb0ef41Sopenharmony_ciclass TypedCodeAssemblerVariable : public CodeAssemblerVariable { 14451cb0ef41Sopenharmony_ci public: 14461cb0ef41Sopenharmony_ci TypedCodeAssemblerVariable(TNode<T> initial_value, CodeAssembler* assembler) 14471cb0ef41Sopenharmony_ci : CodeAssemblerVariable(assembler, PhiMachineRepresentationOf<T>, 14481cb0ef41Sopenharmony_ci initial_value) {} 14491cb0ef41Sopenharmony_ci explicit TypedCodeAssemblerVariable(CodeAssembler* assembler) 14501cb0ef41Sopenharmony_ci : CodeAssemblerVariable(assembler, PhiMachineRepresentationOf<T>) {} 14511cb0ef41Sopenharmony_ci#if DEBUG 14521cb0ef41Sopenharmony_ci TypedCodeAssemblerVariable(AssemblerDebugInfo debug_info, 14531cb0ef41Sopenharmony_ci CodeAssembler* assembler) 14541cb0ef41Sopenharmony_ci : CodeAssemblerVariable(assembler, debug_info, 14551cb0ef41Sopenharmony_ci PhiMachineRepresentationOf<T>) {} 14561cb0ef41Sopenharmony_ci TypedCodeAssemblerVariable(AssemblerDebugInfo debug_info, 14571cb0ef41Sopenharmony_ci TNode<T> initial_value, CodeAssembler* assembler) 14581cb0ef41Sopenharmony_ci : CodeAssemblerVariable(assembler, debug_info, 14591cb0ef41Sopenharmony_ci PhiMachineRepresentationOf<T>, initial_value) {} 14601cb0ef41Sopenharmony_ci#endif // DEBUG 14611cb0ef41Sopenharmony_ci 14621cb0ef41Sopenharmony_ci TNode<T> value() const { 14631cb0ef41Sopenharmony_ci return TNode<T>::UncheckedCast(CodeAssemblerVariable::value()); 14641cb0ef41Sopenharmony_ci } 14651cb0ef41Sopenharmony_ci 14661cb0ef41Sopenharmony_ci void operator=(TNode<T> value) { Bind(value); } 14671cb0ef41Sopenharmony_ci void operator=(const TypedCodeAssemblerVariable<T>& variable) { 14681cb0ef41Sopenharmony_ci Bind(variable.value()); 14691cb0ef41Sopenharmony_ci } 14701cb0ef41Sopenharmony_ci 14711cb0ef41Sopenharmony_ci private: 14721cb0ef41Sopenharmony_ci using CodeAssemblerVariable::Bind; 14731cb0ef41Sopenharmony_ci}; 14741cb0ef41Sopenharmony_ci 14751cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CodeAssemblerLabel { 14761cb0ef41Sopenharmony_ci public: 14771cb0ef41Sopenharmony_ci enum Type { kDeferred, kNonDeferred }; 14781cb0ef41Sopenharmony_ci 14791cb0ef41Sopenharmony_ci explicit CodeAssemblerLabel( 14801cb0ef41Sopenharmony_ci CodeAssembler* assembler, 14811cb0ef41Sopenharmony_ci CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred) 14821cb0ef41Sopenharmony_ci : CodeAssemblerLabel(assembler, 0, nullptr, type) {} 14831cb0ef41Sopenharmony_ci CodeAssemblerLabel( 14841cb0ef41Sopenharmony_ci CodeAssembler* assembler, 14851cb0ef41Sopenharmony_ci const CodeAssemblerVariableList& merged_variables, 14861cb0ef41Sopenharmony_ci CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred) 14871cb0ef41Sopenharmony_ci : CodeAssemblerLabel(assembler, merged_variables.size(), 14881cb0ef41Sopenharmony_ci &(merged_variables[0]), type) {} 14891cb0ef41Sopenharmony_ci CodeAssemblerLabel( 14901cb0ef41Sopenharmony_ci CodeAssembler* assembler, size_t count, 14911cb0ef41Sopenharmony_ci CodeAssemblerVariable* const* vars, 14921cb0ef41Sopenharmony_ci CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred); 14931cb0ef41Sopenharmony_ci CodeAssemblerLabel( 14941cb0ef41Sopenharmony_ci CodeAssembler* assembler, 14951cb0ef41Sopenharmony_ci std::initializer_list<CodeAssemblerVariable*> vars, 14961cb0ef41Sopenharmony_ci CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred) 14971cb0ef41Sopenharmony_ci : CodeAssemblerLabel(assembler, vars.size(), vars.begin(), type) {} 14981cb0ef41Sopenharmony_ci CodeAssemblerLabel( 14991cb0ef41Sopenharmony_ci CodeAssembler* assembler, CodeAssemblerVariable* merged_variable, 15001cb0ef41Sopenharmony_ci CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred) 15011cb0ef41Sopenharmony_ci : CodeAssemblerLabel(assembler, 1, &merged_variable, type) {} 15021cb0ef41Sopenharmony_ci ~CodeAssemblerLabel(); 15031cb0ef41Sopenharmony_ci 15041cb0ef41Sopenharmony_ci // Cannot be copied because the destructor explicitly call the destructor of 15051cb0ef41Sopenharmony_ci // the underlying {RawMachineLabel}, hence only one pointer can point to it. 15061cb0ef41Sopenharmony_ci CodeAssemblerLabel(const CodeAssemblerLabel&) = delete; 15071cb0ef41Sopenharmony_ci CodeAssemblerLabel& operator=(const CodeAssemblerLabel&) = delete; 15081cb0ef41Sopenharmony_ci 15091cb0ef41Sopenharmony_ci inline bool is_bound() const { return bound_; } 15101cb0ef41Sopenharmony_ci inline bool is_used() const { return merge_count_ != 0; } 15111cb0ef41Sopenharmony_ci 15121cb0ef41Sopenharmony_ci private: 15131cb0ef41Sopenharmony_ci friend class CodeAssembler; 15141cb0ef41Sopenharmony_ci 15151cb0ef41Sopenharmony_ci void Bind(); 15161cb0ef41Sopenharmony_ci#if DEBUG 15171cb0ef41Sopenharmony_ci void Bind(AssemblerDebugInfo debug_info); 15181cb0ef41Sopenharmony_ci#endif // DEBUG 15191cb0ef41Sopenharmony_ci void UpdateVariablesAfterBind(); 15201cb0ef41Sopenharmony_ci void MergeVariables(); 15211cb0ef41Sopenharmony_ci 15221cb0ef41Sopenharmony_ci bool bound_; 15231cb0ef41Sopenharmony_ci size_t merge_count_; 15241cb0ef41Sopenharmony_ci CodeAssemblerState* state_; 15251cb0ef41Sopenharmony_ci RawMachineLabel* label_; 15261cb0ef41Sopenharmony_ci // Map of variables that need to be merged to their phi nodes (or placeholders 15271cb0ef41Sopenharmony_ci // for those phis). 15281cb0ef41Sopenharmony_ci std::map<CodeAssemblerVariable::Impl*, Node*, 15291cb0ef41Sopenharmony_ci CodeAssemblerVariable::ImplComparator> 15301cb0ef41Sopenharmony_ci variable_phis_; 15311cb0ef41Sopenharmony_ci // Map of variables to the list of value nodes that have been added from each 15321cb0ef41Sopenharmony_ci // merge path in their order of merging. 15331cb0ef41Sopenharmony_ci std::map<CodeAssemblerVariable::Impl*, std::vector<Node*>, 15341cb0ef41Sopenharmony_ci CodeAssemblerVariable::ImplComparator> 15351cb0ef41Sopenharmony_ci variable_merges_; 15361cb0ef41Sopenharmony_ci}; 15371cb0ef41Sopenharmony_ci 15381cb0ef41Sopenharmony_ciclass CodeAssemblerParameterizedLabelBase { 15391cb0ef41Sopenharmony_ci public: 15401cb0ef41Sopenharmony_ci bool is_used() const { return plain_label_.is_used(); } 15411cb0ef41Sopenharmony_ci explicit CodeAssemblerParameterizedLabelBase(CodeAssembler* assembler, 15421cb0ef41Sopenharmony_ci size_t arity, 15431cb0ef41Sopenharmony_ci CodeAssemblerLabel::Type type) 15441cb0ef41Sopenharmony_ci : state_(assembler->state()), 15451cb0ef41Sopenharmony_ci phi_inputs_(arity), 15461cb0ef41Sopenharmony_ci plain_label_(assembler, type) {} 15471cb0ef41Sopenharmony_ci 15481cb0ef41Sopenharmony_ci protected: 15491cb0ef41Sopenharmony_ci CodeAssemblerLabel* plain_label() { return &plain_label_; } 15501cb0ef41Sopenharmony_ci void AddInputs(std::vector<Node*> inputs); 15511cb0ef41Sopenharmony_ci Node* CreatePhi(MachineRepresentation rep, const std::vector<Node*>& inputs); 15521cb0ef41Sopenharmony_ci const std::vector<Node*>& CreatePhis( 15531cb0ef41Sopenharmony_ci std::vector<MachineRepresentation> representations); 15541cb0ef41Sopenharmony_ci 15551cb0ef41Sopenharmony_ci private: 15561cb0ef41Sopenharmony_ci CodeAssemblerState* state_; 15571cb0ef41Sopenharmony_ci std::vector<std::vector<Node*>> phi_inputs_; 15581cb0ef41Sopenharmony_ci std::vector<Node*> phi_nodes_; 15591cb0ef41Sopenharmony_ci CodeAssemblerLabel plain_label_; 15601cb0ef41Sopenharmony_ci}; 15611cb0ef41Sopenharmony_ci 15621cb0ef41Sopenharmony_citemplate <class... Types> 15631cb0ef41Sopenharmony_ciclass CodeAssemblerParameterizedLabel 15641cb0ef41Sopenharmony_ci : public CodeAssemblerParameterizedLabelBase { 15651cb0ef41Sopenharmony_ci public: 15661cb0ef41Sopenharmony_ci static constexpr size_t kArity = sizeof...(Types); 15671cb0ef41Sopenharmony_ci explicit CodeAssemblerParameterizedLabel(CodeAssembler* assembler, 15681cb0ef41Sopenharmony_ci CodeAssemblerLabel::Type type) 15691cb0ef41Sopenharmony_ci : CodeAssemblerParameterizedLabelBase(assembler, kArity, type) {} 15701cb0ef41Sopenharmony_ci 15711cb0ef41Sopenharmony_ci private: 15721cb0ef41Sopenharmony_ci friend class CodeAssembler; 15731cb0ef41Sopenharmony_ci 15741cb0ef41Sopenharmony_ci void AddInputsVector(std::vector<Node*> inputs) { 15751cb0ef41Sopenharmony_ci CodeAssemblerParameterizedLabelBase::AddInputs(std::move(inputs)); 15761cb0ef41Sopenharmony_ci } 15771cb0ef41Sopenharmony_ci void AddInputs(TNode<Types>... inputs) { 15781cb0ef41Sopenharmony_ci CodeAssemblerParameterizedLabelBase::AddInputs( 15791cb0ef41Sopenharmony_ci std::vector<Node*>{inputs...}); 15801cb0ef41Sopenharmony_ci } 15811cb0ef41Sopenharmony_ci void CreatePhis(TNode<Types>*... results) { 15821cb0ef41Sopenharmony_ci const std::vector<Node*>& phi_nodes = 15831cb0ef41Sopenharmony_ci CodeAssemblerParameterizedLabelBase::CreatePhis( 15841cb0ef41Sopenharmony_ci {PhiMachineRepresentationOf<Types>...}); 15851cb0ef41Sopenharmony_ci auto it = phi_nodes.begin(); 15861cb0ef41Sopenharmony_ci USE(it); 15871cb0ef41Sopenharmony_ci (AssignPhi(results, *(it++)), ...); 15881cb0ef41Sopenharmony_ci } 15891cb0ef41Sopenharmony_ci template <class T> 15901cb0ef41Sopenharmony_ci static void AssignPhi(TNode<T>* result, Node* phi) { 15911cb0ef41Sopenharmony_ci if (phi != nullptr) *result = TNode<T>::UncheckedCast(phi); 15921cb0ef41Sopenharmony_ci } 15931cb0ef41Sopenharmony_ci}; 15941cb0ef41Sopenharmony_ci 15951cb0ef41Sopenharmony_ciusing CodeAssemblerExceptionHandlerLabel = 15961cb0ef41Sopenharmony_ci CodeAssemblerParameterizedLabel<Object>; 15971cb0ef41Sopenharmony_ci 15981cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CodeAssemblerState { 15991cb0ef41Sopenharmony_ci public: 16001cb0ef41Sopenharmony_ci // Create with CallStub linkage. 16011cb0ef41Sopenharmony_ci // |result_size| specifies the number of results returned by the stub. 16021cb0ef41Sopenharmony_ci // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor. 16031cb0ef41Sopenharmony_ci CodeAssemblerState(Isolate* isolate, Zone* zone, 16041cb0ef41Sopenharmony_ci const CallInterfaceDescriptor& descriptor, CodeKind kind, 16051cb0ef41Sopenharmony_ci const char* name, Builtin builtin = Builtin::kNoBuiltinId); 16061cb0ef41Sopenharmony_ci 16071cb0ef41Sopenharmony_ci // Create with JSCall linkage. 16081cb0ef41Sopenharmony_ci CodeAssemblerState(Isolate* isolate, Zone* zone, int parameter_count, 16091cb0ef41Sopenharmony_ci CodeKind kind, const char* name, 16101cb0ef41Sopenharmony_ci Builtin builtin = Builtin::kNoBuiltinId); 16111cb0ef41Sopenharmony_ci 16121cb0ef41Sopenharmony_ci ~CodeAssemblerState(); 16131cb0ef41Sopenharmony_ci 16141cb0ef41Sopenharmony_ci CodeAssemblerState(const CodeAssemblerState&) = delete; 16151cb0ef41Sopenharmony_ci CodeAssemblerState& operator=(const CodeAssemblerState&) = delete; 16161cb0ef41Sopenharmony_ci 16171cb0ef41Sopenharmony_ci const char* name() const { return name_; } 16181cb0ef41Sopenharmony_ci int parameter_count() const; 16191cb0ef41Sopenharmony_ci 16201cb0ef41Sopenharmony_ci#if DEBUG 16211cb0ef41Sopenharmony_ci void PrintCurrentBlock(std::ostream& os); 16221cb0ef41Sopenharmony_ci#endif // DEBUG 16231cb0ef41Sopenharmony_ci bool InsideBlock(); 16241cb0ef41Sopenharmony_ci void SetInitialDebugInformation(const char* msg, const char* file, int line); 16251cb0ef41Sopenharmony_ci 16261cb0ef41Sopenharmony_ci private: 16271cb0ef41Sopenharmony_ci friend class CodeAssembler; 16281cb0ef41Sopenharmony_ci friend class CodeAssemblerLabel; 16291cb0ef41Sopenharmony_ci friend class CodeAssemblerVariable; 16301cb0ef41Sopenharmony_ci friend class CodeAssemblerTester; 16311cb0ef41Sopenharmony_ci friend class CodeAssemblerParameterizedLabelBase; 16321cb0ef41Sopenharmony_ci friend class ScopedExceptionHandler; 16331cb0ef41Sopenharmony_ci 16341cb0ef41Sopenharmony_ci CodeAssemblerState(Isolate* isolate, Zone* zone, 16351cb0ef41Sopenharmony_ci CallDescriptor* call_descriptor, CodeKind kind, 16361cb0ef41Sopenharmony_ci const char* name, Builtin builtin); 16371cb0ef41Sopenharmony_ci 16381cb0ef41Sopenharmony_ci void PushExceptionHandler(CodeAssemblerExceptionHandlerLabel* label); 16391cb0ef41Sopenharmony_ci void PopExceptionHandler(); 16401cb0ef41Sopenharmony_ci 16411cb0ef41Sopenharmony_ci std::unique_ptr<RawMachineAssembler> raw_assembler_; 16421cb0ef41Sopenharmony_ci CodeKind kind_; 16431cb0ef41Sopenharmony_ci const char* name_; 16441cb0ef41Sopenharmony_ci Builtin builtin_; 16451cb0ef41Sopenharmony_ci bool code_generated_; 16461cb0ef41Sopenharmony_ci ZoneSet<CodeAssemblerVariable::Impl*, CodeAssemblerVariable::ImplComparator> 16471cb0ef41Sopenharmony_ci variables_; 16481cb0ef41Sopenharmony_ci CodeAssemblerCallback call_prologue_; 16491cb0ef41Sopenharmony_ci CodeAssemblerCallback call_epilogue_; 16501cb0ef41Sopenharmony_ci std::vector<CodeAssemblerExceptionHandlerLabel*> exception_handler_labels_; 16511cb0ef41Sopenharmony_ci using VariableId = uint32_t; 16521cb0ef41Sopenharmony_ci VariableId next_variable_id_ = 0; 16531cb0ef41Sopenharmony_ci JSGraph* jsgraph_; 16541cb0ef41Sopenharmony_ci 16551cb0ef41Sopenharmony_ci // Only used by CodeStubAssembler builtins. 16561cb0ef41Sopenharmony_ci std::vector<FileAndLine> macro_call_stack_; 16571cb0ef41Sopenharmony_ci 16581cb0ef41Sopenharmony_ci VariableId NextVariableId() { return next_variable_id_++; } 16591cb0ef41Sopenharmony_ci}; 16601cb0ef41Sopenharmony_ci 16611cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE V8_NODISCARD ScopedExceptionHandler { 16621cb0ef41Sopenharmony_ci public: 16631cb0ef41Sopenharmony_ci ScopedExceptionHandler(CodeAssembler* assembler, 16641cb0ef41Sopenharmony_ci CodeAssemblerExceptionHandlerLabel* label); 16651cb0ef41Sopenharmony_ci 16661cb0ef41Sopenharmony_ci // Use this constructor for compatability/ports of old CSA code only. New code 16671cb0ef41Sopenharmony_ci // should use the CodeAssemblerExceptionHandlerLabel version. 16681cb0ef41Sopenharmony_ci ScopedExceptionHandler(CodeAssembler* assembler, CodeAssemblerLabel* label, 16691cb0ef41Sopenharmony_ci TypedCodeAssemblerVariable<Object>* exception); 16701cb0ef41Sopenharmony_ci 16711cb0ef41Sopenharmony_ci ~ScopedExceptionHandler(); 16721cb0ef41Sopenharmony_ci 16731cb0ef41Sopenharmony_ci private: 16741cb0ef41Sopenharmony_ci bool has_handler_; 16751cb0ef41Sopenharmony_ci CodeAssembler* assembler_; 16761cb0ef41Sopenharmony_ci CodeAssemblerLabel* compatibility_label_; 16771cb0ef41Sopenharmony_ci std::unique_ptr<CodeAssemblerExceptionHandlerLabel> label_; 16781cb0ef41Sopenharmony_ci TypedCodeAssemblerVariable<Object>* exception_; 16791cb0ef41Sopenharmony_ci}; 16801cb0ef41Sopenharmony_ci 16811cb0ef41Sopenharmony_ci} // namespace compiler 16821cb0ef41Sopenharmony_ci} // namespace internal 16831cb0ef41Sopenharmony_ci} // namespace v8 16841cb0ef41Sopenharmony_ci 16851cb0ef41Sopenharmony_ci#endif // V8_COMPILER_CODE_ASSEMBLER_H_ 1686