/* Instruction printing code for the OpenRISC 1000
   Copyright (C) 2002, 2005, 2007, 2012 Free Software Foundation, Inc.
   Contributed by Damjan Lampret <lampret@opencores.org>.
   Modified from a29k port.

   This file is part of the GNU opcodes library.

   This library 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, or (at your option)
   any later version.

   It 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, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#ifndef DEBUG
#define DEBUG 0
#endif

#include "sysdep.h"
#include "dis-asm.h"
#include "opcode/or32.h"
#include "safe-ctype.h"

#define EXTEND29(x) ((x) & (unsigned long) 0x10000000 ? ((x) | (unsigned long) 0xf0000000) : ((x)))

/* Now find the four bytes of INSN_CH and put them in *INSN.  */

static void
find_bytes_big (unsigned char *insn_ch, unsigned long *insn)
{
  *insn =
    ((unsigned long) insn_ch[0] << 24) +
    ((unsigned long) insn_ch[1] << 16) +
    ((unsigned long) insn_ch[2] << 8) +
    ((unsigned long) insn_ch[3]);
#if DEBUG
  printf ("find_bytes_big3: %lx\n", *insn);
#endif
}

static void
find_bytes_little (unsigned char *insn_ch, unsigned long *insn)
{
  *insn =
    ((unsigned long) insn_ch[3] << 24) +
    ((unsigned long) insn_ch[2] << 16) +
    ((unsigned long) insn_ch[1] << 8) +
    ((unsigned long) insn_ch[0]);
}

typedef void (*find_byte_func_type) (unsigned char *, unsigned long *);

static unsigned long
or32_extract (char param_ch, char *enc_initial, unsigned long insn)
{
  char *enc;
  unsigned long ret = 0;
  int opc_pos = 0;
  int param_pos = 0;

  for (enc = enc_initial; *enc != '\0'; enc++)
    if (*enc == param_ch)
      {
	if (enc - 2 >= enc_initial && (*(enc - 2) == '0') && (*(enc - 1) == 'x'))
	  continue;
	else
	  param_pos++;
      }

#if DEBUG
  printf ("or32_extract: %c %x ", param_ch, param_pos);
#endif
  opc_pos = 32;

  for (enc = enc_initial; *enc != '\0'; )
    if ((*enc == '0') && (*(enc + 1) == 'x'))
      {
	opc_pos -= 4;

	if ((param_ch == '0') || (param_ch == '1'))
	  {
	    unsigned long tmp = strtoul (enc, NULL, 16);
#if DEBUG
	    printf (" enc=%s, tmp=%lx ", enc, tmp);
#endif
	    if (param_ch == '0')
	      tmp = 15 - tmp;
	    ret |= tmp << opc_pos;
	  }
	enc += 3;
      }
    else if ((*enc == '0') || (*enc == '1'))
      {
	opc_pos--;
	if (param_ch == *enc)
	  ret |= 1 << opc_pos;
	enc++;
      }
    else if (*enc == param_ch)
      {
	opc_pos--;
	param_pos--;
#if DEBUG
	printf ("\n  ret=%lx opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos);
#endif
	ret += ((insn >> opc_pos) & 0x1) << param_pos;

	if (!param_pos
	    && letter_signed (param_ch)
	    && ret >> (letter_range (param_ch) - 1))
	  {
#if DEBUG
	    printf ("\n  ret=%lx opc_pos=%x, param_pos=%x\n",
		    ret, opc_pos, param_pos);
#endif
	    ret |= 0xffffffff << letter_range(param_ch);
#if DEBUG
	    printf ("\n  after conversion to signed: ret=%lx\n", ret);
#endif
	  }
	enc++;
      }
    else if (ISALPHA (*enc))
      {
	opc_pos--;
	enc++;
      }
    else if (*enc == '-')
      {
	opc_pos--;
	enc++;
      }
    else
      enc++;

#if DEBUG
  printf ("ret=%lx\n", ret);
#endif
  return ret;
}

static int
or32_opcode_match (unsigned long insn, char *encoding)
{
  unsigned long ones, zeros;

#if DEBUG
  printf ("or32_opcode_match: %.8lx\n", insn);
#endif    
  ones  = or32_extract ('1', encoding, insn);
  zeros = or32_extract ('0', encoding, insn);
  
#if DEBUG
  printf ("ones: %lx \n", ones);
  printf ("zeros: %lx \n", zeros);
#endif
  if ((insn & ones) != ones)
    {
#if DEBUG
      printf ("ret1\n");
#endif
      return 0;
    }
    
  if ((~insn & zeros) != zeros)
    {
#if DEBUG
      printf ("ret2\n");
#endif
      return 0;
    }
  
#if DEBUG
  printf ("ret3\n");
#endif
  return 1;
}

/* Print register to INFO->STREAM. Used only by print_insn.  */

static void
or32_print_register (char param_ch,
		     char *encoding,
		     unsigned long insn,
		     struct disassemble_info *info)
{
  int regnum = or32_extract (param_ch, encoding, insn);
  
#if DEBUG
  printf ("or32_print_register: %c, %s, %lx\n", param_ch, encoding, insn);
#endif  
  if (param_ch == 'A')
    (*info->fprintf_func) (info->stream, "r%d", regnum);
  else if (param_ch == 'B')
    (*info->fprintf_func) (info->stream, "r%d", regnum);
  else if (param_ch == 'D')
    (*info->fprintf_func) (info->stream, "r%d", regnum);
  else if (regnum < 16)
    (*info->fprintf_func) (info->stream, "r%d", regnum);
  else if (regnum < 32)
    (*info->fprintf_func) (info->stream, "r%d", regnum-16);
  else
    (*info->fprintf_func) (info->stream, "X%d", regnum);
}

/* Print immediate to INFO->STREAM. Used only by print_insn.  */

static void
or32_print_immediate (char param_ch,
		      char *encoding,
		      unsigned long insn,
		      struct disassemble_info *info)
{
  int imm = or32_extract(param_ch, encoding, insn);
  
  if (letter_signed(param_ch))
    (*info->fprintf_func) (info->stream, "0x%x", imm);
/*    (*info->fprintf_func) (info->stream, "%d", imm); */
  else
    (*info->fprintf_func) (info->stream, "0x%x", imm);
}

/* Print one instruction from MEMADDR on INFO->STREAM.
   Return the size of the instruction (always 4 on or32).  */

static int
print_insn (bfd_vma memaddr, struct disassemble_info *info)
{
  /* The raw instruction.  */
  unsigned char insn_ch[4];
  /* Address. Will be sign extened 27-bit.  */
  unsigned long addr;
  /* The four bytes of the instruction.  */
  unsigned long insn;
  find_byte_func_type find_byte_func = (find_byte_func_type) info->private_data;
  struct or32_opcode const * opcode;

  {
    int status =
      (*info->read_memory_func) (memaddr, (bfd_byte *) &insn_ch[0], 4, info);

    if (status != 0)
      {
        (*info->memory_error_func) (status, memaddr, info);
        return -1;
      }
  }

  (*find_byte_func) (&insn_ch[0], &insn);

  for (opcode = &or32_opcodes[0];
       opcode < &or32_opcodes[or32_num_opcodes];
       ++opcode)
    {
      if (or32_opcode_match (insn, opcode->encoding))
        {
          char *s;

          (*info->fprintf_func) (info->stream, "%s ", opcode->name);

          for (s = opcode->args; *s != '\0'; ++s)
            {
              switch (*s)
                {
                case '\0':
                  return 4;
      
                case 'r':
                  or32_print_register (*++s, opcode->encoding, insn, info);
                  break;

                case 'X':
                  addr = or32_extract ('X', opcode->encoding, insn) << 2;

                  /* Calulate the correct address.  XXX is this really correct ??  */
                  addr = memaddr + EXTEND29 (addr);

                  (*info->print_address_func)
                    (addr, info);
                  break;

                default:
                  if (strchr (opcode->encoding, *s))
                    or32_print_immediate (*s, opcode->encoding, insn, info);
                  else
                    (*info->fprintf_func) (info->stream, "%c", *s);
                }
            }

          return 4;
        }
    }

  /* This used to be %8x for binutils.  */
  (*info->fprintf_func)
    (info->stream, ".word 0x%08lx", insn);
  return 4;
}

/* Disassemble a big-endian or32 instruction.  */

int
print_insn_big_or32 (bfd_vma memaddr, struct disassemble_info *info)
{
  info->private_data = find_bytes_big;

  return print_insn (memaddr, info);
}

/* Disassemble a little-endian or32 instruction.  */

int
print_insn_little_or32 (bfd_vma memaddr, struct disassemble_info *info)
{
  info->private_data = find_bytes_little;
  return print_insn (memaddr, info);
}
