/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>
#include <type_traits>

#include "assembler_arm_vixl.h"
#include "base/bit_utils.h"
#include "base/bit_utils_iterator.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "heap_poisoning.h"
#include "thread.h"

using namespace vixl::aarch32;  // NOLINT(build/namespaces)

namespace art HIDDEN {
namespace arm {

#ifdef ___
#error "ARM Assembler macro already defined."
#else
#define ___   vixl_masm_.
#endif

// Thread register definition.
extern const vixl32::Register tr(TR);
// Marking register definition.
extern const vixl32::Register mr(MR);

void ArmVIXLAssembler::FinalizeCode() {
  vixl_masm_.FinalizeCode();
}

size_t ArmVIXLAssembler::CodeSize() const {
  return vixl_masm_.GetSizeOfCodeGenerated();
}

const uint8_t* ArmVIXLAssembler::CodeBufferBaseAddress() const {
  return vixl_masm_.GetBuffer().GetStartAddress<const uint8_t*>();
}

void ArmVIXLAssembler::FinalizeInstructions(const MemoryRegion& region) {
  // Copy the instructions from the buffer.
  MemoryRegion from(vixl_masm_.GetBuffer()->GetStartAddress<void*>(), CodeSize());
  region.CopyFrom(0, from);
}

void ArmVIXLAssembler::PoisonHeapReference(vixl::aarch32::Register reg) {
  // reg = -reg.
  ___ Rsb(reg, reg, 0);
}

void ArmVIXLAssembler::UnpoisonHeapReference(vixl::aarch32::Register reg) {
  // reg = -reg.
  ___ Rsb(reg, reg, 0);
}

void ArmVIXLAssembler::MaybePoisonHeapReference(vixl32::Register reg) {
  if (kPoisonHeapReferences) {
    PoisonHeapReference(reg);
  }
}

void ArmVIXLAssembler::MaybeUnpoisonHeapReference(vixl32::Register reg) {
  if (kPoisonHeapReferences) {
    UnpoisonHeapReference(reg);
  }
}

void ArmVIXLAssembler::GenerateMarkingRegisterCheck(vixl32::Register temp, int code) {
  DCHECK(kReserveMarkingRegister);

  vixl32::Label mr_is_ok;

  // temp = self.tls32_.is.gc_marking
  ___ Ldr(temp, MemOperand(tr, Thread::IsGcMarkingOffset<kArmPointerSize>().Int32Value()));
  // Check that mr == self.tls32_.is.gc_marking.
  ___ Cmp(mr, temp);
  ___ B(eq, &mr_is_ok, /* is_far_target= */ false);
  ___ Bkpt(code);
  ___ Bind(&mr_is_ok);
}

void ArmVIXLAssembler::LoadImmediate(vixl32::Register rd, int32_t value) {
  // TODO(VIXL): Implement this optimization in VIXL.
  if (!ShifterOperandCanAlwaysHold(value) && ShifterOperandCanAlwaysHold(~value)) {
    ___ Mvn(rd, ~value);
  } else {
    ___ Mov(rd, value);
  }
}

bool ArmVIXLAssembler::ShifterOperandCanAlwaysHold(uint32_t immediate) {
  return vixl_masm_.IsModifiedImmediate(immediate);
}

bool ArmVIXLAssembler::ShifterOperandCanHold(Opcode opcode,
                                             uint32_t immediate,
                                             vixl::aarch32::FlagsUpdate update_flags) {
  switch (opcode) {
    case ADD:
    case SUB:
      // Less than (or equal to) 12 bits can be done if we don't need to set condition codes.
      if (IsUint<12>(immediate) && update_flags != vixl::aarch32::SetFlags) {
        return true;
      }
      return ShifterOperandCanAlwaysHold(immediate);

    case MOV:
      // TODO: Support less than or equal to 12bits.
      return ShifterOperandCanAlwaysHold(immediate);

    case MVN:
    default:
      return ShifterOperandCanAlwaysHold(immediate);
  }
}

bool ArmVIXLAssembler::CanSplitLoadStoreOffset(int32_t allowed_offset_bits,
                                               int32_t offset,
                                               /*out*/ int32_t* add_to_base,
                                               /*out*/ int32_t* offset_for_load_store) {
  int32_t other_bits = offset & ~allowed_offset_bits;
  if (ShifterOperandCanAlwaysHold(other_bits) || ShifterOperandCanAlwaysHold(-other_bits)) {
    *add_to_base = offset & ~allowed_offset_bits;
    *offset_for_load_store = offset & allowed_offset_bits;
    return true;
  }
  return false;
}

int32_t ArmVIXLAssembler::AdjustLoadStoreOffset(int32_t allowed_offset_bits,
                                                vixl32::Register temp,
                                                vixl32::Register base,
                                                int32_t offset) {
  DCHECK_NE(offset & ~allowed_offset_bits, 0);
  int32_t add_to_base, offset_for_load;
  if (CanSplitLoadStoreOffset(allowed_offset_bits, offset, &add_to_base, &offset_for_load)) {
    ___ Add(temp, base, add_to_base);
    return offset_for_load;
  } else {
    ___ Mov(temp, offset);
    ___ Add(temp, temp, base);
    return 0;
  }
}

// TODO(VIXL): Implement this in VIXL.
int32_t ArmVIXLAssembler::GetAllowedLoadOffsetBits(LoadOperandType type) {
  switch (type) {
    case kLoadSignedByte:
    case kLoadSignedHalfword:
    case kLoadUnsignedHalfword:
    case kLoadUnsignedByte:
    case kLoadWord:
      // We can encode imm12 offset.
      return 0xfff;
    case kLoadSWord:
    case kLoadDWord:
    case kLoadWordPair:
      // We can encode imm8:'00' offset.
      return 0xff << 2;
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
}

// TODO(VIXL): Implement this in VIXL.
int32_t ArmVIXLAssembler::GetAllowedStoreOffsetBits(StoreOperandType type) {
  switch (type) {
    case kStoreHalfword:
    case kStoreByte:
    case kStoreWord:
      // We can encode imm12 offset.
      return 0xfff;
    case kStoreSWord:
    case kStoreDWord:
    case kStoreWordPair:
      // We can encode imm8:'00' offset.
      return 0xff << 2;
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
}

// TODO(VIXL): Implement this in VIXL.
static bool CanHoldLoadOffsetThumb(LoadOperandType type, int offset) {
  switch (type) {
    case kLoadSignedByte:
    case kLoadSignedHalfword:
    case kLoadUnsignedHalfword:
    case kLoadUnsignedByte:
    case kLoadWord:
      return IsAbsoluteUint<12>(offset);
    case kLoadSWord:
    case kLoadDWord:
      return IsAbsoluteUint<10>(offset) && IsAligned<4>(offset);  // VFP addressing mode.
    case kLoadWordPair:
      return IsAbsoluteUint<10>(offset) && IsAligned<4>(offset);
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
}

// TODO(VIXL): Implement this in VIXL.
static bool CanHoldStoreOffsetThumb(StoreOperandType type, int offset) {
  switch (type) {
    case kStoreHalfword:
    case kStoreByte:
    case kStoreWord:
      return IsAbsoluteUint<12>(offset);
    case kStoreSWord:
    case kStoreDWord:
      return IsAbsoluteUint<10>(offset) && IsAligned<4>(offset);  // VFP addressing mode.
    case kStoreWordPair:
      return IsAbsoluteUint<10>(offset) && IsAligned<4>(offset);
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
}

// Implementation note: this method must emit at most one instruction when
// Address::CanHoldStoreOffsetThumb.
// TODO(VIXL): Implement AdjustLoadStoreOffset logic in VIXL.
void ArmVIXLAssembler::StoreToOffset(StoreOperandType type,
                                     vixl32::Register reg,
                                     vixl32::Register base,
                                     int32_t offset) {
  vixl32::Register tmp_reg;
  UseScratchRegisterScope temps(&vixl_masm_);

  if (!CanHoldStoreOffsetThumb(type, offset)) {
    CHECK_NE(base.GetCode(), kIpCode);
    if ((reg.GetCode() != kIpCode) &&
        (!vixl_masm_.GetScratchRegisterList()->IsEmpty()) &&
        ((type != kStoreWordPair) || (reg.GetCode() + 1 != kIpCode))) {
      tmp_reg = temps.Acquire();
    } else {
      // Be careful not to use ip twice (for `reg` (or `reg` + 1 in
      // the case of a word-pair store) and `base`) to build the
      // Address object used by the store instruction(s) below.
      // Instead, save R5 on the stack (or R6 if R5 is already used by
      // `base`), use it as secondary temporary register, and restore
      // it after the store instruction has been emitted.
      tmp_reg = (base.GetCode() != 5) ? r5 : r6;
      ___ Push(tmp_reg);
      if (base.GetCode() == kSpCode) {
        offset += kRegisterSize;
      }
    }
    // TODO: Implement indexed store (not available for STRD), inline AdjustLoadStoreOffset()
    // and in the "unsplittable" path get rid of the "add" by using the store indexed instead.
    offset = AdjustLoadStoreOffset(GetAllowedStoreOffsetBits(type), tmp_reg, base, offset);
    base = tmp_reg;
  }
  DCHECK(CanHoldStoreOffsetThumb(type, offset));
  switch (type) {
    case kStoreByte:
      ___ Strb(reg, MemOperand(base, offset));
      break;
    case kStoreHalfword:
      ___ Strh(reg, MemOperand(base, offset));
      break;
    case kStoreWord:
      ___ Str(reg, MemOperand(base, offset));
      break;
    case kStoreWordPair:
      ___ Strd(reg, vixl32::Register(reg.GetCode() + 1), MemOperand(base, offset));
      break;
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
  if ((tmp_reg.IsValid()) && (tmp_reg.GetCode() != kIpCode)) {
    CHECK(tmp_reg.Is(r5) || tmp_reg.Is(r6)) << tmp_reg;
    ___ Pop(tmp_reg);
  }
}

// Implementation note: this method must emit at most one instruction when
// Address::CanHoldLoadOffsetThumb.
// TODO(VIXL): Implement AdjustLoadStoreOffset logic in VIXL.
void ArmVIXLAssembler::LoadFromOffset(LoadOperandType type,
                                      vixl32::Register dest,
                                      vixl32::Register base,
                                      int32_t offset) {
  if (!CanHoldLoadOffsetThumb(type, offset)) {
    CHECK(!base.Is(ip));
    // Inlined AdjustLoadStoreOffset() allows us to pull a few more tricks.
    int32_t allowed_offset_bits = GetAllowedLoadOffsetBits(type);
    DCHECK_NE(offset & ~allowed_offset_bits, 0);
    int32_t add_to_base, offset_for_load;
    if (CanSplitLoadStoreOffset(allowed_offset_bits, offset, &add_to_base, &offset_for_load)) {
      // Use reg for the adjusted base. If it's low reg, we may end up using 16-bit load.
      AddConstant(dest, base, add_to_base);
      base = dest;
      offset = offset_for_load;
    } else {
      UseScratchRegisterScope temps(&vixl_masm_);
      vixl32::Register temp = (dest.Is(base)) ? temps.Acquire() : dest;
      LoadImmediate(temp, offset);
      // TODO: Implement indexed load (not available for LDRD) and use it here to avoid the ADD.
      // Use reg for the adjusted base. If it's low reg, we may end up using 16-bit load.
      ___ Add(dest, dest, (dest.Is(base)) ? temp : base);
      base = dest;
      offset = 0;
    }
  }

  DCHECK(CanHoldLoadOffsetThumb(type, offset));
  switch (type) {
    case kLoadSignedByte:
      ___ Ldrsb(dest, MemOperand(base, offset));
      break;
    case kLoadUnsignedByte:
      ___ Ldrb(dest, MemOperand(base, offset));
      break;
    case kLoadSignedHalfword:
      ___ Ldrsh(dest, MemOperand(base, offset));
      break;
    case kLoadUnsignedHalfword:
      ___ Ldrh(dest, MemOperand(base, offset));
      break;
    case kLoadWord:
      CHECK(!dest.IsSP());
      ___ Ldr(dest, MemOperand(base, offset));
      break;
    case kLoadWordPair:
      ___ Ldrd(dest, vixl32::Register(dest.GetCode() + 1), MemOperand(base, offset));
      break;
    default:
      LOG(FATAL) << "UNREACHABLE";
      UNREACHABLE();
  }
}

void ArmVIXLAssembler::StoreSToOffset(vixl32::SRegister source,
                                      vixl32::Register base,
                                      int32_t offset) {
  ___ Vstr(source, MemOperand(base, offset));
}

void ArmVIXLAssembler::StoreDToOffset(vixl32::DRegister source,
                                      vixl32::Register base,
                                      int32_t offset) {
  ___ Vstr(source, MemOperand(base, offset));
}

void ArmVIXLAssembler::LoadSFromOffset(vixl32::SRegister reg,
                                       vixl32::Register base,
                                       int32_t offset) {
  ___ Vldr(reg, MemOperand(base, offset));
}

void ArmVIXLAssembler::LoadDFromOffset(vixl32::DRegister reg,
                                       vixl32::Register base,
                                       int32_t offset) {
  ___ Vldr(reg, MemOperand(base, offset));
}

// Prefer Str to Add/Stm in ArmVIXLAssembler::StoreRegisterList and
// ArmVIXLAssembler::LoadRegisterList where this generates less code (size).
static constexpr int kRegListThreshold = 4;

void ArmVIXLAssembler::StoreRegisterList(RegList regs, size_t stack_offset) {
  int number_of_regs = POPCOUNT(static_cast<uint32_t>(regs));
  if (number_of_regs != 0) {
    if (number_of_regs > kRegListThreshold) {
      UseScratchRegisterScope temps(GetVIXLAssembler());
      vixl32::Register base = sp;
      if (stack_offset != 0) {
        base = temps.Acquire();
        DCHECK_EQ(regs & (1u << base.GetCode()), 0u);
        ___ Add(base, sp, Operand::From(stack_offset));
      }
      ___ Stm(base, NO_WRITE_BACK, RegisterList(regs));
    } else {
      for (uint32_t i : LowToHighBits(static_cast<uint32_t>(regs))) {
        ___ Str(vixl32::Register(i), MemOperand(sp, stack_offset));
        stack_offset += kRegSizeInBytes;
      }
    }
  }
}

void ArmVIXLAssembler::LoadRegisterList(RegList regs, size_t stack_offset) {
  int number_of_regs = POPCOUNT(static_cast<uint32_t>(regs));
  if (number_of_regs != 0) {
    if (number_of_regs > kRegListThreshold) {
      UseScratchRegisterScope temps(GetVIXLAssembler());
      vixl32::Register base = sp;
      if (stack_offset != 0) {
        base = temps.Acquire();
        ___ Add(base, sp, Operand::From(stack_offset));
      }
      ___ Ldm(base, NO_WRITE_BACK, RegisterList(regs));
    } else {
      for (uint32_t i : LowToHighBits(static_cast<uint32_t>(regs))) {
        ___ Ldr(vixl32::Register(i), MemOperand(sp, stack_offset));
        stack_offset += kRegSizeInBytes;
      }
    }
  }
}

void ArmVIXLAssembler::AddConstant(vixl32::Register rd, int32_t value) {
  AddConstant(rd, rd, value);
}

// TODO(VIXL): think about using adds which updates flags where possible.
void ArmVIXLAssembler::AddConstant(vixl32::Register rd,
                                   vixl32::Register rn,
                                   int32_t value) {
  DCHECK(vixl_masm_.OutsideITBlock());
  // TODO(VIXL): implement this optimization in VIXL.
  if (value == 0) {
    if (!rd.Is(rn)) {
      ___ Mov(rd, rn);
    }
    return;
  }
  ___ Add(rd, rn, value);
}

// Inside IT block we must use assembler, macroassembler instructions are not permitted.
void ArmVIXLAssembler::AddConstantInIt(vixl32::Register rd,
                                       vixl32::Register rn,
                                       int32_t value,
                                       vixl32::Condition cond) {
  DCHECK(vixl_masm_.InITBlock());
  if (value == 0) {
    ___ mov(cond, rd, rn);
  } else {
    ___ add(cond, rd, rn, value);
  }
}

void ArmVIXLMacroAssembler::CompareAndBranchIfZero(vixl32::Register rn,
                                                   vixl32::Label* label,
                                                   bool is_far_target) {
  if (!is_far_target && rn.IsLow() && !label->IsBound()) {
    // In T32, Cbz/Cbnz instructions have following limitations:
    // - There are only 7 bits (i:imm5:0) to encode branch target address (cannot be far target).
    // - Only low registers (i.e R0 .. R7) can be encoded.
    // - Only forward branches (unbound labels) are supported.
    Cbz(rn, label);
    return;
  }
  Cmp(rn, 0);
  B(eq, label, is_far_target);
}

void ArmVIXLMacroAssembler::CompareAndBranchIfNonZero(vixl32::Register rn,
                                                      vixl32::Label* label,
                                                      bool is_far_target) {
  if (!is_far_target && rn.IsLow() && !label->IsBound()) {
    Cbnz(rn, label);
    return;
  }
  Cmp(rn, 0);
  B(ne, label, is_far_target);
}

void ArmVIXLMacroAssembler::B(vixl32::Label* label) {
  if (!label->IsBound()) {
    // Try to use a 16-bit encoding of the B instruction.
    DCHECK(OutsideITBlock());
    BPreferNear(label);
    return;
  }
  MacroAssembler::B(label);
}

void ArmVIXLMacroAssembler::B(vixl32::Condition cond, vixl32::Label* label, bool is_far_target) {
  if (!label->IsBound() && !is_far_target) {
    // Try to use a 16-bit encoding of the B instruction.
    DCHECK(OutsideITBlock());
    BPreferNear(cond, label);
    return;
  }
  MacroAssembler::B(cond, label);
}

}  // namespace arm
}  // namespace art
