/* Copyright (C) 2009-2016 Free Software Foundation, Inc.
   Contributed by ARM Ltd.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "common-defs.h"
#include "aarch64-insn.h"

/* Toggle this file's internal debugging dump.  */
int aarch64_debug = 0;

/* Extract a signed value from a bit field within an instruction
   encoding.

   INSN is the instruction opcode.

   WIDTH specifies the width of the bit field to extract (in bits).

   OFFSET specifies the least significant bit of the field where bits
   are numbered zero counting from least to most significant.  */

static int32_t
extract_signed_bitfield (uint32_t insn, unsigned width, unsigned offset)
{
  unsigned shift_l = sizeof (int32_t) * 8 - (offset + width);
  unsigned shift_r = sizeof (int32_t) * 8 - width;

  return ((int32_t) insn << shift_l) >> shift_r;
}

/* Determine if specified bits within an instruction opcode matches a
   specific pattern.

   INSN is the instruction opcode.

   MASK specifies the bits within the opcode that are to be tested
   agsinst for a match with PATTERN.  */

static int
decode_masked_match (uint32_t insn, uint32_t mask, uint32_t pattern)
{
  return (insn & mask) == pattern;
}

/* Decode an opcode if it represents an ADR or ADRP instruction.

   ADDR specifies the address of the opcode.
   INSN specifies the opcode to test.
   IS_ADRP receives the 'op' field from the decoded instruction.
   RD receives the 'rd' field from the decoded instruction.
   OFFSET receives the 'immhi:immlo' field from the decoded instruction.

   Return 1 if the opcodes matches and is decoded, otherwise 0.  */

int
aarch64_decode_adr (CORE_ADDR addr, uint32_t insn, int *is_adrp,
		    unsigned *rd, int32_t *offset)
{
  /* adr  0ii1 0000 iiii iiii iiii iiii iiir rrrr */
  /* adrp 1ii1 0000 iiii iiii iiii iiii iiir rrrr */
  if (decode_masked_match (insn, 0x1f000000, 0x10000000))
    {
      uint32_t immlo = (insn >> 29) & 0x3;
      int32_t immhi = extract_signed_bitfield (insn, 19, 5) << 2;

      *is_adrp = (insn >> 31) & 0x1;
      *rd = (insn >> 0) & 0x1f;

      if (*is_adrp)
	{
	  /* The ADRP instruction has an offset with a -/+ 4GB range,
	     encoded as (immhi:immlo * 4096).  */
	  *offset = (immhi | immlo) * 4096;
	}
      else
	*offset = (immhi | immlo);

      if (aarch64_debug)
	{
	  debug_printf ("decode: 0x%s 0x%x %s x%u, #?\n",
			core_addr_to_string_nz (addr), insn,
			*is_adrp ?  "adrp" : "adr", *rd);
	}
      return 1;
    }
  return 0;
}

/* Decode an opcode if it represents an branch immediate or branch
   and link immediate instruction.

   ADDR specifies the address of the opcode.
   INSN specifies the opcode to test.
   IS_BL receives the 'op' bit from the decoded instruction.
   OFFSET receives the immediate offset from the decoded instruction.

   Return 1 if the opcodes matches and is decoded, otherwise 0.  */

int
aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
		  int32_t *offset)
{
  /* b  0001 01ii iiii iiii iiii iiii iiii iiii */
  /* bl 1001 01ii iiii iiii iiii iiii iiii iiii */
  if (decode_masked_match (insn, 0x7c000000, 0x14000000))
    {
      *is_bl = (insn >> 31) & 0x1;
      *offset = extract_signed_bitfield (insn, 26, 0) << 2;

      if (aarch64_debug)
	{
	  debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
			core_addr_to_string_nz (addr), insn,
			*is_bl ? "bl" : "b",
			core_addr_to_string_nz (addr + *offset));
	}

      return 1;
    }
  return 0;
}

/* Decode an opcode if it represents a conditional branch instruction.

   ADDR specifies the address of the opcode.
   INSN specifies the opcode to test.
   COND receives the branch condition field from the decoded
   instruction.
   OFFSET receives the immediate offset from the decoded instruction.

   Return 1 if the opcodes matches and is decoded, otherwise 0.  */

int
aarch64_decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond,
		      int32_t *offset)
{
  /* b.cond  0101 0100 iiii iiii iiii iiii iii0 cccc */
  if (decode_masked_match (insn, 0xff000010, 0x54000000))
    {
      *cond = (insn >> 0) & 0xf;
      *offset = extract_signed_bitfield (insn, 19, 5) << 2;

      if (aarch64_debug)
	{
	  debug_printf ("decode: 0x%s 0x%x b<%u> 0x%s\n",
			core_addr_to_string_nz (addr), insn, *cond,
			core_addr_to_string_nz (addr + *offset));
	}
      return 1;
    }
  return 0;
}

/* Decode an opcode if it represents a CBZ or CBNZ instruction.

   ADDR specifies the address of the opcode.
   INSN specifies the opcode to test.
   IS64 receives the 'sf' field from the decoded instruction.
   IS_CBNZ receives the 'op' field from the decoded instruction.
   RN receives the 'rn' field from the decoded instruction.
   OFFSET receives the 'imm19' field from the decoded instruction.

   Return 1 if the opcodes matches and is decoded, otherwise 0.  */

int
aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
		   unsigned *rn, int32_t *offset)
{
  /* cbz  T011 010o iiii iiii iiii iiii iiir rrrr */
  /* cbnz T011 010o iiii iiii iiii iiii iiir rrrr */
  if (decode_masked_match (insn, 0x7e000000, 0x34000000))
    {
      *rn = (insn >> 0) & 0x1f;
      *is64 = (insn >> 31) & 0x1;
      *is_cbnz = (insn >> 24) & 0x1;
      *offset = extract_signed_bitfield (insn, 19, 5) << 2;

      if (aarch64_debug)
	{
	  debug_printf ("decode: 0x%s 0x%x %s 0x%s\n",
			core_addr_to_string_nz (addr), insn,
			*is_cbnz ? "cbnz" : "cbz",
			core_addr_to_string_nz (addr + *offset));
	}
      return 1;
    }
  return 0;
}

/* Decode an opcode if it represents a TBZ or TBNZ instruction.

   ADDR specifies the address of the opcode.
   INSN specifies the opcode to test.
   IS_TBNZ receives the 'op' field from the decoded instruction.
   BIT receives the bit position field from the decoded instruction.
   RT receives 'rt' field from the decoded instruction.
   IMM receives 'imm' field from the decoded instruction.

   Return 1 if the opcodes matches and is decoded, otherwise 0.  */

int
aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
		   unsigned *bit, unsigned *rt, int32_t *imm)
{
  /* tbz  b011 0110 bbbb biii iiii iiii iiir rrrr */
  /* tbnz B011 0111 bbbb biii iiii iiii iiir rrrr */
  if (decode_masked_match (insn, 0x7e000000, 0x36000000))
    {
      *rt = (insn >> 0) & 0x1f;
      *is_tbnz = (insn >> 24) & 0x1;
      *bit = ((insn >> (31 - 4)) & 0x20) | ((insn >> 19) & 0x1f);
      *imm = extract_signed_bitfield (insn, 14, 5) << 2;

      if (aarch64_debug)
	{
	  debug_printf ("decode: 0x%s 0x%x %s x%u, #%u, 0x%s\n",
			core_addr_to_string_nz (addr), insn,
			*is_tbnz ? "tbnz" : "tbz", *rt, *bit,
			core_addr_to_string_nz (addr + *imm));
	}
      return 1;
    }
  return 0;
}

/* Decode an opcode if it represents an LDR or LDRSW instruction taking a
   literal offset from the current PC.

   ADDR specifies the address of the opcode.
   INSN specifies the opcode to test.
   IS_W is set if the instruction is LDRSW.
   IS64 receives size field from the decoded instruction.
   RT receives the 'rt' field from the decoded instruction.
   OFFSET receives the 'imm' field from the decoded instruction.

   Return 1 if the opcodes matches and is decoded, otherwise 0.  */

int
aarch64_decode_ldr_literal (CORE_ADDR addr, uint32_t insn, int *is_w,
			    int *is64, unsigned *rt, int32_t *offset)
{
  /* LDR    0T01 1000 iiii iiii iiii iiii iiir rrrr */
  /* LDRSW  1001 1000 iiii iiii iiii iiii iiir rrrr */
  if ((insn & 0x3f000000) == 0x18000000)
    {
      *is_w = (insn >> 31) & 0x1;

      if (*is_w)
	{
	  /* LDRSW always takes a 64-bit destination registers.  */
	  *is64 = 1;
	}
      else
	*is64 = (insn >> 30) & 0x1;

      *rt = (insn >> 0) & 0x1f;
      *offset = extract_signed_bitfield (insn, 19, 5) << 2;

      if (aarch64_debug)
	debug_printf ("decode: %s 0x%x %s %s%u, #?\n",
		      core_addr_to_string_nz (addr), insn,
		      *is_w ? "ldrsw" : "ldr",
		      *is64 ? "x" : "w", *rt);

      return 1;
    }

  return 0;
}

/* Visit an instruction INSN by VISITOR with all needed information in DATA.

   PC relative instructions need to be handled specifically:

   - B/BL
   - B.COND
   - CBZ/CBNZ
   - TBZ/TBNZ
   - ADR/ADRP
   - LDR/LDRSW (literal)  */

void
aarch64_relocate_instruction (uint32_t insn,
			      const struct aarch64_insn_visitor *visitor,
			      struct aarch64_insn_data *data)
{
  int is_bl;
  int is64;
  int is_sw;
  int is_cbnz;
  int is_tbnz;
  int is_adrp;
  unsigned rn;
  unsigned rt;
  unsigned rd;
  unsigned cond;
  unsigned bit;
  int32_t offset;

  if (aarch64_decode_b (data->insn_addr, insn, &is_bl, &offset))
    visitor->b (is_bl, offset, data);
  else if (aarch64_decode_bcond (data->insn_addr, insn, &cond, &offset))
    visitor->b_cond (cond, offset, data);
  else if (aarch64_decode_cb (data->insn_addr, insn, &is64, &is_cbnz, &rn,
			      &offset))
    visitor->cb (offset, is_cbnz, rn, is64, data);
  else if (aarch64_decode_tb (data->insn_addr, insn, &is_tbnz, &bit, &rt,
			      &offset))
    visitor->tb (offset, is_tbnz, rt, bit, data);
  else if (aarch64_decode_adr (data->insn_addr, insn, &is_adrp, &rd, &offset))
    visitor->adr (offset, rd, is_adrp, data);
  else if (aarch64_decode_ldr_literal (data->insn_addr, insn, &is_sw, &is64,
				       &rt, &offset))
    visitor->ldr_literal (offset, is_sw, rt, is64, data);
  else
    visitor->others (insn, data);
}

/* Write a 32-bit unsigned integer INSN info *BUF.  Return the number of
   instructions written (aka. 1).  */

int
aarch64_emit_insn (uint32_t *buf, uint32_t insn)
{
  *buf = insn;
  return 1;
}

/* Helper function emitting a load or store instruction.  */

int
aarch64_emit_load_store (uint32_t *buf, uint32_t size,
			 enum aarch64_opcodes opcode,
			 struct aarch64_register rt,
			 struct aarch64_register rn,
			 struct aarch64_memory_operand operand)
{
  uint32_t op;

  switch (operand.type)
    {
    case MEMORY_OPERAND_OFFSET:
      {
	op = ENCODE (1, 1, 24);

	return aarch64_emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
				  | ENCODE (operand.index >> 3, 12, 10)
				  | ENCODE (rn.num, 5, 5)
				  | ENCODE (rt.num, 5, 0));
      }
    case MEMORY_OPERAND_POSTINDEX:
      {
	uint32_t post_index = ENCODE (1, 2, 10);

	op = ENCODE (0, 1, 24);

	return aarch64_emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
				  | post_index | ENCODE (operand.index, 9, 12)
				  | ENCODE (rn.num, 5, 5)
				  | ENCODE (rt.num, 5, 0));
      }
    case MEMORY_OPERAND_PREINDEX:
      {
	uint32_t pre_index = ENCODE (3, 2, 10);

	op = ENCODE (0, 1, 24);

	return aarch64_emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
				  | pre_index | ENCODE (operand.index, 9, 12)
				  | ENCODE (rn.num, 5, 5)
				  | ENCODE (rt.num, 5, 0));
      }
    default:
      return 0;
    }
}
