Support R_SPARC_WDISP10 and R_SPARC_H34.
[external/binutils.git] / sim / mips / mdmx.igen
index 5222863..8e135ee 100644 (file)
-//  -*- C -*-
-// Media Instructions
-// ------------------
-
-// Ref: http://www.sgi.com/MIPS/arch/ISA5/MDMXspec.pdf
-
-// Note: For OB instructions, the sel field is deduced by special
-// handling of the "vt" operand.
-//         If vt is:
-//             of the form $vt[0],        then sel is 0000
-//             of the form $vt[1],        then sel is 0001
-//             of the form $vt[2],        then sel is 0010
-//             of the form $vt[3],        then sel is 0011
-//             of the form $vt[4],        then sel is 0100
-//             of the form $vt[5],        then sel is 0101
-//             of the form $vt[6],        then sel is 0110
-//             of the form $vt[7],        then sel is 0111
-//             Normal register specifier, then sel is 1011
-//             Constant,                  then sel is 1111
-//
-// VecAcc is the Vector Accumulator.
-//     This accumulator is organized as 8X24 bit (192 bit) register.
-//     This accumulator holds only signed values.
+// -*- C -*-
 
+// Simulator definition for the MIPS MDMX ASE.
+// Copyright (C) 2002, 2010, 2012 Free Software Foundation, Inc.
+// Contributed by Ed Satterthwaite and Chris Demetriou, of 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 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/>.
 
-// Verify that the instruction is valid for the curent Architecture
-// If valid, return the scale (log nr bits) of a vector element
-// as determined by SEL.
+//  Reference: MIPS64 Architecture Volume IV-b:
+//             The MDMX Application-Specific Extension
 
-:function:64,f::int:get_scale:int sel
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-#if 0
-  switch (my_index X STATE_ARCHITECTURE)
-    {
-    }
-#endif
-  switch (sel & 0x7)
-    {
-    case 0:
-    case 2:  
-    case 4:
-    case 6:
-      /* octal byte - ssss0 */
-      return 0;
-    case 1:
-    case 5:
-      /* quad halfword - sss01 */
-      return 1;
-    case 3:
-      /* bi word - ss011 */
-      semantic_illegal (CPU_, cia);
-      return 2;
-    case 7:
-      /* long - ss111 */
-      semantic_illegal (CPU_, cia);
-      return 3;
-    default:
-      abort ();
-      return -1;
-    }
-}
+//  Notes on "format selectors" (FMTSEL):
+//
+//   A selector with final bit 0 indicates OB format.
+//   A selector with final bits 01 indicates QH format.
+//   A selector with final bits 11 has UNPREDICTABLE result per the spec.
+//
+//  Similarly, for the single-bit fields which differentiate between
+//  formats (FMTOP), 0 is OB format and 1 is QH format.
 
+//  If you change this file to add instructions, please make sure that model
+//  "sb1" configurations still build, and that you've added no new
+//  instructions to the "sb1" model.
 
-// Fetch/Store VALUE in ELEMENT of vector register FPR.
-// The the of the element determined by SCALE.
 
-:function:64,f::signed:value_vr:int scale, int fpr, int el
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  switch (FPR_STATE[fpr])
-    {
-    case fmt_uninterpreted:
-      FPR_STATE[fpr] = fmt_long;
-      break;
-    case fmt_long:
-    case fmt_unknown:
-      break;
-    default:
-      sim_io_eprintf (SD, "Vector %d format invalid (PC = 0x%08lx)\n",
-                     fpr, (long) CIA);
-      FPR_STATE[fpr] = fmt_unknown;
-    }
-  switch (scale)
-    {
-    case 0:
-      {
-       signed8 value = *A1_8 (&FGR[fpr], 7 - el);
-       return value;
-      }
-    case 1:
-      {
-       signed16 value = *A2_8 (&FGR[fpr], 3 - el);
-       return value;
-      }
-    default:
-      abort;
-    }
-  return 0;
-}
+// Helper:
+//
+// Check whether MDMX is usable, and if not signal an appropriate exception.
+//
 
-:function:64,f::void:store_vr:int scale, int fpr, int element, signed value
+:function:::void:check_mdmx:instruction_word insn
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
 {
-  switch (FPR_STATE[fpr])
-    {
-    case fmt_uninterpreted:
-      FPR_STATE[fpr] = fmt_long;
-      break;
-    case fmt_long:
-    case fmt_unknown:
-      break;
-    default:
-      sim_io_eprintf (SD, "Vector %d format invalid (PC = 0x%08lx)\n",
-                     fpr, (long) cia);
-      FPR_STATE[fpr] = fmt_unknown;
-    }
-  switch (scale)
-    {
-    case 0:
-      {
-       *A1_8 (&FGR[fpr], 7 - element) = value;
-       break;
-      }
-    case 1:
-      {
-       *A2_8 (&FGR[fpr], 3 - element) = value;
-       break;
-      }
-    default:
-      abort ();
-    }
+  if (! COP_Usable (1))
+    SignalExceptionCoProcessorUnusable (1);
+  if ((SR & (status_MX|status_FR)) != (status_MX|status_FR))
+    SignalExceptionMDMX ();
+  check_u64 (SD_, insn);
 }
 
 
-// Select a value from onr of FGR[VT][ELEMENT], VT and GFR[VT][CONST]
-// according to SEL
+// Helper:
+//
+// Check whether a given MDMX format selector indicates a valid and usable
+// format, and if not signal an appropriate exception.
+//
 
-:function:64,f::unsigned:select_vr:int sel, int vt, int element
+:function:::int:check_mdmx_fmtsel:instruction_word insn, int fmtsel
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
 {
-  switch (sel)
+  switch (fmtsel & 0x03)
     {
-      /* element select - 0xxxx */
-    case 0x00: /* 0 xxx 0 */
+    case 0x00:     /* ob */
     case 0x02:
-    case 0x04:
-    case 0x06:
-    case 0x08:
-    case 0x0a:
-    case 0x0c:
-    case 0x0e:
-      return value_vr (SD_, 0, vt, sel >> 1);
-    case 0x01: /* 0 xx 01 */
-    case 0x05:
-    case 0x09:
-    case 0x0d:
-      return value_vr (SD_, 1, vt, sel >> 2);
-    case 0x03: /* 0 x 011 */
-    case 0x0b:
-      return value_vr (SD_, 2, vt, sel >> 3);
-    case 0x07: /* 0 x 111 */
-    case 0x0f:
-      return value_vr (SD_, 3, vt, sel >> 4);
-
-      /* select vector - 10xxx */
-    case 0x16: /* 10 11 0 */
-      return value_vr (SD_, 0, vt, element);
-    case 0x15: /* 10 1 01 */
-      return value_vr (SD_, 1, vt, element);
-    case 0x13: /* 10  011 */
-      return value_vr (SD_, 2, vt, element);
-    case 0x17: /* 10  111 */
-      return value_vr (SD_, 3, vt, element);
-
-      /* select immediate - 11xxx */
-    case 0x1e: /* 11 11 0 */
-    case 0x1d: /* 11 1 01 */
-    case 0x1b: /* 11  011 */
-    case 0x1f: /* 11  111 */
-      return vt;
-
+    case 0x01:     /* qh */
+      return 1;
+    case 0x03:     /* UNPREDICTABLE */
+      SignalException (ReservedInstruction, insn);
+      return 0;
     }
   return 0;
 }
 
 
-// Saturate (clamp) the signed value to (8 << SCALE) bits.
+// Helper:
+//
+// Check whether a given MDMX format bit indicates a valid and usable
+// format, and if not signal an appropriate exception.
+//
 
-:function:64,f::signed:Clamp:int scale, signed value
+:function:::int:check_mdmx_fmtop:instruction_word insn, int fmtop
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
 {
-  switch (scale)
+  switch (fmtop & 0x01)
     {
-    case 0:
-      {
-       if (value != (signed8) value)
-         {
-           if (value > 0)
-             return 0x7f;
-           else
-             return 0x80;
-         }
-       return value & 0xff;
-      }
-    case 1:
-      {
-       if (value != (signed16) value)
-         {
-           if (value > 0)
-              return 0x7fff;
-           else
-              return 0x8000;
-         }
-       return value & 0xffff;
-      }
-    default:
-      abort ();
-      return 0;
+    case 0x00:     /* ob */
+    case 0x01:     /* qh */
+      return 1;
     }
+  return 0;
 }
 
 
-// Access a single bit of the floating point CC register.
-
-:function:64,f::void:store_cc:int i, int value
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  SETFCC (i, value);
-}
-
-:function:64,f::int:value_cc:int i
+:%s::::FMTSEL:int fmtsel
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  return GETFCC (i);
+  if ((fmtsel & 0x1) == 0)
+    return "ob";
+  else if ((fmtsel & 0x3) == 1)
+    return "qh";
+  else
+    return "?";
 }
 
 
-//  Read/write the accumulator
-
-:function:64,f::signed64:value_acc:int scale, int element
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  signed64 value = 0;
-  switch (scale)
-    {
-    case 0:
-      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
-      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
-      value |= (signed64) (signed8) CPU->acc [element * 3 + 2] << 16;
-      break;
-    case 1:
-      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
-      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
-      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 2] << 16;
-      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 3] << 24;
-      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 4] << 32;
-      value |= (signed64) (signed8) CPU->acc [element * 3 + 5] << 40;
-      break;
-    }
-  return value;
-}
-
-:function:64,f::void:store_acc:int scale, int element, signed64 value
+:%s::::FMTOP:int fmtop
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  switch (scale)
+  switch (fmtop)
     {
-    case 0:
-      CPU->acc [element * 3 + 0] = value >> 0;
-      CPU->acc [element * 3 + 1] = value >> 8;
-      CPU->acc [element * 3 + 2] = value >> 16;
-      break;
-    case 1:
-      CPU->acc [element * 3 + 0] = value >> 0;
-      CPU->acc [element * 3 + 1] = value >> 8;
-      CPU->acc [element * 3 + 2] = value >> 16;
-      CPU->acc [element * 3 + 3] = value >> 24;
-      CPU->acc [element * 3 + 4] = value >> 32;
-      CPU->acc [element * 3 + 5] = value >> 40;
-      break;
+    case 0: return "ob";
+    case 1: return "qh";
+    default: return "?";
     }
 }
 
 
-// Formatting
-
-:%s:64,f:::VT:int sel, int vt
+:%s::::SHOP:int shop
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  static char buf[20];
-  if (sel < 8)
-    sprintf (buf, "v%d[%d]", vt, sel);
-  else if (sel == 0x13)
-    sprintf (buf, "v%d", vt);
-  else if (sel == 0x1f)
-    sprintf (buf, "%d", vt);
+  if ((shop & 0x11) == 0x00)
+    switch ((shop >> 1) & 0x07)
+      {
+      case 3:  return "upsl.ob";
+      case 4:  return "pach.ob";
+      case 6:  return "mixh.ob";
+      case 7:  return "mixl.ob";
+      default: return "?";
+      }
+  else if ((shop & 0x03) == 0x01)
+    switch ((shop >> 2) & 0x07)
+      {
+      case 0:  return "mixh.qh";
+      case 1:  return "mixl.qh";
+      case 2:  return "pach.qh";
+      case 4:  return "bfla.qh";
+      case 6:  return "repa.qh";
+      case 7:  return "repb.qh";
+      default: return "?";
+      }
   else
-    sprintf (buf, "(invalid)");
-  return buf;
+    return "?";
 }
 
-:%s:64,f:::SEL:int sel
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  switch (sel & 7)
-    {
-    case 0:
-    case 2:
-    case 4:
-    case 6:
-      return "ob";
-    case 1:
-    case 5:
-      return "qh";
-    case 3:
-      return "bw";
-    default:
-      return "l";
-    }
-}
-
-
-// Vector Add.
 
-010010,5.SEL,5.VT,5.VS,5.VD,001011::64,f::ADD.fmt
-"add.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,001011:MDMX:64::ADD.fmt
+"add.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             Clamp (SD_, scale,
-                    (value_vr (SD_, scale, VS, i)
-                     + select_vr (SD_, SEL, VT, i))));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Add(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-// Accumulate Vector Add
-
-010010,5.SEL,5.VT,5.VS,1,0000,110111::64,f::ADDA.fmt
-"adda.%s<SEL> v<VD>, v<VS>"
+011110,5.FMTSEL,5.VT,5.VS,0,0000,110111:MDMX:64::ADDA.fmt
+"adda.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, i,
-              (value_acc (SD_, scale, i)
-               + (signed64) value_vr (SD_, scale, VS, i)
-               + (signed64) select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_AddA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
 }
 
 
-// Load Vector Add
-
-010010,5.SEL,5.VT,5.VS,0,0000,110111::64,f::ADDA.fmt
-"addl.%s<SEL> v<VD>, v<VS>"
+011110,5.FMTSEL,5.VT,5.VS,1,0000,110111:MDMX:64::ADDL.fmt
+"addl.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, i,
-              ((signed64) value_vr (SD_, scale, VS, i)
-               + (signed64) select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_AddL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
 }
 
 
-
-// Vector align, Constant Alignment
-
-:function:64,f::void:ByteAlign:int vd, int imm, int vs, int vt
+011110,00,3.IMM,5.VT,5.VS,5.VD,0110,1.FMTOP,0:MDMX:64::ALNI.fmt
+"alni.%s<FMTOP> v<VD>, v<VS>, v<VT>, <IMM>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int s = imm * 8;
-  unsigned64 rs = ValueFPR (vs, fmt_long);
-  unsigned64 rt = ValueFPR (vt, fmt_long);
-  unsigned64 rd;
-  if (BigEndianCPU)
-    {
-      /* (vs || vt) [127 - S .. 64 - S] */
-      if (s == 0)
-       rd = rs;
-      else
-       rd = (MOVED64 (rs, 64 - s, 0, 63, s)
-             | EXTRACTED64 (rt, 63, 64 - s));
-    }
-  else
-    {
-      /* (vs || vt) [63 + S .. S] */
-      if (s == 0)
-       rd = rt;
-      else
-       rd = (MOVED64 (rs, s, 0, 63, 64 - s)
-             | EXTRACTED64 (rt, 63, s));
-    }
-  StoreFPR (vd, fmt_long, rd);
+  unsigned64 result;
+  int s;
+  check_mdmx (SD_, instruction_0);
+  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
+  s = (IMM << 3);
+  result = ValueFPR(VS,fmt_mdmx) << s;
+  if (s != 0)  // x86 gcc treats >> 64 as >> 0
+    result |= ValueFPR(VT,fmt_mdmx) >> (64 - s);
+  StoreFPR(VD,fmt_mdmx,result);
 }
 
-010010,00,3.IMM,5.VT,5.VS,5.VD,0110,X,0::64,f::ALNI.fmt
-"alni.%s<FMT#X> v<VD>, v<VS>, v<VT>, <IMM>"
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  ByteAlign (SD_, VD, IMM, VS, VT);
-}
-
-
 
-// Vector align, Variable Alignment
-
-010010,5.RS,5.VT,5.VS,5.VD,0110,X,1::64,f::ALNV.fmt
-"alnv.%s<FMT#X> v<VD>, v<VS>, v<VT>, r<RS>"
+011110,5.RS,5.VT,5.VS,5.VD,0110,1.FMTOP,1:MDMX:64::ALNV.fmt
+"alnv.%s<FMTOP> v<VD>, v<VS>, v<VT>, r<RS>"
 *mdmx:
+*sb1:
 {
-  ByteAlign (SD_, VD, GPR[RS], VS, VT);
+  unsigned64 result;
+  int s;
+  check_mdmx (SD_, instruction_0);
+  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
+  s = ((GPR[RS] & 0x7) << 3);
+  result = ValueFPR(VS,fmt_mdmx) << s;
+  if (s != 0)  // x86 gcc treats >> 64 as >> 0
+    result |= ValueFPR(VT,fmt_mdmx) >> (64 - s);
+  StoreFPR(VD,fmt_mdmx,result);
 }
 
 
-
-// Vector And.
-
-010010,5.SEL,5.VT,5.VS,5.VD,001100::64,f::AND.fmt
-"and.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,001100:MDMX:64::AND.fmt
+"and.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             (value_vr (SD_, scale, VS, i)
-              & select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_And(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Vector Compare Equal.
-
-
-010010,5.SEL,5.VT,5.VS,00000,000001::64,f::C.EQ.fmt
-"c.EQ.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,00000,000001:MDMX:64::C.EQ.fmt
+"c.eq.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_cc (SD_, i,
-             (value_vr (SD_, scale, VS, i)
-              == select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_Comp(ValueFPR(VS,fmt_mdmx),MX_C_EQ,VT,FMTSEL);
 }
 
 
-
-// Vector Compare Less Than or Equal.
-
-010010,5.SEL,5.VT,5.VS,00000,000101::64,f::C.LE.fmt
-"c.le.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,00000,000101:MDMX:64::C.LE.fmt
+"c.le.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_cc (SD_, i,
-             (value_vr (SD_, scale, VS, i)
-              <= select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_Comp(ValueFPR(VS,fmt_mdmx),MX_C_LT|MX_C_EQ,VT,FMTSEL);
 }
 
 
-
-// Vector Compare Less Than.
-
-010010,5.SEL,5.VT,5.VS,00000,000100::64,f::C.LT.fmt
-"c.lt.%s<SEL> v<VS>, %s<VT#SEL,VT>"
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_cc (SD_, i,
-             (value_vr (SD_, scale, VS, i)
-              < select_vr (SD_, SEL, VT, i)));
-}
-
-
-
-// Vector Maximum.
-
-:function:64,f::signed:Maxi:int scale, signed l, signed r
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  if (l < r)
-    return r;
-  else
-    return l;
-}
-
-010010,5.SEL,5.VT,5.VS,5.VD,000111::64,f::MAX.fmt
-"max.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,00000,000100:MDMX:64::C.LT.fmt
+"c.lt.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             Maxi (SD_, scale,
-                   value_vr (SD_, scale, VS, i),
-                   select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_Comp(ValueFPR(VS,fmt_mdmx),MX_C_LT,VT,FMTSEL);
 }
 
 
-
-// Vector Minimum.
-
-:function:64,f::signed:Mini:int scale, signed l, signed r
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  if (l < r)
-    return l;
-  else
-    return r;
-}
-
-010010,5.SEL,5.VT,5.VS,5.VD,000110::64,f::MIN.fmt
-"min.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,000111:MDMX:64::MAX.fmt
+"max.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             Mini (SD_, scale,
-                   value_vr (SD_, scale, VS, i),
-                   select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Max(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Vector Sign.
-
-:function:64,f::signed:Sign:int scale, signed l, signed r
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  if (l >= 0)
-    return r;
-  else if (r >= 0)
-    return -r;
-  else
-    {
-      /* watch for overflow of MIN_INT */
-      switch (scale)
-       {
-       case 0:
-         if ((r & 0xff) == 0x80)
-           return 0x7ff;
-         else
-           return -r;
-       case 1:
-         if ((r & 0xffff) == 0x8000)
-           return 0x7ffff;
-         else
-           return -r;
-       default:
-         abort ();
-       }
-      return -r;
-    }
-}
-
-010010,5.SEL,5.VT,5.VS,5.VD,000110::64,f::MSGN.fmt
-"msgn.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,000110:MDMX:64::MIN.fmt
+"min.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  if ((SEL & 1) != 1)
-    /* only QH allowed */
-    semantic_illegal (sd, cia);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             Sign (SD_, scale,
-                   value_vr (SD_, scale, VS, i),
-                   select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Min(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Vector Multiply.
-
-010010,5.SEL,5.VT,5.VS,5.VD,110000::64,f::MUL.fmt
-"mul.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,3.SEL,01,5.VT,5.VS,5.VD,000000:MDMX:64::MSGN.QH
+"msgn.qh v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             Clamp (SD_, scale,
-                    (value_vr (SD_, scale, VS, i)
-                     * select_vr (SD_, SEL, VT, i))));
+  check_mdmx (SD_, instruction_0);
+  StoreFPR(VD,fmt_mdmx,MX_Msgn(ValueFPR(VS,fmt_mdmx),VT,qh_fmtsel(SEL)));
 }
 
 
-
-// Accumulate Vector Multiply
-
-010010,5.SEL,5.VT,5.VS,00000,110011::64,f::MULA.fmt
-"mula.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,110000:MDMX:64::MUL.fmt
+"mul.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, i,
-              (value_acc (SD_, scale, i)
-               + ((signed64) value_vr (SD_, scale, VS, i)
-                  * (signed64) select_vr (SD_, SEL, VT, i))));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Mul(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Add Vector Multiply to Accumulator.
-
-010010,5.SEL,5.VT,5.VS,10000,110011::64,f::MULL.fmt
-"mull.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,0,0000,110011:MDMX:64::MULA.fmt
+"mula.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, i,
-              ((signed64) value_vr (SD_, scale, VS, i)
-               * (signed64) select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_MulA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
 }
 
 
-
-// Subtract Vector Multiply from Accumulator
-
-010010,5.SEL,5.VT,5.VS,00000,110010::64,f::MULS.fmt
-"muls.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,1,0000,110011:MDMX:64::MULL.fmt
+"mull.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, i,
-              (value_acc (SD_, scale, i)
-               - ((signed64) value_vr (SD_, scale, VS, i)
-                  * (signed64) select_vr (SD_, SEL, VT, i))));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_MulL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
 }
 
 
-
-// Load Negative Vector Multiply
-
-010010,5.SEL,5.VT,5.VS,10000,110010::64,f::MULSL.fmt
-"mulsl.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,0,0000,110010:MDMX:64::MULS.fmt
+"muls.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, i,
-              - ((signed64) value_vr (SD_, scale, VS, i)
-                 * (signed64) select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_MulS(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
 }
 
 
-
-// Vector Nor.
-
-010010,5.SEL,5.VT,5.VS,5.VD,001111::64,f::NOR.fmt
-"nor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,1,0000,110010:MDMX:64::MULSL.fmt
+"mulsl.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             ~(value_vr (SD_, scale, VS, i)
-               | select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_MulSL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
 }
 
 
-
-// Vector Or.
-
-010010,5.SEL,5.VT,5.VS,5.VD,001110::64,f::OR.fmt
-"or.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,001111:MDMX:64::NOR.fmt
+"nor.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             (value_vr (SD_, scale, VS, i)
-              | select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Nor(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Select Vector Elements - False
-
-010010,5.SEL,5.VT,5.VS,5.VD,000010::64,f::PICKF.fmt
-"pickf.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,001110:MDMX:64::OR.fmt
+"or.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             (value_cc (SD_, i) == 0
-              ? value_vr (SD_, scale, VS, i)
-              : select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Or(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Select Vector Elements - True
-
-010010,5.SEL,5.VT,5.VS,5.VD,000011::64,f::PICKT.fmt
-"pickt.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,000010:MDMX:64::PICKF.fmt
+"pickf.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             (value_cc (SD_, i) != 0
-              ? value_vr (SD_, scale, VS, i)
-              : select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Pick(0,ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Scale, Round and Clamp Accumulator
-
-:%s:64,f:::RND:int rnd
+011110,5.FMTSEL,5.VT,5.VS,5.VD,000011:MDMX:64::PICKT.fmt
+"pickt.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  switch (rnd)
-    {
-    case 0:
-      return "zu";
-    case 1:
-      return "nau";
-    case 2:
-      return "neu";
-    case 4:
-      return "rzs";
-    case 5:
-      return "nas";
-    case 6:
-      return "nes";
-    default:
-      return "(invalid)";
-    }
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Pick(1,ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
-:function:64,f::signed:ScaleRoundClamp:int scale, int rnd, signed val, signed shift
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  int halfway = (1 << (shift - 1));
-  /* must be positive */
-  if (shift < 0)
-    return 0;
-  /* too much shift? */
-  switch (scale)
-    {
-    case 0:
-      if (shift >= 24)
-       return 0;
-      break;
-    case 1:
-      if (shift >= 48)
-       return 0;
-      break;
-    default:
-      abort ();
-    }
-  /* round */
-  switch (rnd & 3)
-    {
-    case 0: /* round towards zero */
-      break;
-    case 1: /* nearest, halfaway rounds away from zero */
-      if (val >= 0)
-       val += halfway;
-      else
-       val -= halfway;
-      break;
-    case 2: /* nearest, halfway rounds to even! */
-      if (val >= 0)
-       {
-         if (val & (halfway << 1))
-           val += halfway;
-         else
-           val += (halfway - 1);
-       }
-      else
-       {
-         if (val & (halfway << 1))
-           val -= halfway;
-         else
-           val -= (halfway - 1);
-       }
-    default:
-      abort ();
-    }
-  /* shift */
-  val >>= shift;
-  /* clamp */
-  switch (rnd & 4)
-    {
-    case 0:
-      /* unsigned clamp */
-      if (val < 0)
-       val = 0;
-      else
-       switch (scale)
-         {
-         case 0:
-           if (val > 0xff)
-             val = 0xff;
-           break;
-         case 1:
-           if (val > 0xffff)
-             val = 0xffff;
-           break;
-         }
-      break;
-    case 8:
-      /* normal signed clamp */
-      val = Clamp (_SD, scale, val);
-      break;
-    }
-  return val;
-}
 
-010010,5.SEL,5.VT,00000,5.VD,100,3.RND::64,f::Rx.fmt
-"r%s<RND>.%s<SEL> v<VD>, v<VT>"
+011110,1000,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACH.fmt
+"rach.%s<FMTOP> v<VD>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             ScaleRoundClamp (SD_, scale, RND,
-                              value_acc (SD_, scale, i),
-                              select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
+  StoreFPR(VD,fmt_mdmx,MX_RAC(MX_RAC_H,FMTOP));
 }
 
 
-
-// Vector Read  Accumulator Low.
-
-010010,0000,1.SEL,00000,00000,5.VD,111111::64,f::RACL.fmt
-"racl.%s<SEL> v<VD>"
+011110,0000,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACL.fmt
+"racl.%s<FMTOP> v<VD>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             EXTRACTED (value_acc (SD_, scale, i),
-                        (8 << scale) - 1,
-                        0));
+  check_mdmx (SD_, instruction_0);
+  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
+  StoreFPR(VD,fmt_mdmx,MX_RAC(MX_RAC_L,FMTOP));
 }
 
 
-
-// Vector Read  Accumulator Middle.
-
-010010,0100,1.SEL,00000,00000,5.VD,111111::64,f::RACM.fmt
-"racm.%s<SEL> v<VD>"
+011110,0100,1.FMTOP,00000,00000,5.VD,111111:MDMX:64::RACM.fmt
+"racm.%s<FMTOP> v<VD>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             EXTRACTED (value_acc (SD_, scale, i),
-                        (16 << scale) - 1,
-                        (8 << scale) - 0));
+  check_mdmx (SD_, instruction_0);
+  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
+  StoreFPR(VD,fmt_mdmx,MX_RAC(MX_RAC_M,FMTOP));
 }
 
 
-
-// Vector Read  Accumulator High.
-
-010010,1000,1.SEL,00000,00000,5.VD,111111::64,f::RACH.fmt
-"rach.%s<SEL> v<VD>"
+011110,3.SEL,01,5.VT,00000,5.VD,100101:MDMX:64::RNAS.QH
+"rnas.qh v<VD>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             EXTRACTED (value_acc (SD_, scale, i),
-                        (24 << scale) - 1,
-                        (16 << scale) - 0));
+  check_mdmx (SD_, instruction_0);
+  StoreFPR(VD,fmt_mdmx,MX_RNAS(VT,qh_fmtsel(SEL)));
 }
 
 
-
-// Vector Element Shuffle.
-
-010010,0000,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPUH.fmt
-"shfl.upuh.%s<SEL> v<VD>, v<VS>, <VT>"
+011110,5.FMTSEL,5.VT,00000,5.VD,100001:MDMX:64::RNAU.fmt
+"rnau.%s<FMTSEL> v<VD>, v<VT>"
 *mdmx:
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < 4; i++)
-    {
-      store_vr (SD_, 1, VD, i,
-               value_vr (SD_, 0, VS, i + 4) & 0xff);
-    }
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_RNAU(VT,FMTSEL));
 }
 
-010010,0001,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPUL.fmt
-"shfl.upul.%s<SEL> v<VD>, v<VS>, <VT>"
-*mdmx:
-{
-  int i;
-  for (i = 0; i < 4; i++)
-    {
-      store_vr (SD_, 1, VD, i,
-               value_vr (SD_, 0, VS, i) & 0xff);
-    }
-}
 
-010010,0000,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPSH.fmt
-"shfl.upsh.%s<SEL> v<VD>, v<VS>, <VT>"
+011110,3.SEL,01,5.VT,00000,5.VD,100110:MDMX:64::RNES.QH
+"rnes.qh v<VD>, v<VT>"
 *mdmx:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < 4; i++)
-    {
-      store_vr (SD_, 1, VD, i,
-               value_vr (SD_, 0, VS, i + 4));
-    }
+  check_mdmx (SD_, instruction_0);
+  StoreFPR(VD,fmt_mdmx,MX_RNES(VT,qh_fmtsel(SEL)));
 }
 
-010010,0001,0,5.VT,5.VS,5.VD,011111::64,f::SHFL.UPSL.fmt
-"shfl.upsl.%s<SEL> v<VD>, v<VS>, <VT>"
-*mdmx:
-{
-  int i;
-  for (i = 0; i < 4; i++)
-    {
-      store_vr (SD_, 1, VD, i,
-               value_vr (SD_, 0, VS, i));
-    }
-}
 
-010010,0100,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.PACH.fmt
-"shfl.pach.%s<SEL> v<VD>, v<VS>, <VT>"
+011110,5.FMTSEL,5.VT,00000,5.VD,100010:MDMX:64::RNEU.fmt
+"rneu.%s<FMTSEL> v<VD>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (4 >> scale); i++)
-    {
-      store_vr (SD_, scale, VD, i,
-               value_vr (SD_, scale, VT, i * 2 + 1));
-      store_vr (SD_, scale, VD, 1 + (4 >> scale),
-               value_vr (SD_, scale, VS, i * 2 + 1));
-    }
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_RNEU(VT,FMTSEL));
 }
 
-010010,0101,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.PACL.fmt
-"shfl.pacl.%s<SEL> v<VD>, v<VS>, <VT>"
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (4 >> scale); i++)
-    {
-      store_vr (SD_, scale, VD, i,
-               value_vr (SD_, scale, VT, i * 2));
-      store_vr (SD_, scale, VD, 1 + (4 >> scale),
-               value_vr (SD_, scale, VS, i * 2));
-    }
-}
 
-010010,0110,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.MIXH.fmt
-"shfl.mixh.%s<SEL> v<VD>, v<VS>, <VT>"
+011110,3.SEL,01,5.VT,00000,5.VD,100100:MDMX:64::RZS.QH
+"rzs.qh v<VD>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (4 >> scale); i++)
-    {
-      store_vr (SD_, scale, VD, i * 2,
-               value_vr (SD_, scale, VT, i + (4 >> scale)));
-      store_vr (SD_, scale, VD, i * 2 + 1,
-               value_vr (SD_, scale, VS, i + (4 >> scale)));
-    }
+  check_mdmx (SD_, instruction_0);
+  StoreFPR(VD,fmt_mdmx,MX_RZS(VT,qh_fmtsel(SEL)));
 }
 
-010010,0111,1.SEL,5.VT,5.VS,5.VD,011111::64,f::SHFL.MIXL.fmt
-"shfl.mixl.%s<SEL> v<VD>, v<VS>, <VT>"
-*mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
-{
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (4 >> scale); i++)
-    {
-      store_vr (SD_, scale, VD, i * 2,
-               value_vr (SD_, scale, VT, i));
-      store_vr (SD_, scale, VD, i * 2 + 1,
-               value_vr (SD_, scale, VS, i));
-    }
-}
 
-010010,100,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.BFLA.fmt
-"shfl.bfla.qh v<VD>, v<VS>, <VT>"
+011110,5.FMTSEL,5.VT,00000,5.VD,100000:MDMX:64::RZU.fmt
+"rzu.%s<FMTSEL> v<VD>, v<VT>"
 *mdmx:
+*sb1:
 {
-  store_vr (SD_, 1, VD, 0,
-           value_vr (SD_, 1, VT, 1));
-  store_vr (SD_, 1, VD, 1,
-           value_vr (SD_, 1, VS, 0));
-  store_vr (SD_, 1, VD, 2,
-           value_vr (SD_, 1, VT, 3));
-  store_vr (SD_, 1, VD, 3,
-           value_vr (SD_, 1, VS, 2));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_RZU(VT,FMTSEL));
 }
 
-010010,101,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.BFLB.fmt
-"shfl.bflb.qh v<VD>, v<VS>, <VT>"
-*mdmx:
-{
-  store_vr (SD_, 1, VD, 0,
-           value_vr (SD_, 1, VT, 3));
-  store_vr (SD_, 1, VD, 1,
-           value_vr (SD_, 1, VS, 2));
-  store_vr (SD_, 1, VD, 2,
-           value_vr (SD_, 1, VT, 1));
-  store_vr (SD_, 1, VD, 3,
-           value_vr (SD_, 1, VS, 0));
-}
-
-010010,101,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.REPA.fmt
-"shfl.repa.qh v<VD>, v<VS>, <VT>"
-*mdmx:
-{
-  store_vr (SD_, 1, VD, 0,
-           value_vr (SD_, 1, VT, 2));
-  store_vr (SD_, 1, VD, 1,
-           value_vr (SD_, 1, VT, 3));
-  store_vr (SD_, 1, VD, 2,
-           value_vr (SD_, 1, VS, 2));
-  store_vr (SD_, 1, VD, 3,
-           value_vr (SD_, 1, VS, 3));
-}
 
-010010,101,01,5.VT,5.VS,5.VD,011111::64,f::SHFL.REPB.fmt
-"shfl.repb.qh v<VD>, v<VS>, <VT>"
+011110,5.SHOP,5.VT,5.VS,5.VD,011111:MDMX:64::SHFL.op.fmt
+"shfl.%s<SHOP> v<VD>, v<VS>, v<VT>"
 *mdmx:
+*sb1:
 {
-  store_vr (SD_, 1, VD, 0,
-           value_vr (SD_, 1, VT, 0));
-  store_vr (SD_, 1, VD, 1,
-           value_vr (SD_, 1, VT, 1));
-  store_vr (SD_, 1, VD, 2,
-           value_vr (SD_, 1, VS, 0));
-  store_vr (SD_, 1, VD, 3,
-           value_vr (SD_, 1, VS, 1));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, SHOP))
+    StoreFPR(VD,fmt_mdmx,MX_SHFL(SHOP,ValueFPR(VS,fmt_mdmx),ValueFPR(VT,fmt_mdmx)));
 }
 
 
-
-// Vector Shift Left Logical
-
-010010,5.SEL,5.VT,5.VS,5.VD,010000::64,f::SLL.fmt
-"sll.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,010000:MDMX:64::SLL.fmt
+"sll.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  int mask = (4 << scale) - 1;
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             (value_vr (SD_, scale, VS, i)
-              << (select_vr (SD_, SEL, VT, i) & mask)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_ShiftLeftLogical(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Vector Shift Right Arithmetic
-
-010010,5.SEL,5.VT,5.VS,5.VD,010011::64,f::SRA.fmt
-"sra.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,3.SEL,01,5.VT,5.VS,5.VD,010011:MDMX:64::SRA.QH
+"sra.qh v<VD>, v<VS>, v<VT>"
 *mdmx:
 {
-  int i;
-  int mask = (4 << scale) - 1;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             (value_vr (SD_, scale, VS, i)
-              >> (select_vr (SD_, SEL, VT, i) & mask)));
+  check_mdmx (SD_, instruction_0);
+  StoreFPR(VD,fmt_mdmx,MX_ShiftRightArith(ValueFPR(VS,fmt_mdmx),VT,qh_fmtsel(SEL)));
 }
 
 
-
-// Vector Shift Right Logical.
-
-010010,5.SEL,5.VT,5.VS,5.VD,010010::64,f::SRL.fmt
-"srl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,010010:MDMX:64::SRL.fmt
+"srl.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  int mask = (4 << scale) - 1;
-  int zeros = (1 << (8 << scale)) - 1;
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             ((value_vr (SD_, scale, VS, i) & zeros)
-              >> (select_vr (SD_, SEL, VT, i) & mask)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_ShiftRightLogical(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Vector Subtract.
-
-010010,5.SEL,5.VT,5.VS,5.VD,001010::64,f::SUB.fmt
-"sub.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,001010:MDMX:64::SUB.fmt
+"sub.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             (value_vr (SD_, scale, VS, i)
-              - select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Sub(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }
 
 
-
-// Accumulate Vector Difference
-
-010010,5.SEL,5.VT,5.VS,0,0000,110110::64,f::SUBA.fmt
-"suba.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,0,0000,110110:MDMX:64::SUBA.fmt
+"suba.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, VD, i,
-              (value_acc (SD, scale, i)
-               + (signed64) value_vr (SD_, scale, VS, i)
-               - (signed64) select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_SubA(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
 }
 
 
-
-// Load Vector Difference
-
-010010,5.SEL,5.VT,5.VS,1,0000,110110::64,f::SUBL.fmt
-"subl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,1,0000,110110:MDMX:64::SUBL.fmt
+"subl.%s<FMTSEL> v<VS>, v<VT>"
 *mdmx:
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, VD, i,
-              ((signed64) value_vr (SD_, scale, VS, i)
-               - (signed64) select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    MX_SubL(ValueFPR(VS,fmt_mdmx),VT,FMTSEL);
 }
 
 
-
-// Write Accumulator High.
-
-010010,1000,1.SEL,00000,5.VS,00000,111110::64,f::WACH.fmt
-"wach.%s<SEL> v<VS>"
+011110,1000,1.FMTOP,00000,5.VS,00000,111110:MDMX:64::WACH.fmt
+"wach.%s<FMTOP> v<VS>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, i,
-              (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
-               | MASKED (value_acc (SD_, scale, i), (16 << scale) - 1, 0)));
+  check_mdmx (SD_, instruction_0);
+  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
+  MX_WACH(FMTOP,ValueFPR(VS,fmt_mdmx));
 }
 
 
-
-// Vector Write Accumulator Low.
-
-010010,0000,1.SEL,5.VT,5.VS,00000,111110::64,f::WACL.fmt
-"wacl.%s<SEL> v<VS>, <VT>"
+011110,0000,1.FMTOP,5.VT,5.VS,00000,111110:MDMX:64::WACL.fmt
+"wacl.%s<FMTOP> v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_acc (SD_, scale, i,
-              (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
-               | MASKED (value_vr (SD_, scale, VT, i),
-                         (16 << scale) - 1, 0)));
+  check_mdmx (SD_, instruction_0);
+  check_mdmx_fmtop (SD_, instruction_0, FMTOP);
+  MX_WACL(FMTOP,ValueFPR(VS,fmt_mdmx),ValueFPR(VT,fmt_mdmx));
 }
 
 
-
-// Vector Xor.
-
-010010,5.SEL,5.VT,5.VS,5.VD,001101::64,f::XOR.fmt
-"xor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+011110,5.FMTSEL,5.VT,5.VS,5.VD,001101:MDMX:64::XOR.fmt
+"xor.%s<FMTSEL> v<VD>, v<VS>, v<VT>"
 *mdmx:
-// start-sanitize-vr5400
-*vr5400:
-// end-sanitize-vr5400
+*sb1:
 {
-  int i;
-  int scale = get_scale (SD_, SEL);
-  for (i = 0; i < (8 >> scale); i++)
-    store_vr (SD_, scale, VD, i,
-             (value_vr (SD_, scale, VS, i)
-              ^ select_vr (SD_, SEL, VT, i)));
+  check_mdmx (SD_, instruction_0);
+  if (check_mdmx_fmtsel (SD_, instruction_0, FMTSEL))
+    StoreFPR(VD,fmt_mdmx,MX_Xor(ValueFPR(VS,fmt_mdmx),VT,FMTSEL));
 }