/* Disassemble ft32 instructions.
   Copyright (C) 2013-2021 Free Software Foundation, Inc.
   Contributed by FTDI (support@ftdichip.com)

   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.  */

#include "sysdep.h"
#include <stdio.h>
#define STATIC_TABLE
#define DEFINE_TABLE

#include "opcode/ft32.h"
#include "disassemble.h"

extern const ft32_opc_info_t ft32_opc_info[128];

static fprintf_ftype fpr;
static void *stream;

static int
sign_extend(int bit, int value)
{
  int onebit = (1 << bit);
  return (value & (onebit - 1)) - (value & onebit);
}

static void
ft32_opcode(bfd_vma addr ATTRIBUTE_UNUSED,
            unsigned int iword,
            struct disassemble_info *info)
{
  const ft32_opc_info_t *oo;

  for (oo = ft32_opc_info; oo->name; oo++)
    if ((iword & oo->mask) == oo->bits)
      break;

  unsigned int sc[2];
  if (ft32_decode_shortcode((unsigned int)addr, iword, sc))
    {
      ft32_opcode(addr, sc[0], info);
      fpr (stream, " ; ");
      ft32_opcode(addr, sc[1], info);
    }

  if (oo->name)
    {
      int f = oo->fields;
      int imm;

      fpr (stream, "%s", oo->name);
      if (oo->dw)
        {
          fpr (stream, ".%c ", "bsl"[(iword >> FT32_FLD_DW_BIT) & 3]);
        }
      else
        {
          fpr (stream, " ");
        }

      while (f)
        {
          int lobit = f & -f;
          if (f & lobit)
            {
              switch (lobit)
              {
              case  FT32_FLD_CBCRCV:
                /* imm is {CB, CV}  */
                imm = ((iword >> FT32_FLD_CB_BIT) & ((1 << FT32_FLD_CB_SIZ) - 1)) << 4;
                imm |= ((iword >> FT32_FLD_CV_BIT) & ((1 << FT32_FLD_CV_SIZ) - 1));
                switch (imm)
                {
                case 0x00: fpr(stream, "nz");  break;
                case 0x01: fpr(stream, "z");   break;
                case 0x10: fpr(stream, "ae");  break;
                case 0x11: fpr(stream, "b");   break;
                case 0x20: fpr(stream, "no");  break;
                case 0x21: fpr(stream, "o");   break;
                case 0x30: fpr(stream, "ns");  break;
                case 0x31: fpr(stream, "s");   break;
                case 0x40: fpr(stream, "lt");  break;
                case 0x41: fpr(stream, "gte"); break;
                case 0x50: fpr(stream, "lte"); break;
                case 0x51: fpr(stream, "gt");  break;
                case 0x60: fpr(stream, "be");  break;
                case 0x61: fpr(stream, "a");   break;
                default:   fpr(stream, "%d,$r30,%d", (imm >> 4), (imm & 1)); break;
                }
                break;
              case  FT32_FLD_CB:
                imm = (iword >> FT32_FLD_CB_BIT) & ((1 << FT32_FLD_CB_SIZ) - 1);
                fpr(stream, "%d", imm);
                break;
              case  FT32_FLD_R_D:
                fpr(stream, "$r%d", (iword >> FT32_FLD_R_D_BIT) & 0x1f);
                break;
              case  FT32_FLD_CR:
                imm = (iword >> FT32_FLD_CR_BIT) & ((1 << FT32_FLD_CR_SIZ) - 1);
                fpr(stream, "$r%d", 28 + imm);
                break;
              case  FT32_FLD_CV:
                imm = (iword >> FT32_FLD_CV_BIT) & ((1 << FT32_FLD_CV_SIZ) - 1);
                fpr(stream, "%d", imm);
                break;
              case  FT32_FLD_R_1:
                fpr(stream, "$r%d", (iword >> FT32_FLD_R_1_BIT) & 0x1f);
                break;
              case  FT32_FLD_RIMM:
                imm = (iword >> FT32_FLD_RIMM_BIT) & ((1 << FT32_FLD_RIMM_SIZ) - 1);
                if (imm & 0x400)
                  fpr(stream, "%d", sign_extend(9, imm));
                else
                  fpr(stream, "$r%d", imm & 0x1f);
                break;
              case  FT32_FLD_R_2:
                fpr(stream, "$r%d", (iword >> FT32_FLD_R_2_BIT) & 0x1f);
                break;
              case  FT32_FLD_K20:
                imm = iword & ((1 << FT32_FLD_K20_SIZ) - 1);
                fpr(stream, "%d", sign_extend(19, imm));
                break;
              case  FT32_FLD_PA:
                imm = (iword & ((1 << FT32_FLD_PA_SIZ) - 1)) << 2;
                info->print_address_func ((bfd_vma) imm, info);
                break;
              case  FT32_FLD_AA:
                imm = iword & ((1 << FT32_FLD_AA_SIZ) - 1);
                info->print_address_func ((1 << 23) | (bfd_vma) imm, info);
                break;
              case  FT32_FLD_K16:
                imm = iword & ((1 << FT32_FLD_K16_SIZ) - 1);
                fpr(stream, "%d", imm);
                break;
              case  FT32_FLD_K15:
                imm = iword & ((1 << FT32_FLD_K15_SIZ) - 1);
                fpr(stream, "%d", sign_extend(14, imm));
                break;
              case  FT32_FLD_R_D_POST:
                fpr(stream, "$r%d", (iword >> FT32_FLD_R_D_BIT) & 0x1f);
                break;
              case  FT32_FLD_R_1_POST:
                fpr(stream, "$r%d", (iword >> FT32_FLD_R_1_BIT) & 0x1f);
                break;
              default:
                break;
              }
              f &= ~lobit;
              if (f)
                {
                  fpr(stream, ",");
                }
            }
        }
    }
    else
    {
      fpr (stream, "!");
    }
}

int
print_insn_ft32 (bfd_vma addr, struct disassemble_info *info)
{
  int status;
  stream = info->stream;
  bfd_byte buffer[4];
  unsigned int iword;

  fpr = info->fprintf_func;

  if ((status = info->read_memory_func (addr, buffer, 4, info)))
    goto fail;

  iword = bfd_getl32 (buffer);

  fpr (stream, "%08x ", iword);

  ft32_opcode(addr, iword, info);

  return 4;

 fail:
  info->memory_error_func (status, addr, info);
  return -1;
}
