11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/builtins/builtins-utils-gen.h"
61cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h"
71cb0ef41Sopenharmony_ci#include "src/codegen/code-stub-assembler.h"
81cb0ef41Sopenharmony_ci#include "src/objects/objects.h"
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_cinamespace v8 {
111cb0ef41Sopenharmony_cinamespace internal {
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciclass SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler {
141cb0ef41Sopenharmony_ci public:
151cb0ef41Sopenharmony_ci  explicit SharedArrayBufferBuiltinsAssembler(
161cb0ef41Sopenharmony_ci      compiler::CodeAssemblerState* state)
171cb0ef41Sopenharmony_ci      : CodeStubAssembler(state) {}
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci protected:
201cb0ef41Sopenharmony_ci  using AssemblerFunction = TNode<Word32T> (CodeAssembler::*)(
211cb0ef41Sopenharmony_ci      MachineType type, TNode<RawPtrT> base, TNode<UintPtrT> offset,
221cb0ef41Sopenharmony_ci      TNode<Word32T> value);
231cb0ef41Sopenharmony_ci  template <class Type>
241cb0ef41Sopenharmony_ci  using AssemblerFunction64 = TNode<Type> (CodeAssembler::*)(
251cb0ef41Sopenharmony_ci      TNode<RawPtrT> base, TNode<UintPtrT> offset, TNode<UintPtrT> value,
261cb0ef41Sopenharmony_ci      TNode<UintPtrT> value_high);
271cb0ef41Sopenharmony_ci  TNode<JSArrayBuffer> ValidateIntegerTypedArray(
281cb0ef41Sopenharmony_ci      TNode<Object> maybe_array, TNode<Context> context,
291cb0ef41Sopenharmony_ci      TNode<Int32T>* out_elements_kind, TNode<RawPtrT>* out_backing_store,
301cb0ef41Sopenharmony_ci      Label* detached);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  TNode<UintPtrT> ValidateAtomicAccess(TNode<JSTypedArray> array,
331cb0ef41Sopenharmony_ci                                       TNode<Object> index,
341cb0ef41Sopenharmony_ci                                       TNode<Context> context);
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci  inline void DebugCheckAtomicIndex(TNode<JSTypedArray> array,
371cb0ef41Sopenharmony_ci                                    TNode<UintPtrT> index);
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  void AtomicBinopBuiltinCommon(
401cb0ef41Sopenharmony_ci      TNode<Object> maybe_array, TNode<Object> index, TNode<Object> value,
411cb0ef41Sopenharmony_ci      TNode<Context> context, AssemblerFunction function,
421cb0ef41Sopenharmony_ci      AssemblerFunction64<AtomicInt64> function_int_64,
431cb0ef41Sopenharmony_ci      AssemblerFunction64<AtomicUint64> function_uint_64,
441cb0ef41Sopenharmony_ci      Runtime::FunctionId runtime_function, const char* method_name);
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  // Create a BigInt from the result of a 64-bit atomic operation, using
471cb0ef41Sopenharmony_ci  // projections on 32-bit platforms.
481cb0ef41Sopenharmony_ci  TNode<BigInt> BigIntFromSigned64(TNode<AtomicInt64> signed64);
491cb0ef41Sopenharmony_ci  TNode<BigInt> BigIntFromUnsigned64(TNode<AtomicUint64> unsigned64);
501cb0ef41Sopenharmony_ci};
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-validateintegertypedarray
531cb0ef41Sopenharmony_ciTNode<JSArrayBuffer>
541cb0ef41Sopenharmony_ciSharedArrayBufferBuiltinsAssembler::ValidateIntegerTypedArray(
551cb0ef41Sopenharmony_ci    TNode<Object> maybe_array, TNode<Context> context,
561cb0ef41Sopenharmony_ci    TNode<Int32T>* out_elements_kind, TNode<RawPtrT>* out_backing_store,
571cb0ef41Sopenharmony_ci    Label* detached) {
581cb0ef41Sopenharmony_ci  Label not_float_or_clamped(this), invalid(this);
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  // The logic of TypedArrayBuiltinsAssembler::ValidateTypedArrayBuffer is
611cb0ef41Sopenharmony_ci  // inlined to avoid duplicate error branches.
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  // Fail if it is not a heap object.
641cb0ef41Sopenharmony_ci  GotoIf(TaggedIsSmi(maybe_array), &invalid);
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci  // Fail if the array's instance type is not JSTypedArray.
671cb0ef41Sopenharmony_ci  TNode<Map> map = LoadMap(CAST(maybe_array));
681cb0ef41Sopenharmony_ci  GotoIfNot(IsJSTypedArrayMap(map), &invalid);
691cb0ef41Sopenharmony_ci  TNode<JSTypedArray> array = CAST(maybe_array);
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_ci  // Fail if the array's JSArrayBuffer is detached.
721cb0ef41Sopenharmony_ci  TNode<JSArrayBuffer> array_buffer = GetTypedArrayBuffer(context, array);
731cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), detached);
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci  // Fail if the array's element type is float32, float64 or clamped.
761cb0ef41Sopenharmony_ci  STATIC_ASSERT(INT8_ELEMENTS < FLOAT32_ELEMENTS);
771cb0ef41Sopenharmony_ci  STATIC_ASSERT(INT16_ELEMENTS < FLOAT32_ELEMENTS);
781cb0ef41Sopenharmony_ci  STATIC_ASSERT(INT32_ELEMENTS < FLOAT32_ELEMENTS);
791cb0ef41Sopenharmony_ci  STATIC_ASSERT(UINT8_ELEMENTS < FLOAT32_ELEMENTS);
801cb0ef41Sopenharmony_ci  STATIC_ASSERT(UINT16_ELEMENTS < FLOAT32_ELEMENTS);
811cb0ef41Sopenharmony_ci  STATIC_ASSERT(UINT32_ELEMENTS < FLOAT32_ELEMENTS);
821cb0ef41Sopenharmony_ci  TNode<Int32T> elements_kind = LoadMapElementsKind(map);
831cb0ef41Sopenharmony_ci  GotoIf(Int32LessThan(elements_kind, Int32Constant(FLOAT32_ELEMENTS)),
841cb0ef41Sopenharmony_ci         &not_float_or_clamped);
851cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGINT64_ELEMENTS > UINT8_CLAMPED_ELEMENTS);
861cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGUINT64_ELEMENTS > UINT8_CLAMPED_ELEMENTS);
871cb0ef41Sopenharmony_ci  Branch(Int32GreaterThan(elements_kind, Int32Constant(UINT8_CLAMPED_ELEMENTS)),
881cb0ef41Sopenharmony_ci         &not_float_or_clamped, &invalid);
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  BIND(&invalid);
911cb0ef41Sopenharmony_ci  {
921cb0ef41Sopenharmony_ci    ThrowTypeError(context, MessageTemplate::kNotIntegerTypedArray,
931cb0ef41Sopenharmony_ci                   maybe_array);
941cb0ef41Sopenharmony_ci  }
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  BIND(&not_float_or_clamped);
971cb0ef41Sopenharmony_ci  *out_elements_kind = elements_kind;
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  TNode<RawPtrT> backing_store = LoadJSArrayBufferBackingStorePtr(array_buffer);
1001cb0ef41Sopenharmony_ci  TNode<UintPtrT> byte_offset = LoadJSArrayBufferViewByteOffset(array);
1011cb0ef41Sopenharmony_ci  *out_backing_store = RawPtrAdd(backing_store, Signed(byte_offset));
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  return array_buffer;
1041cb0ef41Sopenharmony_ci}
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci// https://tc39.github.io/ecma262/#sec-validateatomicaccess
1071cb0ef41Sopenharmony_ci// ValidateAtomicAccess( typedArray, requestIndex )
1081cb0ef41Sopenharmony_ciTNode<UintPtrT> SharedArrayBufferBuiltinsAssembler::ValidateAtomicAccess(
1091cb0ef41Sopenharmony_ci    TNode<JSTypedArray> array, TNode<Object> index, TNode<Context> context) {
1101cb0ef41Sopenharmony_ci  Label done(this), range_error(this);
1111cb0ef41Sopenharmony_ci  // TODO(v8:11111): Support RAB / GSAB.
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  // 1. Assert: typedArray is an Object that has a [[ViewedArrayBuffer]]
1141cb0ef41Sopenharmony_ci  // internal slot.
1151cb0ef41Sopenharmony_ci  // 2. Let length be typedArray.[[ArrayLength]].
1161cb0ef41Sopenharmony_ci  TNode<UintPtrT> array_length = LoadJSTypedArrayLength(array);
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci  // 3. Let accessIndex be ? ToIndex(requestIndex).
1191cb0ef41Sopenharmony_ci  TNode<UintPtrT> index_uintptr = ToIndex(context, index, &range_error);
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci  // 4. Assert: accessIndex ≥ 0.
1221cb0ef41Sopenharmony_ci  // 5. If accessIndex ≥ length, throw a RangeError exception.
1231cb0ef41Sopenharmony_ci  Branch(UintPtrLessThan(index_uintptr, array_length), &done, &range_error);
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci  BIND(&range_error);
1261cb0ef41Sopenharmony_ci  ThrowRangeError(context, MessageTemplate::kInvalidAtomicAccessIndex);
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  // 6. Return accessIndex.
1291cb0ef41Sopenharmony_ci  BIND(&done);
1301cb0ef41Sopenharmony_ci  return index_uintptr;
1311cb0ef41Sopenharmony_ci}
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_civoid SharedArrayBufferBuiltinsAssembler::DebugCheckAtomicIndex(
1341cb0ef41Sopenharmony_ci    TNode<JSTypedArray> array, TNode<UintPtrT> index) {
1351cb0ef41Sopenharmony_ci  // In Debug mode, we re-validate the index as a sanity check because ToInteger
1361cb0ef41Sopenharmony_ci  // above calls out to JavaScript. Atomics work on ArrayBuffers, which may be
1371cb0ef41Sopenharmony_ci  // detached, and detachment state must be checked and throw before this
1381cb0ef41Sopenharmony_ci  // check. The length cannot change.
1391cb0ef41Sopenharmony_ci  //
1401cb0ef41Sopenharmony_ci  // This function must always be called after ValidateIntegerTypedArray, which
1411cb0ef41Sopenharmony_ci  // will ensure that LoadJSArrayBufferViewBuffer will not be null.
1421cb0ef41Sopenharmony_ci  CSA_DCHECK(this, Word32BinaryNot(
1431cb0ef41Sopenharmony_ci                       IsDetachedBuffer(LoadJSArrayBufferViewBuffer(array))));
1441cb0ef41Sopenharmony_ci  CSA_DCHECK(this, UintPtrLessThan(index, LoadJSTypedArrayLength(array)));
1451cb0ef41Sopenharmony_ci}
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ciTNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromSigned64(
1481cb0ef41Sopenharmony_ci    TNode<AtomicInt64> signed64) {
1491cb0ef41Sopenharmony_ci#if defined(V8_HOST_ARCH_32_BIT)
1501cb0ef41Sopenharmony_ci  TNode<IntPtrT> low = Projection<0>(signed64);
1511cb0ef41Sopenharmony_ci  TNode<IntPtrT> high = Projection<1>(signed64);
1521cb0ef41Sopenharmony_ci  return BigIntFromInt32Pair(low, high);
1531cb0ef41Sopenharmony_ci#else
1541cb0ef41Sopenharmony_ci  return BigIntFromInt64(signed64);
1551cb0ef41Sopenharmony_ci#endif
1561cb0ef41Sopenharmony_ci}
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ciTNode<BigInt> SharedArrayBufferBuiltinsAssembler::BigIntFromUnsigned64(
1591cb0ef41Sopenharmony_ci    TNode<AtomicUint64> unsigned64) {
1601cb0ef41Sopenharmony_ci#if defined(V8_HOST_ARCH_32_BIT)
1611cb0ef41Sopenharmony_ci  TNode<UintPtrT> low = Projection<0>(unsigned64);
1621cb0ef41Sopenharmony_ci  TNode<UintPtrT> high = Projection<1>(unsigned64);
1631cb0ef41Sopenharmony_ci  return BigIntFromUint32Pair(low, high);
1641cb0ef41Sopenharmony_ci#else
1651cb0ef41Sopenharmony_ci  return BigIntFromUint64(unsigned64);
1661cb0ef41Sopenharmony_ci#endif
1671cb0ef41Sopenharmony_ci}
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomicload
1701cb0ef41Sopenharmony_ciTF_BUILTIN(AtomicsLoad, SharedArrayBufferBuiltinsAssembler) {
1711cb0ef41Sopenharmony_ci  auto maybe_array_or_shared_struct =
1721cb0ef41Sopenharmony_ci      Parameter<Object>(Descriptor::kArrayOrSharedStruct);
1731cb0ef41Sopenharmony_ci  auto index_or_field_name = Parameter<Object>(Descriptor::kIndexOrFieldName);
1741cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci  Label shared_struct(this);
1771cb0ef41Sopenharmony_ci  GotoIf(IsJSSharedStruct(maybe_array_or_shared_struct), &shared_struct);
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_ci  // 1. Let buffer be ? ValidateIntegerTypedArray(typedArray).
1801cb0ef41Sopenharmony_ci  Label detached(this);
1811cb0ef41Sopenharmony_ci  TNode<Int32T> elements_kind;
1821cb0ef41Sopenharmony_ci  TNode<RawPtrT> backing_store;
1831cb0ef41Sopenharmony_ci  TNode<JSArrayBuffer> array_buffer =
1841cb0ef41Sopenharmony_ci      ValidateIntegerTypedArray(maybe_array_or_shared_struct, context,
1851cb0ef41Sopenharmony_ci                                &elements_kind, &backing_store, &detached);
1861cb0ef41Sopenharmony_ci  TNode<JSTypedArray> array = CAST(maybe_array_or_shared_struct);
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci  // 2. Let i be ? ValidateAtomicAccess(typedArray, index).
1891cb0ef41Sopenharmony_ci  TNode<UintPtrT> index_word =
1901cb0ef41Sopenharmony_ci      ValidateAtomicAccess(array, index_or_field_name, context);
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_ci  // 3. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
1931cb0ef41Sopenharmony_ci  // 4. NOTE: The above check is not redundant with the check in
1941cb0ef41Sopenharmony_ci  // ValidateIntegerTypedArray because the call to ValidateAtomicAccess on the
1951cb0ef41Sopenharmony_ci  // preceding line can have arbitrary side effects, which could cause the
1961cb0ef41Sopenharmony_ci  // buffer to become detached.
1971cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), &detached);
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci  // Steps 5-10.
2001cb0ef41Sopenharmony_ci  //
2011cb0ef41Sopenharmony_ci  // (Not copied from ecma262 due to the axiomatic nature of the memory model.)
2021cb0ef41Sopenharmony_ci  Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this),
2031cb0ef41Sopenharmony_ci      i64(this), u64(this), other(this);
2041cb0ef41Sopenharmony_ci  int32_t case_values[] = {
2051cb0ef41Sopenharmony_ci      INT8_ELEMENTS,  UINT8_ELEMENTS,  INT16_ELEMENTS,    UINT16_ELEMENTS,
2061cb0ef41Sopenharmony_ci      INT32_ELEMENTS, UINT32_ELEMENTS, BIGINT64_ELEMENTS, BIGUINT64_ELEMENTS,
2071cb0ef41Sopenharmony_ci  };
2081cb0ef41Sopenharmony_ci  Label* case_labels[] = {&i8, &u8, &i16, &u16, &i32, &u32, &i64, &u64};
2091cb0ef41Sopenharmony_ci  Switch(elements_kind, &other, case_values, case_labels,
2101cb0ef41Sopenharmony_ci         arraysize(case_labels));
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci  BIND(&i8);
2131cb0ef41Sopenharmony_ci  Return(SmiFromInt32(AtomicLoad<Int8T>(AtomicMemoryOrder::kSeqCst,
2141cb0ef41Sopenharmony_ci                                        backing_store, index_word)));
2151cb0ef41Sopenharmony_ci
2161cb0ef41Sopenharmony_ci  BIND(&u8);
2171cb0ef41Sopenharmony_ci  Return(SmiFromInt32(AtomicLoad<Uint8T>(AtomicMemoryOrder::kSeqCst,
2181cb0ef41Sopenharmony_ci                                         backing_store, index_word)));
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci  BIND(&i16);
2211cb0ef41Sopenharmony_ci  Return(SmiFromInt32(AtomicLoad<Int16T>(
2221cb0ef41Sopenharmony_ci      AtomicMemoryOrder::kSeqCst, backing_store, WordShl(index_word, 1))));
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ci  BIND(&u16);
2251cb0ef41Sopenharmony_ci  Return(SmiFromInt32(AtomicLoad<Uint16T>(
2261cb0ef41Sopenharmony_ci      AtomicMemoryOrder::kSeqCst, backing_store, WordShl(index_word, 1))));
2271cb0ef41Sopenharmony_ci
2281cb0ef41Sopenharmony_ci  BIND(&i32);
2291cb0ef41Sopenharmony_ci  Return(ChangeInt32ToTagged(AtomicLoad<Int32T>(
2301cb0ef41Sopenharmony_ci      AtomicMemoryOrder::kSeqCst, backing_store, WordShl(index_word, 2))));
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci  BIND(&u32);
2331cb0ef41Sopenharmony_ci  Return(ChangeUint32ToTagged(AtomicLoad<Uint32T>(
2341cb0ef41Sopenharmony_ci      AtomicMemoryOrder::kSeqCst, backing_store, WordShl(index_word, 2))));
2351cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_MIPS && !_MIPS_ARCH_MIPS32R6
2361cb0ef41Sopenharmony_ci  BIND(&i64);
2371cb0ef41Sopenharmony_ci  Goto(&u64);
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ci  BIND(&u64);
2401cb0ef41Sopenharmony_ci  {
2411cb0ef41Sopenharmony_ci    TNode<Number> index_number = ChangeUintPtrToTagged(index_word);
2421cb0ef41Sopenharmony_ci    Return(CallRuntime(Runtime::kAtomicsLoad64, context, array, index_number));
2431cb0ef41Sopenharmony_ci  }
2441cb0ef41Sopenharmony_ci#else
2451cb0ef41Sopenharmony_ci  BIND(&i64);
2461cb0ef41Sopenharmony_ci  Return(BigIntFromSigned64(AtomicLoad64<AtomicInt64>(
2471cb0ef41Sopenharmony_ci      AtomicMemoryOrder::kSeqCst, backing_store, WordShl(index_word, 3))));
2481cb0ef41Sopenharmony_ci
2491cb0ef41Sopenharmony_ci  BIND(&u64);
2501cb0ef41Sopenharmony_ci  Return(BigIntFromUnsigned64(AtomicLoad64<AtomicUint64>(
2511cb0ef41Sopenharmony_ci      AtomicMemoryOrder::kSeqCst, backing_store, WordShl(index_word, 3))));
2521cb0ef41Sopenharmony_ci#endif
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_ci  // This shouldn't happen, we've already validated the type.
2551cb0ef41Sopenharmony_ci  BIND(&other);
2561cb0ef41Sopenharmony_ci  Unreachable();
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci  BIND(&detached);
2591cb0ef41Sopenharmony_ci  {
2601cb0ef41Sopenharmony_ci    ThrowTypeError(context, MessageTemplate::kDetachedOperation,
2611cb0ef41Sopenharmony_ci                   "Atomics.load");
2621cb0ef41Sopenharmony_ci  }
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ci  BIND(&shared_struct);
2651cb0ef41Sopenharmony_ci  {
2661cb0ef41Sopenharmony_ci    Return(CallRuntime(Runtime::kAtomicsLoadSharedStructField, context,
2671cb0ef41Sopenharmony_ci                       maybe_array_or_shared_struct, index_or_field_name));
2681cb0ef41Sopenharmony_ci  }
2691cb0ef41Sopenharmony_ci}
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomics.store
2721cb0ef41Sopenharmony_ciTF_BUILTIN(AtomicsStore, SharedArrayBufferBuiltinsAssembler) {
2731cb0ef41Sopenharmony_ci  auto maybe_array_or_shared_struct =
2741cb0ef41Sopenharmony_ci      Parameter<Object>(Descriptor::kArrayOrSharedStruct);
2751cb0ef41Sopenharmony_ci  auto index_or_field_name = Parameter<Object>(Descriptor::kIndexOrFieldName);
2761cb0ef41Sopenharmony_ci  auto value = Parameter<Object>(Descriptor::kValue);
2771cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  Label shared_struct(this);
2801cb0ef41Sopenharmony_ci  GotoIf(IsJSSharedStruct(maybe_array_or_shared_struct), &shared_struct);
2811cb0ef41Sopenharmony_ci
2821cb0ef41Sopenharmony_ci  // 1. Let buffer be ? ValidateIntegerTypedArray(typedArray).
2831cb0ef41Sopenharmony_ci  Label detached(this);
2841cb0ef41Sopenharmony_ci  TNode<Int32T> elements_kind;
2851cb0ef41Sopenharmony_ci  TNode<RawPtrT> backing_store;
2861cb0ef41Sopenharmony_ci  TNode<JSArrayBuffer> array_buffer =
2871cb0ef41Sopenharmony_ci      ValidateIntegerTypedArray(maybe_array_or_shared_struct, context,
2881cb0ef41Sopenharmony_ci                                &elements_kind, &backing_store, &detached);
2891cb0ef41Sopenharmony_ci  TNode<JSTypedArray> array = CAST(maybe_array_or_shared_struct);
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci  // 2. Let i be ? ValidateAtomicAccess(typedArray, index).
2921cb0ef41Sopenharmony_ci  TNode<UintPtrT> index_word =
2931cb0ef41Sopenharmony_ci      ValidateAtomicAccess(array, index_or_field_name, context);
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci  Label u8(this), u16(this), u32(this), u64(this), other(this);
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci  // 3. Let arrayTypeName be typedArray.[[TypedArrayName]].
2981cb0ef41Sopenharmony_ci  // 4. If arrayTypeName is "BigUint64Array" or "BigInt64Array",
2991cb0ef41Sopenharmony_ci  //    let v be ? ToBigInt(value).
3001cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGINT64_ELEMENTS > INT32_ELEMENTS);
3011cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGUINT64_ELEMENTS > INT32_ELEMENTS);
3021cb0ef41Sopenharmony_ci  GotoIf(Int32GreaterThan(elements_kind, Int32Constant(INT32_ELEMENTS)), &u64);
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  // 5. Otherwise, let v be ? ToInteger(value).
3051cb0ef41Sopenharmony_ci  TNode<Number> value_integer = ToInteger_Inline(context, value);
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci  // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
3081cb0ef41Sopenharmony_ci  // 7. NOTE: The above check is not redundant with the check in
3091cb0ef41Sopenharmony_ci  // ValidateIntegerTypedArray because the call to ToBigInt or ToInteger on the
3101cb0ef41Sopenharmony_ci  // preceding lines can have arbitrary side effects, which could cause the
3111cb0ef41Sopenharmony_ci  // buffer to become detached.
3121cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), &detached);
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci  TNode<Word32T> value_word32 = TruncateTaggedToWord32(context, value_integer);
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci  DebugCheckAtomicIndex(array, index_word);
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci  // Steps 8-13.
3191cb0ef41Sopenharmony_ci  //
3201cb0ef41Sopenharmony_ci  // (Not copied from ecma262 due to the axiomatic nature of the memory model.)
3211cb0ef41Sopenharmony_ci  int32_t case_values[] = {
3221cb0ef41Sopenharmony_ci      INT8_ELEMENTS,   UINT8_ELEMENTS, INT16_ELEMENTS,
3231cb0ef41Sopenharmony_ci      UINT16_ELEMENTS, INT32_ELEMENTS, UINT32_ELEMENTS,
3241cb0ef41Sopenharmony_ci  };
3251cb0ef41Sopenharmony_ci  Label* case_labels[] = {&u8, &u8, &u16, &u16, &u32, &u32};
3261cb0ef41Sopenharmony_ci  Switch(elements_kind, &other, case_values, case_labels,
3271cb0ef41Sopenharmony_ci         arraysize(case_labels));
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_ci  BIND(&u8);
3301cb0ef41Sopenharmony_ci  AtomicStore(MachineRepresentation::kWord8, AtomicMemoryOrder::kSeqCst,
3311cb0ef41Sopenharmony_ci              backing_store, index_word, value_word32);
3321cb0ef41Sopenharmony_ci  Return(value_integer);
3331cb0ef41Sopenharmony_ci
3341cb0ef41Sopenharmony_ci  BIND(&u16);
3351cb0ef41Sopenharmony_ci  AtomicStore(MachineRepresentation::kWord16, AtomicMemoryOrder::kSeqCst,
3361cb0ef41Sopenharmony_ci              backing_store, WordShl(index_word, 1), value_word32);
3371cb0ef41Sopenharmony_ci  Return(value_integer);
3381cb0ef41Sopenharmony_ci
3391cb0ef41Sopenharmony_ci  BIND(&u32);
3401cb0ef41Sopenharmony_ci  AtomicStore(MachineRepresentation::kWord32, AtomicMemoryOrder::kSeqCst,
3411cb0ef41Sopenharmony_ci              backing_store, WordShl(index_word, 2), value_word32);
3421cb0ef41Sopenharmony_ci  Return(value_integer);
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ci  BIND(&u64);
3451cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_MIPS && !_MIPS_ARCH_MIPS32R6
3461cb0ef41Sopenharmony_ci  TNode<Number> index_number = ChangeUintPtrToTagged(index_word);
3471cb0ef41Sopenharmony_ci  Return(CallRuntime(Runtime::kAtomicsStore64, context, array, index_number,
3481cb0ef41Sopenharmony_ci                     value));
3491cb0ef41Sopenharmony_ci#else
3501cb0ef41Sopenharmony_ci  // 4. If arrayTypeName is "BigUint64Array" or "BigInt64Array",
3511cb0ef41Sopenharmony_ci  //    let v be ? ToBigInt(value).
3521cb0ef41Sopenharmony_ci  TNode<BigInt> value_bigint = ToBigInt(context, value);
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_ci  // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
3551cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), &detached);
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ci  DebugCheckAtomicIndex(array, index_word);
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_low);
3601cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_high);
3611cb0ef41Sopenharmony_ci  BigIntToRawBytes(value_bigint, &var_low, &var_high);
3621cb0ef41Sopenharmony_ci  TNode<UintPtrT> high = Is64() ? TNode<UintPtrT>() : var_high.value();
3631cb0ef41Sopenharmony_ci  AtomicStore64(AtomicMemoryOrder::kSeqCst, backing_store,
3641cb0ef41Sopenharmony_ci                WordShl(index_word, 3), var_low.value(), high);
3651cb0ef41Sopenharmony_ci  Return(value_bigint);
3661cb0ef41Sopenharmony_ci#endif
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci  // This shouldn't happen, we've already validated the type.
3691cb0ef41Sopenharmony_ci  BIND(&other);
3701cb0ef41Sopenharmony_ci  Unreachable();
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci  BIND(&detached);
3731cb0ef41Sopenharmony_ci  {
3741cb0ef41Sopenharmony_ci    ThrowTypeError(context, MessageTemplate::kDetachedOperation,
3751cb0ef41Sopenharmony_ci                   "Atomics.store");
3761cb0ef41Sopenharmony_ci  }
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci  BIND(&shared_struct);
3791cb0ef41Sopenharmony_ci  {
3801cb0ef41Sopenharmony_ci    Return(CallRuntime(Runtime::kAtomicsStoreSharedStructField, context,
3811cb0ef41Sopenharmony_ci                       maybe_array_or_shared_struct, index_or_field_name,
3821cb0ef41Sopenharmony_ci                       value));
3831cb0ef41Sopenharmony_ci  }
3841cb0ef41Sopenharmony_ci}
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomics.exchange
3871cb0ef41Sopenharmony_ciTF_BUILTIN(AtomicsExchange, SharedArrayBufferBuiltinsAssembler) {
3881cb0ef41Sopenharmony_ci  auto maybe_array_or_shared_struct =
3891cb0ef41Sopenharmony_ci      Parameter<Object>(Descriptor::kArrayOrSharedStruct);
3901cb0ef41Sopenharmony_ci  auto index_or_field_name = Parameter<Object>(Descriptor::kIndexOrFieldName);
3911cb0ef41Sopenharmony_ci  auto value = Parameter<Object>(Descriptor::kValue);
3921cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ci  Label shared_struct(this);
3951cb0ef41Sopenharmony_ci  GotoIf(IsJSSharedStruct(maybe_array_or_shared_struct), &shared_struct);
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_ci  // Inlines AtomicReadModifyWrite
3981cb0ef41Sopenharmony_ci  // https://tc39.es/ecma262/#sec-atomicreadmodifywrite
3991cb0ef41Sopenharmony_ci
4001cb0ef41Sopenharmony_ci  // 1. Let buffer be ? ValidateIntegerTypedArray(typedArray).
4011cb0ef41Sopenharmony_ci  Label detached(this);
4021cb0ef41Sopenharmony_ci  TNode<Int32T> elements_kind;
4031cb0ef41Sopenharmony_ci  TNode<RawPtrT> backing_store;
4041cb0ef41Sopenharmony_ci  TNode<JSArrayBuffer> array_buffer =
4051cb0ef41Sopenharmony_ci      ValidateIntegerTypedArray(maybe_array_or_shared_struct, context,
4061cb0ef41Sopenharmony_ci                                &elements_kind, &backing_store, &detached);
4071cb0ef41Sopenharmony_ci  TNode<JSTypedArray> array = CAST(maybe_array_or_shared_struct);
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci  // 2. Let i be ? ValidateAtomicAccess(typedArray, index).
4101cb0ef41Sopenharmony_ci  TNode<UintPtrT> index_word =
4111cb0ef41Sopenharmony_ci      ValidateAtomicAccess(array, index_or_field_name, context);
4121cb0ef41Sopenharmony_ci
4131cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_RISCV64
4141cb0ef41Sopenharmony_ci  USE(array_buffer);
4151cb0ef41Sopenharmony_ci  TNode<Number> index_number = ChangeUintPtrToTagged(index_word);
4161cb0ef41Sopenharmony_ci  Return(CallRuntime(Runtime::kAtomicsExchange, context, array, index_number,
4171cb0ef41Sopenharmony_ci                     value));
4181cb0ef41Sopenharmony_ci#else
4191cb0ef41Sopenharmony_ci
4201cb0ef41Sopenharmony_ci  Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this),
4211cb0ef41Sopenharmony_ci      i64(this), u64(this), big(this), other(this);
4221cb0ef41Sopenharmony_ci
4231cb0ef41Sopenharmony_ci  // 3. Let arrayTypeName be typedArray.[[TypedArrayName]].
4241cb0ef41Sopenharmony_ci  // 4. If typedArray.[[ContentType]] is BigInt, let v be ? ToBigInt(value).
4251cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGINT64_ELEMENTS > INT32_ELEMENTS);
4261cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGUINT64_ELEMENTS > INT32_ELEMENTS);
4271cb0ef41Sopenharmony_ci  GotoIf(Int32GreaterThan(elements_kind, Int32Constant(INT32_ELEMENTS)), &big);
4281cb0ef41Sopenharmony_ci
4291cb0ef41Sopenharmony_ci  // 5. Otherwise, let v be ? ToInteger(value).
4301cb0ef41Sopenharmony_ci  TNode<Number> value_integer = ToInteger_Inline(context, value);
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_ci  // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
4331cb0ef41Sopenharmony_ci  // 7. NOTE: The above check is not redundant with the check in
4341cb0ef41Sopenharmony_ci  // ValidateIntegerTypedArray because the call to ToBigInt or ToInteger on the
4351cb0ef41Sopenharmony_ci  // preceding lines can have arbitrary side effects, which could cause the
4361cb0ef41Sopenharmony_ci  // buffer to become detached.
4371cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), &detached);
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_ci  DebugCheckAtomicIndex(array, index_word);
4401cb0ef41Sopenharmony_ci
4411cb0ef41Sopenharmony_ci  TNode<Word32T> value_word32 = TruncateTaggedToWord32(context, value_integer);
4421cb0ef41Sopenharmony_ci
4431cb0ef41Sopenharmony_ci  // Steps 8-12.
4441cb0ef41Sopenharmony_ci  //
4451cb0ef41Sopenharmony_ci  // (Not copied from ecma262 due to the axiomatic nature of the memory model.)
4461cb0ef41Sopenharmony_ci  int32_t case_values[] = {
4471cb0ef41Sopenharmony_ci      INT8_ELEMENTS,   UINT8_ELEMENTS, INT16_ELEMENTS,
4481cb0ef41Sopenharmony_ci      UINT16_ELEMENTS, INT32_ELEMENTS, UINT32_ELEMENTS,
4491cb0ef41Sopenharmony_ci  };
4501cb0ef41Sopenharmony_ci  Label* case_labels[] = {
4511cb0ef41Sopenharmony_ci      &i8, &u8, &i16, &u16, &i32, &u32,
4521cb0ef41Sopenharmony_ci  };
4531cb0ef41Sopenharmony_ci  Switch(elements_kind, &other, case_values, case_labels,
4541cb0ef41Sopenharmony_ci         arraysize(case_labels));
4551cb0ef41Sopenharmony_ci
4561cb0ef41Sopenharmony_ci  BIND(&i8);
4571cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed(AtomicExchange(MachineType::Int8(), backing_store,
4581cb0ef41Sopenharmony_ci                                            index_word, value_word32))));
4591cb0ef41Sopenharmony_ci
4601cb0ef41Sopenharmony_ci  BIND(&u8);
4611cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed(AtomicExchange(MachineType::Uint8(), backing_store,
4621cb0ef41Sopenharmony_ci                                            index_word, value_word32))));
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_ci  BIND(&i16);
4651cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed(
4661cb0ef41Sopenharmony_ci      AtomicExchange(MachineType::Int16(), backing_store,
4671cb0ef41Sopenharmony_ci                     WordShl(index_word, UintPtrConstant(1)), value_word32))));
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci  BIND(&u16);
4701cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed(
4711cb0ef41Sopenharmony_ci      AtomicExchange(MachineType::Uint16(), backing_store,
4721cb0ef41Sopenharmony_ci                     WordShl(index_word, UintPtrConstant(1)), value_word32))));
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ci  BIND(&i32);
4751cb0ef41Sopenharmony_ci  Return(ChangeInt32ToTagged(Signed(
4761cb0ef41Sopenharmony_ci      AtomicExchange(MachineType::Int32(), backing_store,
4771cb0ef41Sopenharmony_ci                     WordShl(index_word, UintPtrConstant(2)), value_word32))));
4781cb0ef41Sopenharmony_ci
4791cb0ef41Sopenharmony_ci  BIND(&u32);
4801cb0ef41Sopenharmony_ci  Return(ChangeUint32ToTagged(Unsigned(
4811cb0ef41Sopenharmony_ci      AtomicExchange(MachineType::Uint32(), backing_store,
4821cb0ef41Sopenharmony_ci                     WordShl(index_word, UintPtrConstant(2)), value_word32))));
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ci  BIND(&big);
4851cb0ef41Sopenharmony_ci  // 4. If typedArray.[[ContentType]] is BigInt, let v be ? ToBigInt(value).
4861cb0ef41Sopenharmony_ci  TNode<BigInt> value_bigint = ToBigInt(context, value);
4871cb0ef41Sopenharmony_ci
4881cb0ef41Sopenharmony_ci  // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
4891cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), &detached);
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ci  DebugCheckAtomicIndex(array, index_word);
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_low);
4941cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_high);
4951cb0ef41Sopenharmony_ci  BigIntToRawBytes(value_bigint, &var_low, &var_high);
4961cb0ef41Sopenharmony_ci  TNode<UintPtrT> high = Is64() ? TNode<UintPtrT>() : var_high.value();
4971cb0ef41Sopenharmony_ci  GotoIf(Word32Equal(elements_kind, Int32Constant(BIGINT64_ELEMENTS)), &i64);
4981cb0ef41Sopenharmony_ci  GotoIf(Word32Equal(elements_kind, Int32Constant(BIGUINT64_ELEMENTS)), &u64);
4991cb0ef41Sopenharmony_ci  Unreachable();
5001cb0ef41Sopenharmony_ci
5011cb0ef41Sopenharmony_ci  BIND(&i64);
5021cb0ef41Sopenharmony_ci  Return(BigIntFromSigned64(AtomicExchange64<AtomicInt64>(
5031cb0ef41Sopenharmony_ci      backing_store, WordShl(index_word, UintPtrConstant(3)), var_low.value(),
5041cb0ef41Sopenharmony_ci      high)));
5051cb0ef41Sopenharmony_ci
5061cb0ef41Sopenharmony_ci  BIND(&u64);
5071cb0ef41Sopenharmony_ci  Return(BigIntFromUnsigned64(AtomicExchange64<AtomicUint64>(
5081cb0ef41Sopenharmony_ci      backing_store, WordShl(index_word, UintPtrConstant(3)), var_low.value(),
5091cb0ef41Sopenharmony_ci      high)));
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_ci  // This shouldn't happen, we've already validated the type.
5121cb0ef41Sopenharmony_ci  BIND(&other);
5131cb0ef41Sopenharmony_ci  Unreachable();
5141cb0ef41Sopenharmony_ci#endif  // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 ||
5151cb0ef41Sopenharmony_ci        // V8_TARGET_ARCH_RISCV64
5161cb0ef41Sopenharmony_ci
5171cb0ef41Sopenharmony_ci  BIND(&detached);
5181cb0ef41Sopenharmony_ci  {
5191cb0ef41Sopenharmony_ci    ThrowTypeError(context, MessageTemplate::kDetachedOperation,
5201cb0ef41Sopenharmony_ci                   "Atomics.exchange");
5211cb0ef41Sopenharmony_ci  }
5221cb0ef41Sopenharmony_ci
5231cb0ef41Sopenharmony_ci  BIND(&shared_struct);
5241cb0ef41Sopenharmony_ci  {
5251cb0ef41Sopenharmony_ci    Return(CallRuntime(Runtime::kAtomicsExchangeSharedStructField, context,
5261cb0ef41Sopenharmony_ci                       maybe_array_or_shared_struct, index_or_field_name,
5271cb0ef41Sopenharmony_ci                       value));
5281cb0ef41Sopenharmony_ci  }
5291cb0ef41Sopenharmony_ci}
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomics.compareexchange
5321cb0ef41Sopenharmony_ciTF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) {
5331cb0ef41Sopenharmony_ci  auto maybe_array = Parameter<Object>(Descriptor::kArray);
5341cb0ef41Sopenharmony_ci  auto index = Parameter<Object>(Descriptor::kIndex);
5351cb0ef41Sopenharmony_ci  auto old_value = Parameter<Object>(Descriptor::kOldValue);
5361cb0ef41Sopenharmony_ci  auto new_value = Parameter<Object>(Descriptor::kNewValue);
5371cb0ef41Sopenharmony_ci  auto context = Parameter<Context>(Descriptor::kContext);
5381cb0ef41Sopenharmony_ci
5391cb0ef41Sopenharmony_ci  // 1. Let buffer be ? ValidateIntegerTypedArray(typedArray).
5401cb0ef41Sopenharmony_ci  Label detached(this);
5411cb0ef41Sopenharmony_ci  TNode<Int32T> elements_kind;
5421cb0ef41Sopenharmony_ci  TNode<RawPtrT> backing_store;
5431cb0ef41Sopenharmony_ci  TNode<JSArrayBuffer> array_buffer = ValidateIntegerTypedArray(
5441cb0ef41Sopenharmony_ci      maybe_array, context, &elements_kind, &backing_store, &detached);
5451cb0ef41Sopenharmony_ci  TNode<JSTypedArray> array = CAST(maybe_array);
5461cb0ef41Sopenharmony_ci
5471cb0ef41Sopenharmony_ci  // 2. Let i be ? ValidateAtomicAccess(typedArray, index).
5481cb0ef41Sopenharmony_ci  TNode<UintPtrT> index_word = ValidateAtomicAccess(array, index, context);
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 || \
5511cb0ef41Sopenharmony_ci    V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X ||    \
5521cb0ef41Sopenharmony_ci    V8_TARGET_ARCH_RISCV64
5531cb0ef41Sopenharmony_ci  USE(array_buffer);
5541cb0ef41Sopenharmony_ci  TNode<Number> index_number = ChangeUintPtrToTagged(index_word);
5551cb0ef41Sopenharmony_ci  Return(CallRuntime(Runtime::kAtomicsCompareExchange, context, array,
5561cb0ef41Sopenharmony_ci                     index_number, old_value, new_value));
5571cb0ef41Sopenharmony_ci#else
5581cb0ef41Sopenharmony_ci  Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this),
5591cb0ef41Sopenharmony_ci      i64(this), u64(this), big(this), other(this);
5601cb0ef41Sopenharmony_ci
5611cb0ef41Sopenharmony_ci  // 3. Let arrayTypeName be typedArray.[[TypedArrayName]].
5621cb0ef41Sopenharmony_ci  // 4. If typedArray.[[ContentType]] is BigInt, then
5631cb0ef41Sopenharmony_ci  //   a. Let expected be ? ToBigInt(expectedValue).
5641cb0ef41Sopenharmony_ci  //   b. Let replacement be ? ToBigInt(replacementValue).
5651cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGINT64_ELEMENTS > INT32_ELEMENTS);
5661cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGUINT64_ELEMENTS > INT32_ELEMENTS);
5671cb0ef41Sopenharmony_ci  GotoIf(Int32GreaterThan(elements_kind, Int32Constant(INT32_ELEMENTS)), &big);
5681cb0ef41Sopenharmony_ci
5691cb0ef41Sopenharmony_ci  // 5. Else,
5701cb0ef41Sopenharmony_ci  //   a. Let expected be ? ToInteger(expectedValue).
5711cb0ef41Sopenharmony_ci  //   b. Let replacement be ? ToInteger(replacementValue).
5721cb0ef41Sopenharmony_ci  TNode<Number> old_value_integer = ToInteger_Inline(context, old_value);
5731cb0ef41Sopenharmony_ci  TNode<Number> new_value_integer = ToInteger_Inline(context, new_value);
5741cb0ef41Sopenharmony_ci
5751cb0ef41Sopenharmony_ci  // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
5761cb0ef41Sopenharmony_ci  // 7. NOTE: The above check is not redundant with the check in
5771cb0ef41Sopenharmony_ci  // ValidateIntegerTypedArray because the call to ToBigInt or ToInteger on the
5781cb0ef41Sopenharmony_ci  // preceding lines can have arbitrary side effects, which could cause the
5791cb0ef41Sopenharmony_ci  // buffer to become detached.
5801cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), &detached);
5811cb0ef41Sopenharmony_ci
5821cb0ef41Sopenharmony_ci  DebugCheckAtomicIndex(array, index_word);
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ci  TNode<Word32T> old_value_word32 =
5851cb0ef41Sopenharmony_ci      TruncateTaggedToWord32(context, old_value_integer);
5861cb0ef41Sopenharmony_ci  TNode<Word32T> new_value_word32 =
5871cb0ef41Sopenharmony_ci      TruncateTaggedToWord32(context, new_value_integer);
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ci  // Steps 8-14.
5901cb0ef41Sopenharmony_ci  //
5911cb0ef41Sopenharmony_ci  // (Not copied from ecma262 due to the axiomatic nature of the memory model.)
5921cb0ef41Sopenharmony_ci  int32_t case_values[] = {
5931cb0ef41Sopenharmony_ci      INT8_ELEMENTS,   UINT8_ELEMENTS, INT16_ELEMENTS,
5941cb0ef41Sopenharmony_ci      UINT16_ELEMENTS, INT32_ELEMENTS, UINT32_ELEMENTS,
5951cb0ef41Sopenharmony_ci  };
5961cb0ef41Sopenharmony_ci  Label* case_labels[] = {
5971cb0ef41Sopenharmony_ci      &i8, &u8, &i16, &u16, &i32, &u32,
5981cb0ef41Sopenharmony_ci  };
5991cb0ef41Sopenharmony_ci  Switch(elements_kind, &other, case_values, case_labels,
6001cb0ef41Sopenharmony_ci         arraysize(case_labels));
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ci  BIND(&i8);
6031cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed(
6041cb0ef41Sopenharmony_ci      AtomicCompareExchange(MachineType::Int8(), backing_store, index_word,
6051cb0ef41Sopenharmony_ci                            old_value_word32, new_value_word32))));
6061cb0ef41Sopenharmony_ci
6071cb0ef41Sopenharmony_ci  BIND(&u8);
6081cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed(
6091cb0ef41Sopenharmony_ci      AtomicCompareExchange(MachineType::Uint8(), backing_store, index_word,
6101cb0ef41Sopenharmony_ci                            old_value_word32, new_value_word32))));
6111cb0ef41Sopenharmony_ci
6121cb0ef41Sopenharmony_ci  BIND(&i16);
6131cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed(AtomicCompareExchange(
6141cb0ef41Sopenharmony_ci      MachineType::Int16(), backing_store, WordShl(index_word, 1),
6151cb0ef41Sopenharmony_ci      old_value_word32, new_value_word32))));
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_ci  BIND(&u16);
6181cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed(AtomicCompareExchange(
6191cb0ef41Sopenharmony_ci      MachineType::Uint16(), backing_store, WordShl(index_word, 1),
6201cb0ef41Sopenharmony_ci      old_value_word32, new_value_word32))));
6211cb0ef41Sopenharmony_ci
6221cb0ef41Sopenharmony_ci  BIND(&i32);
6231cb0ef41Sopenharmony_ci  Return(ChangeInt32ToTagged(Signed(AtomicCompareExchange(
6241cb0ef41Sopenharmony_ci      MachineType::Int32(), backing_store, WordShl(index_word, 2),
6251cb0ef41Sopenharmony_ci      old_value_word32, new_value_word32))));
6261cb0ef41Sopenharmony_ci
6271cb0ef41Sopenharmony_ci  BIND(&u32);
6281cb0ef41Sopenharmony_ci  Return(ChangeUint32ToTagged(Unsigned(AtomicCompareExchange(
6291cb0ef41Sopenharmony_ci      MachineType::Uint32(), backing_store, WordShl(index_word, 2),
6301cb0ef41Sopenharmony_ci      old_value_word32, new_value_word32))));
6311cb0ef41Sopenharmony_ci
6321cb0ef41Sopenharmony_ci  BIND(&big);
6331cb0ef41Sopenharmony_ci  // 4. If typedArray.[[ContentType]] is BigInt, then
6341cb0ef41Sopenharmony_ci  //   a. Let expected be ? ToBigInt(expectedValue).
6351cb0ef41Sopenharmony_ci  //   b. Let replacement be ? ToBigInt(replacementValue).
6361cb0ef41Sopenharmony_ci  TNode<BigInt> old_value_bigint = ToBigInt(context, old_value);
6371cb0ef41Sopenharmony_ci  TNode<BigInt> new_value_bigint = ToBigInt(context, new_value);
6381cb0ef41Sopenharmony_ci
6391cb0ef41Sopenharmony_ci  // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
6401cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), &detached);
6411cb0ef41Sopenharmony_ci
6421cb0ef41Sopenharmony_ci  DebugCheckAtomicIndex(array, index_word);
6431cb0ef41Sopenharmony_ci
6441cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_old_low);
6451cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_old_high);
6461cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_new_low);
6471cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_new_high);
6481cb0ef41Sopenharmony_ci  BigIntToRawBytes(old_value_bigint, &var_old_low, &var_old_high);
6491cb0ef41Sopenharmony_ci  BigIntToRawBytes(new_value_bigint, &var_new_low, &var_new_high);
6501cb0ef41Sopenharmony_ci  TNode<UintPtrT> old_high = Is64() ? TNode<UintPtrT>() : var_old_high.value();
6511cb0ef41Sopenharmony_ci  TNode<UintPtrT> new_high = Is64() ? TNode<UintPtrT>() : var_new_high.value();
6521cb0ef41Sopenharmony_ci  GotoIf(Word32Equal(elements_kind, Int32Constant(BIGINT64_ELEMENTS)), &i64);
6531cb0ef41Sopenharmony_ci  GotoIf(Word32Equal(elements_kind, Int32Constant(BIGUINT64_ELEMENTS)), &u64);
6541cb0ef41Sopenharmony_ci  Unreachable();
6551cb0ef41Sopenharmony_ci
6561cb0ef41Sopenharmony_ci  BIND(&i64);
6571cb0ef41Sopenharmony_ci  // This uses Uint64() intentionally: AtomicCompareExchange is not implemented
6581cb0ef41Sopenharmony_ci  // for Int64(), which is fine because the machine instruction only cares
6591cb0ef41Sopenharmony_ci  // about words.
6601cb0ef41Sopenharmony_ci  Return(BigIntFromSigned64(AtomicCompareExchange64<AtomicInt64>(
6611cb0ef41Sopenharmony_ci      backing_store, WordShl(index_word, 3), var_old_low.value(),
6621cb0ef41Sopenharmony_ci      var_new_low.value(), old_high, new_high)));
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci  BIND(&u64);
6651cb0ef41Sopenharmony_ci  Return(BigIntFromUnsigned64(AtomicCompareExchange64<AtomicUint64>(
6661cb0ef41Sopenharmony_ci      backing_store, WordShl(index_word, 3), var_old_low.value(),
6671cb0ef41Sopenharmony_ci      var_new_low.value(), old_high, new_high)));
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci  // This shouldn't happen, we've already validated the type.
6701cb0ef41Sopenharmony_ci  BIND(&other);
6711cb0ef41Sopenharmony_ci  Unreachable();
6721cb0ef41Sopenharmony_ci#endif  // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64
6731cb0ef41Sopenharmony_ci        // || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X
6741cb0ef41Sopenharmony_ci        // || V8_TARGET_ARCH_RISCV64
6751cb0ef41Sopenharmony_ci
6761cb0ef41Sopenharmony_ci  BIND(&detached);
6771cb0ef41Sopenharmony_ci  {
6781cb0ef41Sopenharmony_ci    ThrowTypeError(context, MessageTemplate::kDetachedOperation,
6791cb0ef41Sopenharmony_ci                   "Atomics.store");
6801cb0ef41Sopenharmony_ci  }
6811cb0ef41Sopenharmony_ci}
6821cb0ef41Sopenharmony_ci
6831cb0ef41Sopenharmony_ci#define BINOP_BUILTIN(op, method_name)                                        \
6841cb0ef41Sopenharmony_ci  TF_BUILTIN(Atomics##op, SharedArrayBufferBuiltinsAssembler) {               \
6851cb0ef41Sopenharmony_ci    auto array = Parameter<Object>(Descriptor::kArray);                       \
6861cb0ef41Sopenharmony_ci    auto index = Parameter<Object>(Descriptor::kIndex);                       \
6871cb0ef41Sopenharmony_ci    auto value = Parameter<Object>(Descriptor::kValue);                       \
6881cb0ef41Sopenharmony_ci    auto context = Parameter<Context>(Descriptor::kContext);                  \
6891cb0ef41Sopenharmony_ci    AtomicBinopBuiltinCommon(array, index, value, context,                    \
6901cb0ef41Sopenharmony_ci                             &CodeAssembler::Atomic##op,                      \
6911cb0ef41Sopenharmony_ci                             &CodeAssembler::Atomic##op##64 < AtomicInt64 >,  \
6921cb0ef41Sopenharmony_ci                             &CodeAssembler::Atomic##op##64 < AtomicUint64 >, \
6931cb0ef41Sopenharmony_ci                             Runtime::kAtomics##op, method_name);             \
6941cb0ef41Sopenharmony_ci  }
6951cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomics.add
6961cb0ef41Sopenharmony_ciBINOP_BUILTIN(Add, "Atomics.add")
6971cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomics.sub
6981cb0ef41Sopenharmony_ciBINOP_BUILTIN(Sub, "Atomics.sub")
6991cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomics.and
7001cb0ef41Sopenharmony_ciBINOP_BUILTIN(And, "Atomics.and")
7011cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomics.or
7021cb0ef41Sopenharmony_ciBINOP_BUILTIN(Or, "Atomics.or")
7031cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomics.xor
7041cb0ef41Sopenharmony_ciBINOP_BUILTIN(Xor, "Atomics.xor")
7051cb0ef41Sopenharmony_ci#undef BINOP_BUILTIN
7061cb0ef41Sopenharmony_ci
7071cb0ef41Sopenharmony_ci// https://tc39.es/ecma262/#sec-atomicreadmodifywrite
7081cb0ef41Sopenharmony_civoid SharedArrayBufferBuiltinsAssembler::AtomicBinopBuiltinCommon(
7091cb0ef41Sopenharmony_ci    TNode<Object> maybe_array, TNode<Object> index, TNode<Object> value,
7101cb0ef41Sopenharmony_ci    TNode<Context> context, AssemblerFunction function,
7111cb0ef41Sopenharmony_ci    AssemblerFunction64<AtomicInt64> function_int_64,
7121cb0ef41Sopenharmony_ci    AssemblerFunction64<AtomicUint64> function_uint_64,
7131cb0ef41Sopenharmony_ci    Runtime::FunctionId runtime_function, const char* method_name) {
7141cb0ef41Sopenharmony_ci  // 1. Let buffer be ? ValidateIntegerTypedArray(typedArray).
7151cb0ef41Sopenharmony_ci  Label detached(this);
7161cb0ef41Sopenharmony_ci  TNode<Int32T> elements_kind;
7171cb0ef41Sopenharmony_ci  TNode<RawPtrT> backing_store;
7181cb0ef41Sopenharmony_ci  TNode<JSArrayBuffer> array_buffer = ValidateIntegerTypedArray(
7191cb0ef41Sopenharmony_ci      maybe_array, context, &elements_kind, &backing_store, &detached);
7201cb0ef41Sopenharmony_ci  TNode<JSTypedArray> array = CAST(maybe_array);
7211cb0ef41Sopenharmony_ci
7221cb0ef41Sopenharmony_ci  // 2. Let i be ? ValidateAtomicAccess(typedArray, index).
7231cb0ef41Sopenharmony_ci  TNode<UintPtrT> index_word = ValidateAtomicAccess(array, index, context);
7241cb0ef41Sopenharmony_ci
7251cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 || \
7261cb0ef41Sopenharmony_ci    V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X ||    \
7271cb0ef41Sopenharmony_ci    V8_TARGET_ARCH_RISCV64
7281cb0ef41Sopenharmony_ci  USE(array_buffer);
7291cb0ef41Sopenharmony_ci  TNode<Number> index_number = ChangeUintPtrToTagged(index_word);
7301cb0ef41Sopenharmony_ci  Return(CallRuntime(runtime_function, context, array, index_number, value));
7311cb0ef41Sopenharmony_ci#else
7321cb0ef41Sopenharmony_ci  Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this),
7331cb0ef41Sopenharmony_ci      i64(this), u64(this), big(this), other(this);
7341cb0ef41Sopenharmony_ci
7351cb0ef41Sopenharmony_ci  // 3. Let arrayTypeName be typedArray.[[TypedArrayName]].
7361cb0ef41Sopenharmony_ci  // 4. If typedArray.[[ContentType]] is BigInt, let v be ? ToBigInt(value).
7371cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGINT64_ELEMENTS > INT32_ELEMENTS);
7381cb0ef41Sopenharmony_ci  STATIC_ASSERT(BIGUINT64_ELEMENTS > INT32_ELEMENTS);
7391cb0ef41Sopenharmony_ci  GotoIf(Int32GreaterThan(elements_kind, Int32Constant(INT32_ELEMENTS)), &big);
7401cb0ef41Sopenharmony_ci
7411cb0ef41Sopenharmony_ci  // 5. Otherwise, let v be ? ToInteger(value).
7421cb0ef41Sopenharmony_ci  TNode<Number> value_integer = ToInteger_Inline(context, value);
7431cb0ef41Sopenharmony_ci
7441cb0ef41Sopenharmony_ci  // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
7451cb0ef41Sopenharmony_ci  // 7. NOTE: The above check is not redundant with the check in
7461cb0ef41Sopenharmony_ci  // ValidateIntegerTypedArray because the call to ToBigInt or ToInteger on the
7471cb0ef41Sopenharmony_ci  // preceding lines can have arbitrary side effects, which could cause the
7481cb0ef41Sopenharmony_ci  // buffer to become detached.
7491cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), &detached);
7501cb0ef41Sopenharmony_ci
7511cb0ef41Sopenharmony_ci  DebugCheckAtomicIndex(array, index_word);
7521cb0ef41Sopenharmony_ci
7531cb0ef41Sopenharmony_ci  TNode<Word32T> value_word32 = TruncateTaggedToWord32(context, value_integer);
7541cb0ef41Sopenharmony_ci
7551cb0ef41Sopenharmony_ci  // Steps 8-12.
7561cb0ef41Sopenharmony_ci  //
7571cb0ef41Sopenharmony_ci  // (Not copied from ecma262 due to the axiomatic nature of the memory model.)
7581cb0ef41Sopenharmony_ci  int32_t case_values[] = {
7591cb0ef41Sopenharmony_ci      INT8_ELEMENTS,   UINT8_ELEMENTS, INT16_ELEMENTS,
7601cb0ef41Sopenharmony_ci      UINT16_ELEMENTS, INT32_ELEMENTS, UINT32_ELEMENTS,
7611cb0ef41Sopenharmony_ci  };
7621cb0ef41Sopenharmony_ci  Label* case_labels[] = {
7631cb0ef41Sopenharmony_ci      &i8, &u8, &i16, &u16, &i32, &u32,
7641cb0ef41Sopenharmony_ci  };
7651cb0ef41Sopenharmony_ci  Switch(elements_kind, &other, case_values, case_labels,
7661cb0ef41Sopenharmony_ci         arraysize(case_labels));
7671cb0ef41Sopenharmony_ci
7681cb0ef41Sopenharmony_ci  BIND(&i8);
7691cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed((this->*function)(
7701cb0ef41Sopenharmony_ci      MachineType::Int8(), backing_store, index_word, value_word32))));
7711cb0ef41Sopenharmony_ci  BIND(&u8);
7721cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed((this->*function)(
7731cb0ef41Sopenharmony_ci      MachineType::Uint8(), backing_store, index_word, value_word32))));
7741cb0ef41Sopenharmony_ci  BIND(&i16);
7751cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed((this->*function)(
7761cb0ef41Sopenharmony_ci      MachineType::Int16(), backing_store,
7771cb0ef41Sopenharmony_ci      WordShl(index_word, UintPtrConstant(1)), value_word32))));
7781cb0ef41Sopenharmony_ci  BIND(&u16);
7791cb0ef41Sopenharmony_ci  Return(SmiFromInt32(Signed((this->*function)(
7801cb0ef41Sopenharmony_ci      MachineType::Uint16(), backing_store,
7811cb0ef41Sopenharmony_ci      WordShl(index_word, UintPtrConstant(1)), value_word32))));
7821cb0ef41Sopenharmony_ci  BIND(&i32);
7831cb0ef41Sopenharmony_ci  Return(ChangeInt32ToTagged(Signed((this->*function)(
7841cb0ef41Sopenharmony_ci      MachineType::Int32(), backing_store,
7851cb0ef41Sopenharmony_ci      WordShl(index_word, UintPtrConstant(2)), value_word32))));
7861cb0ef41Sopenharmony_ci  BIND(&u32);
7871cb0ef41Sopenharmony_ci  Return(ChangeUint32ToTagged(Unsigned((this->*function)(
7881cb0ef41Sopenharmony_ci      MachineType::Uint32(), backing_store,
7891cb0ef41Sopenharmony_ci      WordShl(index_word, UintPtrConstant(2)), value_word32))));
7901cb0ef41Sopenharmony_ci  BIND(&big);
7911cb0ef41Sopenharmony_ci  // 4. If typedArray.[[ContentType]] is BigInt, let v be ? ToBigInt(value).
7921cb0ef41Sopenharmony_ci  TNode<BigInt> value_bigint = ToBigInt(context, value);
7931cb0ef41Sopenharmony_ci
7941cb0ef41Sopenharmony_ci  // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
7951cb0ef41Sopenharmony_ci  GotoIf(IsDetachedBuffer(array_buffer), &detached);
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ci  DebugCheckAtomicIndex(array, index_word);
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_low);
8001cb0ef41Sopenharmony_ci  TVARIABLE(UintPtrT, var_high);
8011cb0ef41Sopenharmony_ci  BigIntToRawBytes(value_bigint, &var_low, &var_high);
8021cb0ef41Sopenharmony_ci  TNode<UintPtrT> high = Is64() ? TNode<UintPtrT>() : var_high.value();
8031cb0ef41Sopenharmony_ci  GotoIf(Word32Equal(elements_kind, Int32Constant(BIGINT64_ELEMENTS)), &i64);
8041cb0ef41Sopenharmony_ci  GotoIf(Word32Equal(elements_kind, Int32Constant(BIGUINT64_ELEMENTS)), &u64);
8051cb0ef41Sopenharmony_ci  Unreachable();
8061cb0ef41Sopenharmony_ci
8071cb0ef41Sopenharmony_ci  BIND(&i64);
8081cb0ef41Sopenharmony_ci  Return(BigIntFromSigned64((this->*function_int_64)(
8091cb0ef41Sopenharmony_ci      backing_store, WordShl(index_word, UintPtrConstant(3)), var_low.value(),
8101cb0ef41Sopenharmony_ci      high)));
8111cb0ef41Sopenharmony_ci  BIND(&u64);
8121cb0ef41Sopenharmony_ci  Return(BigIntFromUnsigned64((this->*function_uint_64)(
8131cb0ef41Sopenharmony_ci      backing_store, WordShl(index_word, UintPtrConstant(3)), var_low.value(),
8141cb0ef41Sopenharmony_ci      high)));
8151cb0ef41Sopenharmony_ci  // // This shouldn't happen, we've already validated the type.
8161cb0ef41Sopenharmony_ci  BIND(&other);
8171cb0ef41Sopenharmony_ci  Unreachable();
8181cb0ef41Sopenharmony_ci#endif  // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64
8191cb0ef41Sopenharmony_ci        // || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X
8201cb0ef41Sopenharmony_ci        // || V8_TARGET_ARCH_RISCV64
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci  BIND(&detached);
8231cb0ef41Sopenharmony_ci  ThrowTypeError(context, MessageTemplate::kDetachedOperation, method_name);
8241cb0ef41Sopenharmony_ci}
8251cb0ef41Sopenharmony_ci
8261cb0ef41Sopenharmony_ci}  // namespace internal
8271cb0ef41Sopenharmony_ci}  // namespace v8
828