/* Instruction printing code for the DLX Microprocessor
   Copyright 2002, 2005, 2007, 2010 Free Software Foundation, Inc.
   Contributed by Kuang Hwa Lin.  Written by Kuang Hwa Lin, 03/2002.

   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 "dis-asm.h"
#include "opcode/dlx.h"

#define R_ERROR     0x1
#define R_TYPE      0x2
#define ILD_TYPE    0x3
#define IST_TYPE    0x4
#define IAL_TYPE    0x5
#define IBR_TYPE    0x6
#define IJ_TYPE     0x7
#define IJR_TYPE    0x8
#define NIL         0x9

#define OPC(x)      ((x >> 26) & 0x3F)
#define FUNC(x)     (x & 0x7FF)

unsigned char opc, rs1, rs2, rd;
unsigned long imm26, imm16, func, current_insn_addr;

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

static unsigned char
dlx_get_opcode (unsigned long opcode)
{
  return (unsigned char) ((opcode >> 26) & 0x3F);
}

static unsigned char
dlx_get_rs1 (unsigned long opcode)
{
  return (unsigned char) ((opcode >> 21) & 0x1F);
}

static unsigned char
dlx_get_rs2 (unsigned long opcode)
{
  return (unsigned char) ((opcode >> 16) & 0x1F);
}

static unsigned char
dlx_get_rdR (unsigned long opcode)
{
  return (unsigned char) ((opcode >> 11) & 0x1F);
}

static unsigned long
dlx_get_func (unsigned long opcode)
{
  return (unsigned char) (opcode & 0x7FF);
}

static unsigned long
dlx_get_imm16 (unsigned long opcode)
{
  return (unsigned long) (opcode & 0xFFFF);
}

static unsigned long
dlx_get_imm26 (unsigned long opcode)
{
  return (unsigned long) (opcode & 0x03FFFFFF);
}

/* Fill the opcode to the max length.  */

static void
operand_deliminator (struct disassemble_info *info, char *ptr)
{
  int difft = 8 - (int) strlen (ptr);

  while (difft > 0)
    {
      (*info->fprintf_func) (info->stream, "%c", ' ');
      difft -= 1;
    }
}

/* Process the R-type opcode.  */

static unsigned char
dlx_r_type (struct disassemble_info *info)
{
  unsigned char r_opc[] = { OPC(ALUOP) }; /* Fix ME */
  int r_opc_num = (sizeof r_opc) / (sizeof (char));
  struct _r_opcode
  {
    unsigned long func;
    char *name;
  }
  dlx_r_opcode[] =
  {
    { NOPF,     "nop"    },  /* NOP                          */
    { ADDF,     "add"    },  /* Add                          */
    { ADDUF,    "addu"   },  /* Add Unsigned                 */
    { SUBF,     "sub"    },  /* SUB                          */
    { SUBUF,    "subu"   },  /* Sub Unsigned                 */
    { MULTF,    "mult"   },  /* MULTIPLY                     */
    { MULTUF,   "multu"  },  /* MULTIPLY Unsigned            */
    { DIVF,     "div"    },  /* DIVIDE                       */
    { DIVUF,    "divu"   },  /* DIVIDE Unsigned              */
    { ANDF,     "and"    },  /* AND                          */
    { ORF,      "or"     },  /* OR                           */
    { XORF,     "xor"    },  /* Exclusive OR                 */
    { SLLF,     "sll"    },  /* SHIFT LEFT LOGICAL           */
    { SRAF,     "sra"    },  /* SHIFT RIGHT ARITHMETIC       */
    { SRLF,     "srl"    },  /* SHIFT RIGHT LOGICAL          */
    { SEQF,     "seq"    },  /* Set if equal                 */
    { SNEF,     "sne"    },  /* Set if not equal             */
    { SLTF,     "slt"    },  /* Set if less                  */
    { SGTF,     "sgt"    },  /* Set if greater               */
    { SLEF,     "sle"    },  /* Set if less or equal         */
    { SGEF,     "sge"    },  /* Set if greater or equal      */
    { SEQUF,    "sequ"   },  /* Set if equal                 */
    { SNEUF,    "sneu"   },  /* Set if not equal             */
    { SLTUF,    "sltu"   },  /* Set if less                  */
    { SGTUF,    "sgtu"   },  /* Set if greater               */
    { SLEUF,    "sleu"   },  /* Set if less or equal         */
    { SGEUF,    "sgeu"   },  /* Set if greater or equal      */
    { MVTSF,    "mvts"   },  /* Move to special register     */
    { MVFSF,    "mvfs"   },  /* Move from special register   */
    { BSWAPF,   "bswap"  },  /* Byte swap ??                 */
    { LUTF,     "lut"    }   /* ????????? ??                 */
  };
  int dlx_r_opcode_num = (sizeof dlx_r_opcode) / (sizeof dlx_r_opcode[0]);
  int idx;

  for (idx = 0; idx < r_opc_num; idx++)
    {
      if (r_opc[idx] != opc)
	continue;
      else
	break;
    }

  if (idx == r_opc_num)
    return NIL;

  for (idx = 0 ; idx < dlx_r_opcode_num; idx++)
    if (dlx_r_opcode[idx].func == func)
      {
	(*info->fprintf_func) (info->stream, "%s", dlx_r_opcode[idx].name);

	if (func != NOPF)
	  {
	    /* This is not a nop.  */
	    operand_deliminator (info, dlx_r_opcode[idx].name);
	    (*info->fprintf_func) (info->stream, "r%d,", (int)rd);
	    (*info->fprintf_func) (info->stream, "r%d", (int)rs1);
	    if (func != MVTSF && func != MVFSF)
	      (*info->fprintf_func) (info->stream, ",r%d", (int)rs2);
	  }
	return (unsigned char) R_TYPE;
      }

  return (unsigned char) R_ERROR;
}

/* Process the memory read opcode.  */

static unsigned char
dlx_load_type (struct disassemble_info* info)
{
  struct _load_opcode
  {
    unsigned long opcode;
    char *name;
  }
  dlx_load_opcode[] =
  {
    { OPC(LHIOP),   "lhi" },  /* Load HI to register.           */
    { OPC(LBOP),     "lb" },  /* load byte sign extended.       */
    { OPC(LBUOP),   "lbu" },  /* load byte unsigned.            */
    { OPC(LSBUOP),"ldstbu"},  /* load store byte unsigned.      */
    { OPC(LHOP),     "lh" },  /* load halfword sign extended.   */
    { OPC(LHUOP),   "lhu" },  /* load halfword unsigned.        */
    { OPC(LSHUOP),"ldsthu"},  /* load store halfword unsigned.  */
    { OPC(LWOP),     "lw" },  /* load word.                     */
    { OPC(LSWOP), "ldstw" }   /* load store word.               */
  };
  int dlx_load_opcode_num =
    (sizeof dlx_load_opcode) / (sizeof dlx_load_opcode[0]);
  int idx;

  for (idx = 0 ; idx < dlx_load_opcode_num; idx++)
    if (dlx_load_opcode[idx].opcode == opc)
      {
	if (opc == OPC (LHIOP))
	  {
	    (*info->fprintf_func) (info->stream, "%s", dlx_load_opcode[idx].name);
	    operand_deliminator (info, dlx_load_opcode[idx].name);
	    (*info->fprintf_func) (info->stream, "r%d,", (int)rs2);
	    (*info->fprintf_func) (info->stream, "0x%04x", (int)imm16);
	  }
	else
	  {
	    (*info->fprintf_func) (info->stream, "%s", dlx_load_opcode[idx].name);
	    operand_deliminator (info, dlx_load_opcode[idx].name);
	    (*info->fprintf_func) (info->stream, "r%d,", (int)rs2);
	    (*info->fprintf_func) (info->stream, "0x%04x[r%d]", (int)imm16, (int)rs1);
	  }

	return (unsigned char) ILD_TYPE;
    }

  return (unsigned char) NIL;
}

/* Process the memory store opcode.  */

static unsigned char
dlx_store_type (struct disassemble_info* info)
{
  struct _store_opcode
  {
    unsigned long opcode;
    char *name;
  }
  dlx_store_opcode[] =
  {
    { OPC(SBOP),     "sb" },  /* Store byte.      */
    { OPC(SHOP),     "sh" },  /* Store halfword.  */
    { OPC(SWOP),     "sw" },  /* Store word.      */
  };
  int dlx_store_opcode_num =
    (sizeof dlx_store_opcode) / (sizeof dlx_store_opcode[0]);
  int idx;

  for (idx = 0 ; idx < dlx_store_opcode_num; idx++)
    if (dlx_store_opcode[idx].opcode == opc)
      {
	(*info->fprintf_func) (info->stream, "%s", dlx_store_opcode[idx].name);
	operand_deliminator (info, dlx_store_opcode[idx].name);
	(*info->fprintf_func) (info->stream, "0x%04x[r%d],", (int)imm16, (int)rs1);
	(*info->fprintf_func) (info->stream, "r%d", (int)rs2);
	return (unsigned char) IST_TYPE;
      }

  return (unsigned char) NIL;
}

/* Process the Arithmetic and Logical I-TYPE opcode.  */

static unsigned char
dlx_aluI_type (struct disassemble_info* info)
{
  struct _aluI_opcode
  {
    unsigned long opcode;
    char *name;
  }
  dlx_aluI_opcode[] =
  {
    { OPC(ADDIOP),   "addi"  },  /* Store byte.      */
    { OPC(ADDUIOP),  "addui" },  /* Store halfword.  */
    { OPC(SUBIOP),   "subi"  },  /* Store word.      */
    { OPC(SUBUIOP),  "subui" },  /* Store word.      */
    { OPC(ANDIOP),   "andi"  },  /* Store word.      */
    { OPC(ORIOP),    "ori"   },  /* Store word.      */
    { OPC(XORIOP),   "xori"  },  /* Store word.      */
    { OPC(SLLIOP),   "slli"  },  /* Store word.      */
    { OPC(SRAIOP),   "srai"  },  /* Store word.      */
    { OPC(SRLIOP),   "srli"  },  /* Store word.      */
    { OPC(SEQIOP),   "seqi"  },  /* Store word.      */
    { OPC(SNEIOP),   "snei"  },  /* Store word.      */
    { OPC(SLTIOP),   "slti"  },  /* Store word.      */
    { OPC(SGTIOP),   "sgti"  },  /* Store word.      */
    { OPC(SLEIOP),   "slei"  },  /* Store word.      */
    { OPC(SGEIOP),   "sgei"  },  /* Store word.      */
    { OPC(SEQUIOP),  "sequi" },  /* Store word.      */
    { OPC(SNEUIOP),  "sneui" },  /* Store word.      */
    { OPC(SLTUIOP),  "sltui" },  /* Store word.      */
    { OPC(SGTUIOP),  "sgtui" },  /* Store word.      */
    { OPC(SLEUIOP),  "sleui" },  /* Store word.      */
    { OPC(SGEUIOP),  "sgeui" },  /* Store word.      */
#if 0						       
    { OPC(MVTSOP),   "mvts"  },  /* Store word.      */
    { OPC(MVFSOP),   "mvfs"  },  /* Store word.      */
#endif
  };
  int dlx_aluI_opcode_num =
    (sizeof dlx_aluI_opcode) / (sizeof dlx_aluI_opcode[0]);
  int idx;

  for (idx = 0 ; idx < dlx_aluI_opcode_num; idx++)
    if (dlx_aluI_opcode[idx].opcode == opc)
      {
	(*info->fprintf_func) (info->stream, "%s", dlx_aluI_opcode[idx].name);
	operand_deliminator (info, dlx_aluI_opcode[idx].name);
	(*info->fprintf_func) (info->stream, "r%d,", (int)rs2);
	(*info->fprintf_func) (info->stream, "r%d,", (int)rs1);
	(*info->fprintf_func) (info->stream, "0x%04x", (int)imm16);

	return (unsigned char) IAL_TYPE;
      }

  return (unsigned char) NIL;
}

/* Process the branch instruction.  */

static unsigned char
dlx_br_type (struct disassemble_info* info)
{
  struct _br_opcode
  {
    unsigned long opcode;
    char *name;
  }
  dlx_br_opcode[] =
  {
    { OPC(BEQOP), "beqz" }, /* Store byte.  */
    { OPC(BNEOP), "bnez" }  /* Store halfword.  */
  };
  int dlx_br_opcode_num =
    (sizeof dlx_br_opcode) / (sizeof dlx_br_opcode[0]);
  int idx;

  for (idx = 0 ; idx < dlx_br_opcode_num; idx++)
    if (dlx_br_opcode[idx].opcode == opc)
      {
	if (imm16 & 0x00008000)
	  imm16 |= 0xFFFF0000;

	imm16 += (current_insn_addr + 4);
	(*info->fprintf_func) (info->stream, "%s", dlx_br_opcode[idx].name);
	operand_deliminator (info, dlx_br_opcode[idx].name);
	(*info->fprintf_func) (info->stream, "r%d,", (int) rs1);
	(*info->fprintf_func) (info->stream, "0x%08x", (int) imm16);

	return (unsigned char) IBR_TYPE;
      }

  return (unsigned char) NIL;
}

/* Process the jump instruction.  */

static unsigned char
dlx_jmp_type (struct disassemble_info* info)
{
  struct _jmp_opcode
  {
    unsigned long opcode;
    char *name;
  }
  dlx_jmp_opcode[] =
  {
    { OPC(JOP),         "j" },  /* Store byte.      */
    { OPC(JALOP),     "jal" },  /* Store halfword.  */
    { OPC(BREAKOP), "break" },  /* Store halfword.  */
    { OPC(TRAPOP),   "trap" },  /* Store halfword.  */
    { OPC(RFEOP),     "rfe" }   /* Store halfword.  */
  };
  int dlx_jmp_opcode_num =
    (sizeof dlx_jmp_opcode) / (sizeof dlx_jmp_opcode[0]);
  int idx;

  for (idx = 0 ; idx < dlx_jmp_opcode_num; idx++)
    if (dlx_jmp_opcode[idx].opcode == opc)
      {
	if (imm26 & 0x02000000)
	  imm26 |= 0xFC000000;

	imm26 += (current_insn_addr + 4);

	(*info->fprintf_func) (info->stream, "%s", dlx_jmp_opcode[idx].name);
	operand_deliminator (info, dlx_jmp_opcode[idx].name);
	(*info->fprintf_func) (info->stream, "0x%08x", (int)imm26);

	return (unsigned char) IJ_TYPE;
      }

  return (unsigned char) NIL;
}

/* Process the jump register instruction.  */

static unsigned char
dlx_jr_type (struct disassemble_info* info)
{
  struct _jr_opcode
  {
    unsigned long opcode;
    char *name;
  }
  dlx_jr_opcode[] =
  {
    { OPC(JROP),   "jr"    },  /* Store byte.  */
    { OPC(JALROP), "jalr"  }   /* Store halfword.  */
  };
  int dlx_jr_opcode_num =
    (sizeof dlx_jr_opcode) / (sizeof dlx_jr_opcode[0]);
  int idx;

  for (idx = 0 ; idx < dlx_jr_opcode_num; idx++)
    if (dlx_jr_opcode[idx].opcode == opc)
      {
	(*info->fprintf_func) (info->stream, "%s", dlx_jr_opcode[idx].name);
	operand_deliminator (info, dlx_jr_opcode[idx].name);
	(*info->fprintf_func) (info->stream, "r%d", (int)rs1);
	return (unsigned char) IJR_TYPE;
      }

  return (unsigned char) NIL;
}

typedef unsigned char (* dlx_insn) (struct disassemble_info *);

/* This is the main DLX insn handling routine.  */

int
print_insn_dlx (bfd_vma memaddr, struct disassemble_info* info)
{
  bfd_byte buffer[4];
  int insn_idx;
  unsigned long insn_word;
  dlx_insn dlx_insn_type[] =
  {
    dlx_r_type,
    dlx_load_type,
    dlx_store_type,
    dlx_aluI_type,
    dlx_br_type,
    dlx_jmp_type,
    dlx_jr_type,
    (dlx_insn) NULL
  };
  int dlx_insn_type_num = ((sizeof dlx_insn_type) / (sizeof (dlx_insn))) - 1;
  int status =
    (*info->read_memory_func) (memaddr, (bfd_byte *) &buffer[0], 4, info);

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

  /* Now decode the insn    */
  insn_word = bfd_getb32 (buffer);
  opc  = dlx_get_opcode (insn_word);
  rs1  = dlx_get_rs1 (insn_word);
  rs2  = dlx_get_rs2 (insn_word);
  rd   = dlx_get_rdR (insn_word);
  func = dlx_get_func (insn_word);
  imm16= dlx_get_imm16 (insn_word);
  imm26= dlx_get_imm26 (insn_word);

#if 0
  printf ("print_insn_big_dlx: opc = 0x%02x\n"
	  "                    rs1 = 0x%02x\n"
	  "                    rs2 = 0x%02x\n"
	  "                    rd  = 0x%02x\n"
	  "                  func  = 0x%08x\n"
	  "                 imm16  = 0x%08x\n"
	  "                 imm26  = 0x%08x\n",
	  opc, rs1, rs2, rd, func, imm16, imm26);
#endif

  /* Scan through all the insn type and print the insn out.  */
  current_insn_addr = (unsigned long) memaddr;

  for (insn_idx = 0; dlx_insn_type[insn_idx] != 0x0; insn_idx++)
    switch ((dlx_insn_type[insn_idx]) (info))
      {
	/* Found the correct opcode   */
      case R_TYPE:
      case ILD_TYPE:
      case IST_TYPE:
      case IAL_TYPE:
      case IBR_TYPE:
      case IJ_TYPE:
      case IJR_TYPE:
	return 4;

	/* Wrong insn type check next one. */
      default:
      case NIL:
	continue;

	/* All rest of the return code are not recongnized, treat it as error */
	/* we should never get here,  I hope! */
      case R_ERROR:
	return -1;
      }

  if (insn_idx ==  dlx_insn_type_num)
    /* Well, does not recoganize this opcode.  */
    (*info->fprintf_func) (info->stream, "<%s>", "Unrecognized Opcode");

  return 4;
}
