// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"

#if defined(TARGET_ARCH_ARM64)

#include "vm/compiler/assembler/assembler.h"
#include "vm/compiler/runtime_api.h"
#include "vm/constants.h"
#include "vm/object.h"
#include "vm/stack_frame.h"
#include "vm/symbols.h"

#define __ assembler->

namespace dart {

void GenerateInvokeTTSStub(compiler::Assembler* assembler) {
  __ EnterDartFrame(0);

  intptr_t sum = 0;
  for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
    if (((1 << i) & kDartAvailableCpuRegs) == 0) continue;
    if (((1 << i) & TypeTestABI::kAbiRegisters) != 0) continue;
    if (((1 << i) & TTSInternalRegs::kInternalRegisters) != 0) continue;
    __ LoadImmediate(static_cast<Register>(i), 0x10 + 2 * i);
    sum += 0x10 + 2 * i;
  }

  // Load the arguments into the right TTS calling convention registers.
  __ ldr(TypeTestABI::kInstanceReg,
         compiler::Address(
             FP, (kCallerSpSlotFromFp + 3) * compiler::target::kWordSize));
  __ ldr(TypeTestABI::kInstantiatorTypeArgumentsReg,
         compiler::Address(
             FP, (kCallerSpSlotFromFp + 2) * compiler::target::kWordSize));
  __ ldr(TypeTestABI::kFunctionTypeArgumentsReg,
         compiler::Address(
             FP, (kCallerSpSlotFromFp + 1) * compiler::target::kWordSize));
  __ ldr(TypeTestABI::kDstTypeReg,
         compiler::Address(
             FP, (kCallerSpSlotFromFp + 0) * compiler::target::kWordSize));

  const intptr_t sub_type_cache_index = __ object_pool_builder().AddObject(
      Object::null_object(), compiler::ObjectPoolBuilderEntry::kPatchable);
  const intptr_t dst_name_index = __ object_pool_builder().AddObject(
      Symbols::OptimizedOut(), compiler::ObjectPoolBuilderEntry::kPatchable);
  ASSERT((sub_type_cache_index + 1) == dst_name_index);
  ASSERT(__ constant_pool_allowed());

  // Call the TTS.
  __ ldr(R9, compiler::FieldAddress(
                 TypeTestABI::kDstTypeReg,
                 AbstractType::type_test_stub_entry_point_offset()));
  __ LoadWordFromPoolIndex(TypeTestABI::kSubtypeTestCacheReg,
                           sub_type_cache_index);
  __ blr(R9);

  // We have the guarantee that TTS preserve all registers except for one
  // scratch register atm (if the TTS handles the type test successfully).
  //
  // Let the test know whether TTS abi registers were preserved.
  compiler::Label abi_regs_modified, store_abi_regs_modified_bool;
  __ CompareWithMemoryValue(
      TypeTestABI::kInstanceReg,
      compiler::Address(
          FP, (kCallerSpSlotFromFp + 3) * compiler::target::kWordSize));
  __ BranchIf(NOT_EQUAL, &abi_regs_modified);
  __ CompareWithMemoryValue(
      TypeTestABI::kInstantiatorTypeArgumentsReg,
      compiler::Address(
          FP, (kCallerSpSlotFromFp + 2) * compiler::target::kWordSize));
  __ BranchIf(NOT_EQUAL, &abi_regs_modified);
  __ CompareWithMemoryValue(
      TypeTestABI::kFunctionTypeArgumentsReg,
      compiler::Address(
          FP, (kCallerSpSlotFromFp + 1) * compiler::target::kWordSize));
  __ BranchIf(NOT_EQUAL, &abi_regs_modified);
  __ CompareWithMemoryValue(
      TypeTestABI::kDstTypeReg,
      compiler::Address(
          FP, (kCallerSpSlotFromFp + 0) * compiler::target::kWordSize));
  __ BranchIf(NOT_EQUAL, &abi_regs_modified);
  __ ldr(R0, compiler::Address(THR, Thread::bool_false_offset()));
  __ b(&store_abi_regs_modified_bool);
  __ Bind(&abi_regs_modified);
  __ ldr(R0, compiler::Address(THR, Thread::bool_true_offset()));
  __ Bind(&store_abi_regs_modified_bool);
  __ ldr(TMP, compiler::Address(
                  FP, (kCallerSpSlotFromFp + 5) * compiler::target::kWordSize));
  __ str(R0, compiler::FieldAddress(TMP, Array::element_offset(0)));

  // Let the test know whether the non-TTS abi registers were preserved.
  compiler::Label rest_regs_modified, store_rest_regs_modified_bool;
  __ LoadImmediate(TMP, 0);
  for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
    if (((1 << i) & kDartAvailableCpuRegs) == 0) continue;
    if (((1 << i) & TypeTestABI::kAbiRegisters) != 0) continue;
    if (((1 << i) & TTSInternalRegs::kInternalRegisters) != 0) continue;
    __ add(TMP, TMP, compiler::Operand(static_cast<Register>(i)));
  }
  __ cmp(TMP, compiler::Operand(sum));
  __ BranchIf(NOT_EQUAL, &rest_regs_modified);
  __ ldr(R0, compiler::Address(THR, Thread::bool_false_offset()));
  __ b(&store_rest_regs_modified_bool);
  __ Bind(&rest_regs_modified);
  __ ldr(R0, compiler::Address(THR, Thread::bool_true_offset()));
  __ Bind(&store_rest_regs_modified_bool);
  __ ldr(TMP, compiler::Address(
                  FP, (kCallerSpSlotFromFp + 4) * compiler::target::kWordSize));
  __ str(R0, compiler::FieldAddress(TMP, Array::element_offset(0)));

  __ LoadObject(R0, Object::null_object());
  __ LeaveDartFrame();
  __ Ret();
}

}  // namespace dart

#endif  // defined(TARGET_ARCH_ARM64)
