// -*- C -*-

// Simulator definition for the Broadcom SiByte SB-1 CPU extensions.
// Copyright (C) 2002 Free Software Foundation, Inc.
// Contributed by Broadcom Corporation (SiByte).
//
// This file is part of GDB, the GNU debugger.
// 
// 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 2, 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, write to the Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


//  MDMX ASE Instructions
//  ---------------------
//
//  The SB-1 implements the format OB subset of MDMX
//  and has three additions (pavg, pabsdiff, pabsdifc).
//  In addition, there are a couple of partial-decoding
//  issues for the read/write accumulator instructions.
//
//  This code is structured so that mdmx.igen can be used by
//  selecting the allowed instructions either via model, or by
//  using check_mdmx_fmtsel and check_mdmx_fmtop to cause an
//  exception if the instruction is not allowed.


:function:::void:check_mdmx:instruction_word insn
*sb1:
{
  if (!COP_Usable(1))
    SignalExceptionCoProcessorUnusable(1);
  if ((SR & status_MX) == 0)
    SignalExceptionMDMX();
  check_u64 (SD_, insn);
}

:function:::int:check_mdmx_fmtsel:instruction_word insn, int fmtsel
*sb1:
{
  switch (fmtsel & 0x03)
    {
    case 0x00:     /* ob */
    case 0x02:
      return 1;
    case 0x01:     /* qh */
    case 0x03:     /* UNPREDICTABLE */
      SignalException (ReservedInstruction, insn);
      return 0;
    }
  return 0;
}

:function:::int:check_mdmx_fmtop:instruction_word insn, int fmtop
*sb1:
{
  switch (fmtop & 0x01)
    {
    case 0x00:     /* ob */
      return 1;
    case 0x01:     /* qh */
      SignalException (ReservedInstruction, insn);
      return 0;
    }
  return 0;
}


011110,10,2.X!0,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACH.sb1.fmt
"rach.?<X>.%s<FMTOP> v<VD>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
  /* No op.  */
}


011110,00,2.X!0,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACL.sb1.fmt
"racl.?<X>.%s<FMTOP> v<VD>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
  /* No op.  */
}


011110,01,2.X!0,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACM.sb1.fmt
"racm.?<X>.%s<FMTOP> v<VD>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
  /* No op.  */
}


011110,2.X1!0!1!2,2.X2,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RAC.sb1.fmt
"rac?<X1>.?<X2> v<VD>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
  /* No op.  */
}


011110,10,2.X!0,1.FMTOP,00000,5.VS,00000,111110:MDMX:64::WACH.sb1.fmt
"wach.?<X>.%s<FMTOP> v<VS>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
  /* No op.  */
}


011110,00,2.X!0,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WACL.sb1.fmt
"wacl.?<X>.%s<FMTOP> v<VS>,v<VT>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
  /* No op.  */
}


011110,2.X1!0!2,2.X2,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WAC.sb1.fmt
"wacl?<X1>.?<X2>.%s<FMTOP> v<VS>,v<VT>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
  /* No op.  */
}


011110,5.FMTSEL,5.VT,5.VS,5.VD,001001:MDMX:64::PABSDIFF.fmt
"pabsdiff.%s<FMTSEL> v<VD>,v<VS>,v<VT>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  if (SR & status_SBX)
    {
      check_mdmx_fmtsel (SD_, instruction_0, FMTSEL);
      StoreFPR(VD,fmt_mdmx,MX_AbsDiff(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
    }
  else
    SignalException(ReservedInstruction, instruction_0);
}


011110,5.FMTSEL,5.VT,5.VS,00000,110101:MDMX:64::PABSDIFC.fmt
"pabsdifc.%<FMTSEL> v<VS>,v<VT>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  if (SR & status_SBX)
    {
      check_mdmx_fmtsel (SD_, instruction_0, FMTSEL);
      MX_AbsDiffC(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
    }
  else
    SignalException(ReservedInstruction, instruction_0);
}


011110,5.FMTSEL,5.VT,5.VS,5.VD,001000:MDMX:64::PAVG.fmt
"pavg.%s<FMTSEL> v<VD>,v<VS>,v<VT>"
*sb1:
{
  check_mdmx (SD_, instruction_0);
  if (SR & status_SBX)
    {
      check_mdmx_fmtsel (SD_, instruction_0, FMTSEL);
      StoreFPR(VD,fmt_mdmx,MX_Avg(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
    }
  else
    SignalException(ReservedInstruction, instruction_0);
}
