// Copyright 2011 Google Inc. All Rights Reserved.

#ifndef ART_SRC_ASSEMBLER_ARM_H_
#define ART_SRC_ASSEMBLER_ARM_H_

#include "constants.h"
#include "managed_register.h"
#include "logging.h"
#include "offsets.h"
#include "utils.h"

namespace art {

// Encodes Addressing Mode 1 - Data-processing operands defined in Section 5.1.
class ShifterOperand {
 public:
  // Data-processing operands - Uninitialized
  ShifterOperand() {
    type_ = -1;
  }

  // Data-processing operands - Immediate
  explicit ShifterOperand(uint32_t immediate) {
    CHECK(immediate < (1 << kImmed8Bits));
    type_ = 1;
    encoding_ = immediate;
  }

  // Data-processing operands - Rotated immediate
  ShifterOperand(uint32_t rotate, uint32_t immed8) {
    CHECK((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits)));
    type_ = 1;
    encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift);
  }

  // Data-processing operands - Register
  explicit ShifterOperand(Register rm) {
    type_ = 0;
    encoding_ = static_cast<uint32_t>(rm);
  }

  // Data-processing operands - Logical shift/rotate by immediate
  ShifterOperand(Register rm, Shift shift, uint32_t shift_imm) {
    CHECK(shift_imm < (1 << kShiftImmBits));
    type_ = 0;
    encoding_ = shift_imm << kShiftImmShift |
                static_cast<uint32_t>(shift) << kShiftShift |
                static_cast<uint32_t>(rm);
  }

  // Data-processing operands - Logical shift/rotate by register
  ShifterOperand(Register rm, Shift shift, Register rs) {
    type_ = 0;
    encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift |
                static_cast<uint32_t>(shift) << kShiftShift | (1 << 4) |
                static_cast<uint32_t>(rm);
  }

  static bool CanHold(uint32_t immediate, ShifterOperand* shifter_op) {
    // Avoid the more expensive test for frequent small immediate values.
    if (immediate < (1 << kImmed8Bits)) {
      shifter_op->type_ = 1;
      shifter_op->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift);
      return true;
    }
    // Note that immediate must be unsigned for the test to work correctly.
    for (int rot = 0; rot < 16; rot++) {
      uint32_t imm8 = (immediate << 2*rot) | (immediate >> (32 - 2*rot));
      if (imm8 < (1 << kImmed8Bits)) {
        shifter_op->type_ = 1;
        shifter_op->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift);
        return true;
      }
    }
    return false;
  }

 private:
  bool is_valid() const { return (type_ == 0) || (type_ == 1); }

  uint32_t type() const {
    CHECK(is_valid());
    return type_;
  }

  uint32_t encoding() const {
    CHECK(is_valid());
    return encoding_;
  }

  uint32_t type_;  // Encodes the type field (bits 27-25) in the instruction.
  uint32_t encoding_;

  friend class Assembler;
#ifdef SOURCE_ASSEMBLER_SUPPORT
  friend class BinaryAssembler;
#endif
};


enum LoadOperandType {
  kLoadSignedByte,
  kLoadUnsignedByte,
  kLoadSignedHalfword,
  kLoadUnsignedHalfword,
  kLoadWord,
  kLoadWordPair,
  kLoadSWord,
  kLoadDWord
};


enum StoreOperandType {
  kStoreByte,
  kStoreHalfword,
  kStoreWord,
  kStoreWordPair,
  kStoreSWord,
  kStoreDWord
};


// Load/store multiple addressing mode.
enum BlockAddressMode {
  // bit encoding P U W
  DA           = (0|0|0) << 21,  // decrement after
  IA           = (0|4|0) << 21,  // increment after
  DB           = (8|0|0) << 21,  // decrement before
  IB           = (8|4|0) << 21,  // increment before
  DA_W         = (0|0|1) << 21,  // decrement after with writeback to base
  IA_W         = (0|4|1) << 21,  // increment after with writeback to base
  DB_W         = (8|0|1) << 21,  // decrement before with writeback to base
  IB_W         = (8|4|1) << 21   // increment before with writeback to base
};


class Address {
 public:
  // Memory operand addressing mode
  enum Mode {
    // bit encoding P U W
    Offset       = (8|4|0) << 21,  // offset (w/o writeback to base)
    PreIndex     = (8|4|1) << 21,  // pre-indexed addressing with writeback
    PostIndex    = (0|4|0) << 21,  // post-indexed addressing with writeback
    NegOffset    = (8|0|0) << 21,  // negative offset (w/o writeback to base)
    NegPreIndex  = (8|0|1) << 21,  // negative pre-indexed with writeback
    NegPostIndex = (0|0|0) << 21   // negative post-indexed with writeback
  };

  explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) {
    CHECK(IsAbsoluteUint(12, offset));
    if (offset < 0) {
      encoding_ = (am ^ (1 << kUShift)) | -offset;  // Flip U to adjust sign.
    } else {
      encoding_ = am | offset;
    }
    encoding_ |= static_cast<uint32_t>(rn) << kRnShift;
  }

  static bool CanHoldLoadOffset(LoadOperandType type, int offset);
  static bool CanHoldStoreOffset(StoreOperandType type, int offset);

 private:
  uint32_t encoding() const { return encoding_; }

  // Encoding for addressing mode 3.
  uint32_t encoding3() const {
    const uint32_t offset_mask = (1 << 12) - 1;
    uint32_t offset = encoding_ & offset_mask;
    CHECK_LT(offset, 256u);
    return (encoding_ & ~offset_mask) | ((offset & 0xf0) << 4) | (offset & 0xf);
  }

  // Encoding for vfp load/store addressing.
  uint32_t vencoding() const {
    const uint32_t offset_mask = (1 << 12) - 1;
    uint32_t offset = encoding_ & offset_mask;
    CHECK(IsAbsoluteUint(10, offset));  // In the range -1020 to +1020.
    CHECK(IsAligned(offset, 2));  // Multiple of 4.
    int mode = encoding_ & ((8|4|1) << 21);
    CHECK((mode == Offset) || (mode == NegOffset));
    uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2);
    if (mode == Offset) {
      vencoding |= 1 << 23;
    }
    return vencoding;
  }

  uint32_t encoding_;

  friend class Assembler;
};


class Assembler {
 public:
  Assembler() : buffer_() {}

  // Data-processing instructions.
  void and_(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void eor(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void sub(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
  void subs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void rsb(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
  void rsbs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void add(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void adds(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void adc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void sbc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void rsc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void tst(Register rn, ShifterOperand so, Condition cond = AL);

  void teq(Register rn, ShifterOperand so, Condition cond = AL);

  void cmp(Register rn, ShifterOperand so, Condition cond = AL);

  void cmn(Register rn, ShifterOperand so, Condition cond = AL);

  void orr(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
  void orrs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void mov(Register rd, ShifterOperand so, Condition cond = AL);
  void movs(Register rd, ShifterOperand so, Condition cond = AL);

  void bic(Register rd, Register rn, ShifterOperand so, Condition cond = AL);

  void mvn(Register rd, ShifterOperand so, Condition cond = AL);
  void mvns(Register rd, ShifterOperand so, Condition cond = AL);

  // Miscellaneous data-processing instructions.
  void clz(Register rd, Register rm, Condition cond = AL);
  void movw(Register rd, uint16_t imm16, Condition cond = AL);
  void movt(Register rd, uint16_t imm16, Condition cond = AL);

  // Multiply instructions.
  void mul(Register rd, Register rn, Register rm, Condition cond = AL);
  void mla(Register rd, Register rn, Register rm, Register ra,
           Condition cond = AL);
  void mls(Register rd, Register rn, Register rm, Register ra,
           Condition cond = AL);
  void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
             Condition cond = AL);

  // Load/store instructions.
  void ldr(Register rd, Address ad, Condition cond = AL);
  void str(Register rd, Address ad, Condition cond = AL);

  void ldrb(Register rd, Address ad, Condition cond = AL);
  void strb(Register rd, Address ad, Condition cond = AL);

  void ldrh(Register rd, Address ad, Condition cond = AL);
  void strh(Register rd, Address ad, Condition cond = AL);

  void ldrsb(Register rd, Address ad, Condition cond = AL);
  void ldrsh(Register rd, Address ad, Condition cond = AL);

  void ldrd(Register rd, Address ad, Condition cond = AL);
  void strd(Register rd, Address ad, Condition cond = AL);

  void ldm(BlockAddressMode am, Register base,
           RegList regs, Condition cond = AL);
  void stm(BlockAddressMode am, Register base,
           RegList regs, Condition cond = AL);

  void ldrex(Register rd, Register rn, Condition cond = AL);
  void strex(Register rd, Register rt, Register rn, Condition cond = AL);

  // Miscellaneous instructions.
  void clrex();
  void nop(Condition cond = AL);

  // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0.
  void bkpt(uint16_t imm16);
  void svc(uint32_t imm24);

  // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
  void vmovsr(SRegister sn, Register rt, Condition cond = AL);
  void vmovrs(Register rt, SRegister sn, Condition cond = AL);
  void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL);
  void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL);
  void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL);
  void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL);
  void vmovs(SRegister sd, SRegister sm, Condition cond = AL);
  void vmovd(DRegister dd, DRegister dm, Condition cond = AL);

  // Returns false if the immediate cannot be encoded.
  bool vmovs(SRegister sd, float s_imm, Condition cond = AL);
  bool vmovd(DRegister dd, double d_imm, Condition cond = AL);

  void vldrs(SRegister sd, Address ad, Condition cond = AL);
  void vstrs(SRegister sd, Address ad, Condition cond = AL);
  void vldrd(DRegister dd, Address ad, Condition cond = AL);
  void vstrd(DRegister dd, Address ad, Condition cond = AL);

  void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
  void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
  void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
  void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
  void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
  void vmuld(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
  void vmlas(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
  void vmlad(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
  void vmlss(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
  void vmlsd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
  void vdivs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
  void vdivd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);

  void vabss(SRegister sd, SRegister sm, Condition cond = AL);
  void vabsd(DRegister dd, DRegister dm, Condition cond = AL);
  void vnegs(SRegister sd, SRegister sm, Condition cond = AL);
  void vnegd(DRegister dd, DRegister dm, Condition cond = AL);
  void vsqrts(SRegister sd, SRegister sm, Condition cond = AL);
  void vsqrtd(DRegister dd, DRegister dm, Condition cond = AL);

  void vcvtsd(SRegister sd, DRegister dm, Condition cond = AL);
  void vcvtds(DRegister dd, SRegister sm, Condition cond = AL);
  void vcvtis(SRegister sd, SRegister sm, Condition cond = AL);
  void vcvtid(SRegister sd, DRegister dm, Condition cond = AL);
  void vcvtsi(SRegister sd, SRegister sm, Condition cond = AL);
  void vcvtdi(DRegister dd, SRegister sm, Condition cond = AL);
  void vcvtus(SRegister sd, SRegister sm, Condition cond = AL);
  void vcvtud(SRegister sd, DRegister dm, Condition cond = AL);
  void vcvtsu(SRegister sd, SRegister sm, Condition cond = AL);
  void vcvtdu(DRegister dd, SRegister sm, Condition cond = AL);

  void vcmps(SRegister sd, SRegister sm, Condition cond = AL);
  void vcmpd(DRegister dd, DRegister dm, Condition cond = AL);
  void vcmpsz(SRegister sd, Condition cond = AL);
  void vcmpdz(DRegister dd, Condition cond = AL);
  void vmstat(Condition cond = AL);  // VMRS APSR_nzcv, FPSCR

  // Branch instructions.
  void b(Label* label, Condition cond = AL);
  void bl(Label* label, Condition cond = AL);
  void blx(Register rm, Condition cond = AL);

  // Macros.
  // Add signed constant value to rd. May clobber IP.
  void AddConstant(Register rd, int32_t value, Condition cond = AL);
  void AddConstant(Register rd, Register rn, int32_t value,
                   Condition cond = AL);
  void AddConstantSetFlags(Register rd, Register rn, int32_t value,
                           Condition cond = AL);
  void AddConstantWithCarry(Register rd, Register rn, int32_t value,
                            Condition cond = AL);

  // Load and Store. May clobber IP.
  void LoadImmediate(Register rd, int32_t value, Condition cond = AL);
  void LoadSImmediate(SRegister sd, float value, Condition cond = AL);
  void LoadDImmediate(DRegister dd, double value,
                      Register scratch, Condition cond = AL);
  void MarkExceptionHandler(Label* label);
  void LoadFromOffset(LoadOperandType type,
                      Register reg,
                      Register base,
                      int32_t offset,
                      Condition cond = AL);
  void StoreToOffset(StoreOperandType type,
                     Register reg,
                     Register base,
                     int32_t offset,
                     Condition cond = AL);
  void LoadSFromOffset(SRegister reg,
                       Register base,
                       int32_t offset,
                       Condition cond = AL);
  void StoreSToOffset(SRegister reg,
                      Register base,
                      int32_t offset,
                      Condition cond = AL);
  void LoadDFromOffset(DRegister reg,
                       Register base,
                       int32_t offset,
                       Condition cond = AL);
  void StoreDToOffset(DRegister reg,
                      Register base,
                      int32_t offset,
                      Condition cond = AL);

  void Push(Register rd, Condition cond = AL);
  void Pop(Register rd, Condition cond = AL);

  void PushList(RegList regs, Condition cond = AL);
  void PopList(RegList regs, Condition cond = AL);

  void Mov(Register rd, Register rm, Condition cond = AL);

  // Convenience shift instructions. Use mov instruction with shifter operand
  // for variants setting the status flags or using a register shift count.
  void Lsl(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
  void Lsr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
  void Asr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
  void Ror(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
  void Rrx(Register rd, Register rm, Condition cond = AL);

  // Encode a signed constant in tst instructions, only affecting the flags.
  void EncodeUint32InTstInstructions(uint32_t data);
  // ... and decode from a pc pointing to the start of encoding instructions.
  static uint32_t DecodeUint32FromTstInstructions(uword pc);
  static bool IsInstructionForExceptionHandling(uword pc);

  // Debugging and bringup support.
  void Stop(const char* message);
  void Unimplemented(const char* message);
  void Untested(const char* message);
  void Unreachable(const char* message);

  // Emit code that will create an activation on the stack
  void BuildFrame(size_t frame_size, ManagedRegister method_reg);

  // Emit code that will remove an activation from the stack
  void RemoveFrame(size_t frame_size);

  void IncreaseFrameSize(size_t adjust);
  void DecreaseFrameSize(size_t adjust);

  // Store bytes from the given register onto the stack
  void Store(FrameOffset dest, ManagedRegister src, size_t size);
  void StoreRef(FrameOffset dest, ManagedRegister src);
  void StoreRawPtr(FrameOffset dest, ManagedRegister src);

  void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister scratch);
  void LoadRef(ManagedRegister dest, ManagedRegister base, MemberOffset offs);

  void StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
                             ManagedRegister scratch);
  void StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
                              ManagedRegister scratch);

  void Load(ManagedRegister dest, FrameOffset src, size_t size);

  void LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset offs);
  void CopyRawPtrFromThread(FrameOffset fr_offs, ThreadOffset thr_offs,
                            ManagedRegister scratch);
  void CopyRawPtrToThread(ThreadOffset thr_offs, FrameOffset fr_offs,
                          ManagedRegister scratch);

  void StoreStackOffsetToThread(ThreadOffset thr_offs, FrameOffset fr_offs,
                                ManagedRegister scratch);
  void StoreStackPointerToThread(ThreadOffset thr_offs);

  void Move(ManagedRegister dest, ManagedRegister src);
  void Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch,
            size_t size);
  void CreateStackHandle(ManagedRegister out_reg, FrameOffset handle_offset,
                         ManagedRegister in_reg, bool null_allowed);

  void CreateStackHandle(FrameOffset out_off, FrameOffset handle_offset,
                         ManagedRegister scratch, bool null_allowed);

  void LoadReferenceFromStackHandle(ManagedRegister dst, ManagedRegister src);

  void ValidateRef(ManagedRegister src, bool could_be_null);

  void ValidateRef(FrameOffset src, bool could_be_null);

  void Call(ManagedRegister base, Offset offset, ManagedRegister scratch);
  void Call(FrameOffset base, Offset offset, ManagedRegister scratch);

  // Generate code to check if Thread::Current()->suspend_count_ is non-zero
  // and branch to a SuspendSlowPath if it is. The SuspendSlowPath will continue
  // at the next instruction.
  void SuspendPoll(ManagedRegister scratch, ManagedRegister return_reg,
                   FrameOffset return_save_location, size_t return_size);

  // Generate code to check if Thread::Current()->exception_ is non-null
  // and branch to a ExceptionSlowPath if it is.
  void ExceptionPoll(ManagedRegister scratch);

  // Emit data (e.g. encoded instruction or immediate) to the
  // instruction stream.
  void Emit(int32_t value);

  void Bind(Label* label);

  void EmitSlowPaths() { buffer_.EmitSlowPaths(this); }

  size_t CodeSize() const { return buffer_.Size(); }

  void FinalizeInstructions(const MemoryRegion& region) {
    buffer_.FinalizeInstructions(region);
  }

 private:
  AssemblerBuffer buffer_;

  void EmitType01(Condition cond,
                  int type,
                  Opcode opcode,
                  int set_cc,
                  Register rn,
                  Register rd,
                  ShifterOperand so);

  void EmitType5(Condition cond, int offset, bool link);

  void EmitMemOp(Condition cond,
                 bool load,
                 bool byte,
                 Register rd,
                 Address ad);

  void EmitMemOpAddressMode3(Condition cond,
                             int32_t mode,
                             Register rd,
                             Address ad);

  void EmitMultiMemOp(Condition cond,
                      BlockAddressMode am,
                      bool load,
                      Register base,
                      RegList regs);

  void EmitShiftImmediate(Condition cond,
                          Shift opcode,
                          Register rd,
                          Register rm,
                          ShifterOperand so);

  void EmitShiftRegister(Condition cond,
                         Shift opcode,
                         Register rd,
                         Register rm,
                         ShifterOperand so);

  void EmitMulOp(Condition cond,
                 int32_t opcode,
                 Register rd,
                 Register rn,
                 Register rm,
                 Register rs);

  void EmitVFPsss(Condition cond,
                  int32_t opcode,
                  SRegister sd,
                  SRegister sn,
                  SRegister sm);

  void EmitVFPddd(Condition cond,
                  int32_t opcode,
                  DRegister dd,
                  DRegister dn,
                  DRegister dm);

  void EmitVFPsd(Condition cond,
                 int32_t opcode,
                 SRegister sd,
                 DRegister dm);

  void EmitVFPds(Condition cond,
                 int32_t opcode,
                 DRegister dd,
                 SRegister sm);

  void EmitBranch(Condition cond, Label* label, bool link);
  static int32_t EncodeBranchOffset(int offset, int32_t inst);
  static int DecodeBranchOffset(int32_t inst);
  int32_t EncodeTstOffset(int offset, int32_t inst);
  int DecodeTstOffset(int32_t inst);

  // Returns whether or not the given register is used for passing parameters.
  static int RegisterCompare(const Register* reg1, const Register* reg2) {
    return *reg1 - *reg2;
  }
};

}  // namespace art

#endif  // ART_SRC_ASSEMBLER_ARM_H_
