/* ppc-opc.c -- PowerPC opcode list
- Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002
+ Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support
-This file is part of GDB, GAS, and the GNU binutils.
+ This file is part of GDB, GAS, and the GNU binutils.
-GDB, GAS, and the GNU binutils are free software; you can redistribute
-them and/or modify them 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.
+ GDB, GAS, and the GNU binutils are free software; you can redistribute
+ them and/or modify them 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.
-GDB, GAS, and the GNU binutils are distributed in the hope that they
-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.
+ GDB, GAS, and the GNU binutils are distributed in the hope that they
+ 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 file; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this file; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
#include <stdio.h>
#include "sysdep.h"
\f
/* Local insertion and extraction functions. */
-static unsigned long insert_bat
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_bat
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_bba
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_bba
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_bd
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_bd
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_bdm
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_bdm
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_bdp
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_bdp
- PARAMS ((unsigned long, int, int *));
-static int valid_bo
- PARAMS ((long, int));
-static unsigned long insert_bo
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_bo
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_boe
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_boe
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_ds
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_ds
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_de
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_de
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_des
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_des
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_li
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_li
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_mbe
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_mbe
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_mb6
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_mb6
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_nb
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_nb
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_nsi
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_nsi
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_ral
- PARAMS ((unsigned long, long, int, const char **));
-static unsigned long insert_ram
- PARAMS ((unsigned long, long, int, const char **));
-static unsigned long insert_ras
- PARAMS ((unsigned long, long, int, const char **));
-static unsigned long insert_rbs
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_rbs
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_sh6
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_sh6
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_spr
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_spr
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_tbr
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_tbr
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_ev2
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_ev2
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_ev4
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_ev4
- PARAMS ((unsigned long, int, int *));
-static unsigned long insert_ev8
- PARAMS ((unsigned long, long, int, const char **));
-static long extract_ev8
- PARAMS ((unsigned long, int, int *));
+static unsigned long insert_bat (unsigned long, long, int, const char **);
+static long extract_bat (unsigned long, int, int *);
+static unsigned long insert_bba (unsigned long, long, int, const char **);
+static long extract_bba (unsigned long, int, int *);
+static unsigned long insert_bd (unsigned long, long, int, const char **);
+static long extract_bd (unsigned long, int, int *);
+static unsigned long insert_bdm (unsigned long, long, int, const char **);
+static long extract_bdm (unsigned long, int, int *);
+static unsigned long insert_bdp (unsigned long, long, int, const char **);
+static long extract_bdp (unsigned long, int, int *);
+static int valid_bo (long, int);
+static unsigned long insert_bo (unsigned long, long, int, const char **);
+static long extract_bo (unsigned long, int, int *);
+static unsigned long insert_boe (unsigned long, long, int, const char **);
+static long extract_boe (unsigned long, int, int *);
+static unsigned long insert_dq (unsigned long, long, int, const char **);
+static long extract_dq (unsigned long, int, int *);
+static unsigned long insert_ds (unsigned long, long, int, const char **);
+static long extract_ds (unsigned long, int, int *);
+static unsigned long insert_de (unsigned long, long, int, const char **);
+static long extract_de (unsigned long, int, int *);
+static unsigned long insert_des (unsigned long, long, int, const char **);
+static long extract_des (unsigned long, int, int *);
+static unsigned long insert_fxm (unsigned long, long, int, const char **);
+static long extract_fxm (unsigned long, int, int *);
+static unsigned long insert_li (unsigned long, long, int, const char **);
+static long extract_li (unsigned long, int, int *);
+static unsigned long insert_mbe (unsigned long, long, int, const char **);
+static long extract_mbe (unsigned long, int, int *);
+static unsigned long insert_mb6 (unsigned long, long, int, const char **);
+static long extract_mb6 (unsigned long, int, int *);
+static unsigned long insert_nb (unsigned long, long, int, const char **);
+static long extract_nb (unsigned long, int, int *);
+static unsigned long insert_nsi (unsigned long, long, int, const char **);
+static long extract_nsi (unsigned long, int, int *);
+static unsigned long insert_ral (unsigned long, long, int, const char **);
+static unsigned long insert_ram (unsigned long, long, int, const char **);
+static unsigned long insert_raq (unsigned long, long, int, const char **);
+static unsigned long insert_ras (unsigned long, long, int, const char **);
+static unsigned long insert_rbs (unsigned long, long, int, const char **);
+static long extract_rbs (unsigned long, int, int *);
+static unsigned long insert_rsq (unsigned long, long, int, const char **);
+static unsigned long insert_rtq (unsigned long, long, int, const char **);
+static unsigned long insert_sh6 (unsigned long, long, int, const char **);
+static long extract_sh6 (unsigned long, int, int *);
+static unsigned long insert_spr (unsigned long, long, int, const char **);
+static long extract_spr (unsigned long, int, int *);
+static unsigned long insert_tbr (unsigned long, long, int, const char **);
+static long extract_tbr (unsigned long, int, int *);
+static unsigned long insert_ev2 (unsigned long, long, int, const char **);
+static long extract_ev2 (unsigned long, int, int *);
+static unsigned long insert_ev4 (unsigned long, long, int, const char **);
+static long extract_ev4 (unsigned long, int, int *);
+static unsigned long insert_ev8 (unsigned long, long, int, const char **);
+static long extract_ev8 (unsigned long, int, int *);
\f
/* The operands table.
#define DES DE + 1
{ 14, 0, insert_des, extract_des, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
+ /* The DQ field in a DQ form instruction. This is like D, but the
+ lower four bits are forced to zero. */
+#define DQ DES + 1
+ { 16, 0, insert_dq, extract_dq,
+ PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DQ },
+
/* The DS field in a DS form instruction. This is like D, but the
lower two bits are forced to zero. */
-#define DS DES + 1
+#define DS DQ + 1
{ 16, 0, insert_ds, extract_ds,
PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS },
/* The FXM field in an XFX instruction. */
#define FXM FRS + 1
#define FXM_MASK (0xff << 12)
- { 8, 12, 0, 0, 0 },
+ { 8, 12, insert_fxm, extract_fxm, 0 },
+
+ /* Power4 version for mfcr. */
+#define FXM4 FXM + 1
+ { 8, 12, insert_fxm, extract_fxm, PPC_OPERAND_OPTIONAL },
/* The L field in a D or X form instruction. */
-#define L FXM + 1
+#define L FXM4 + 1
{ 1, 21, 0, 0, PPC_OPERAND_OPTIONAL },
/* The LEV field in a POWER SC form instruction. */
{ 16, 0, insert_nsi, extract_nsi,
PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
- /* The RA field in an D, DS, X, XO, M, or MDS form instruction. */
+ /* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction. */
#define RA NSI + 1
#define RA_MASK (0x1f << 16)
{ 5, 16, 0, 0, PPC_OPERAND_GPR },
+ /* The RA field in the DQ form lq instruction, which has special
+ value restrictions. */
+#define RAQ RA + 1
+ { 5, 16, insert_raq, 0, PPC_OPERAND_GPR },
+
/* The RA field in a D or X form instruction which is an updating
load, which means that the RA field may not be zero and may not
equal the RT field. */
-#define RAL RA + 1
+#define RAL RAQ + 1
{ 5, 16, insert_ral, 0, PPC_OPERAND_GPR },
/* The RA field in an lmw instruction, which has special value
#define RT_MASK (0x1f << 21)
{ 5, 21, 0, 0, PPC_OPERAND_GPR },
+ /* The RS field of the DS form stq instruction, which has special
+ value restrictions. */
+#define RSQ RS + 1
+ { 5, 21, insert_rsq, 0, PPC_OPERAND_GPR },
+
+ /* The RT field of the DQ form lq instruction, which has special
+ value restrictions. */
+#define RTQ RSQ + 1
+ { 5, 21, insert_rtq, 0, PPC_OPERAND_GPR },
+
/* The SH field in an X or M form instruction. */
-#define SH RS + 1
+#define SH RTQ + 1
#define SH_MASK (0x1f << 11)
{ 5, 11, 0, 0, 0 },
#define UI U + 1
{ 16, 0, 0, 0, 0 },
- /* The VA field in a VA, VX or VXR form instruction. */
+ /* The VA field in a VA, VX or VXR form instruction. */
#define VA UI + 1
#define VA_MASK (0x1f << 16)
{ 5, 16, 0, 0, PPC_OPERAND_VR },
- /* The VB field in a VA, VX or VXR form instruction. */
+ /* The VB field in a VA, VX or VXR form instruction. */
#define VB VA + 1
#define VB_MASK (0x1f << 11)
{ 5, 11, 0, 0, PPC_OPERAND_VR },
- /* The VC field in a VA form instruction. */
+ /* The VC field in a VA form instruction. */
#define VC VB + 1
#define VC_MASK (0x1f << 6)
{ 5, 6, 0, 0, PPC_OPERAND_VR },
- /* The VD or VS field in a VA, VX, VXR or X form instruction. */
+ /* The VD or VS field in a VA, VX, VXR or X form instruction. */
#define VD VC + 1
#define VS VD
#define VD_MASK (0x1f << 21)
{ 5, 21, 0, 0, PPC_OPERAND_VR },
- /* The SIMM field in a VX form instruction. */
+ /* The SIMM field in a VX form instruction. */
#define SIMM VD + 1
{ 5, 16, 0, 0, PPC_OPERAND_SIGNED},
- /* The UIMM field in a VX form instruction. */
+ /* The UIMM field in a VX form instruction. */
#define UIMM SIMM + 1
{ 5, 16, 0, 0, 0 },
- /* The SHB field in a VA form instruction. */
+ /* The SHB field in a VA form instruction. */
#define SHB UIMM + 1
{ 4, 6, 0, 0, 0 },
- /* The other UIMM field in a EVX form instruction. */
+ /* The other UIMM field in a EVX form instruction. */
#define EVUIMM SHB + 1
{ 5, 11, 0, 0, 0 },
- /* The other UIMM field in a half word EVX form instruction. */
+ /* The other UIMM field in a half word EVX form instruction. */
#define EVUIMM_2 EVUIMM + 1
{ 32, 11, insert_ev2, extract_ev2, PPC_OPERAND_PARENS },
- /* The other UIMM field in a word EVX form instruction. */
+ /* The other UIMM field in a word EVX form instruction. */
#define EVUIMM_4 EVUIMM_2 + 1
{ 32, 11, insert_ev4, extract_ev4, PPC_OPERAND_PARENS },
- /* The other UIMM field in a double EVX form instruction. */
+ /* The other UIMM field in a double EVX form instruction. */
#define EVUIMM_8 EVUIMM_4 + 1
{ 32, 11, insert_ev8, extract_ev8, PPC_OPERAND_PARENS },
return value & 0x1e;
}
+ /* The DQ field in a DQ form instruction. This is like D, but the
+ lower four bits are forced to zero. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_dq (insn, value, dialect, errmsg)
+ unsigned long insn;
+ long value;
+ int dialect ATTRIBUTE_UNUSED;
+ const char ** errmsg ATTRIBUTE_UNUSED;
+{
+ if ((value & 0xf) != 0 && errmsg != NULL)
+ *errmsg = _("offset not a multiple of 16");
+ return insn | (value & 0xfff0);
+}
+
+/*ARGSUSED*/
+static long
+extract_dq (insn, dialect, invalid)
+ unsigned long insn;
+ int dialect ATTRIBUTE_UNUSED;
+ int *invalid ATTRIBUTE_UNUSED;
+{
+ return ((insn & 0xfff0) ^ 0x8000) - 0x8000;
+}
+
static unsigned long
insert_ev2 (insn, value, dialect, errmsg)
unsigned long insn;
return (((insn >> 2) & 0x3ffc) ^ 0x2000) - 0x2000;
}
+static unsigned long insert_fxm (unsigned long insn,
+ long value,
+ int dialect,
+ const char **errmsg)
+{
+ /* If the optional field on mfcr is missing that means we want to use
+ the old form of the instruction that moves the whole cr. In that
+ case we'll have VALUE zero. There doesn't seem to be a way to
+ distinguish this from the case where someone writes mfcr %r3,0. */
+ if (value == 0)
+ ;
+
+ /* If only one bit of the FXM field is set, we can use the new form
+ of the instruction, which is faster. */
+ else if ((dialect & PPC_OPCODE_POWER4) != 0 && (value & -value) == value)
+ insn |= 1 << 20;
+
+ /* Any other value on mfcr is an error. */
+ else if ((insn & (0x3ff << 1)) == 19 << 1)
+ {
+ if (errmsg != NULL)
+ *errmsg = _("ignoring invalid mfcr mask");
+ value = 0;
+ }
+
+ return insn | ((value & 0xff) << 12);
+}
+
+static long extract_fxm (unsigned long insn, int dialect, int *invalid)
+{
+ long mask = (insn >> 12) & 0xff;
+
+ /* Is this a Power4 insn? */
+ if ((insn & (1 << 20)) != 0)
+ {
+ if ((dialect & PPC_OPCODE_POWER4) == 0)
+ {
+ if (invalid != NULL)
+ *invalid = 1;
+ }
+ else
+ {
+ /* Exactly one bit of MASK should be set. */
+ if ((mask == 0 || (mask & -mask) != mask) && invalid != NULL)
+ *invalid = 1;
+ }
+ }
+
+ /* Check that non-power4 form of mfcr has a zero MASK. */
+ else if ((insn & (0x3ff << 1)) == 19 << 1)
+ {
+ if (mask != 0 && invalid != NULL)
+ *invalid = 1;
+ }
+
+ return mask;
+}
+
/* The LI field in an I form instruction. The lower two bits are
forced to zero. */
return insn | ((value & 0x1f) << 16);
}
+ /* The RA field in the DQ form lq instruction, which has special
+ value restrictions. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_raq (insn, value, dialect, errmsg)
+ unsigned long insn;
+ long value;
+ int dialect ATTRIBUTE_UNUSED;
+ const char **errmsg;
+{
+ long rtvalue = (insn & RT_MASK) >> 21;
+
+ if (value == rtvalue && errmsg != NULL)
+ *errmsg = _("source and target register operands must be different");
+ return insn | ((value & 0x1f) << 16);
+}
+
/* The RA field in a D or X form instruction which is an updating
store or an updating floating point load, which means that the RA
field may not be zero. */
return 0;
}
+ /* The RT field of the DQ form lq instruction, which has special
+ value restrictions. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_rtq (insn, value, dialect, errmsg)
+ unsigned long insn;
+ long value;
+ int dialect ATTRIBUTE_UNUSED;
+ const char **errmsg;
+{
+ if ((value & 1) != 0 && errmsg != NULL)
+ *errmsg = _("target register operand must be even");
+ return insn | ((value & 0x1f) << 21);
+}
+
+ /* The RS field of the DS form stq instruction, which has special
+ value restrictions. */
+
+/*ARGSUSED*/
+static unsigned long
+insert_rsq (insn, value, dialect, errmsg)
+ unsigned long insn;
+ long value ATTRIBUTE_UNUSED;
+ int dialect ATTRIBUTE_UNUSED;
+ const char **errmsg;
+{
+ if ((value & 1) != 0 && errmsg != NULL)
+ *errmsg = _("source register operand must be even");
+ return insn | ((value & 0x1f) << 21);
+}
+
/* The SH field in an MD form instruction. This is split. */
/*ARGSUSED*/
#define SC(op, sa, lk) (OP (op) | ((((unsigned long)(sa)) & 1) << 1) | ((lk) & 1))
#define SC_MASK (OP_MASK | (((unsigned long)0x3ff) << 16) | (((unsigned long)1) << 1) | 1)
-/* An VX form instruction. */
+/* An VX form instruction. */
#define VX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7ff))
-/* The mask for an VX form instruction. */
+/* The mask for an VX form instruction. */
#define VX_MASK VX(0x3f, 0x7ff)
-/* An VA form instruction. */
+/* An VA form instruction. */
#define VXA(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x03f))
-/* The mask for an VA form instruction. */
+/* The mask for an VA form instruction. */
#define VXA_MASK VXA(0x3f, 0x3f)
-/* An VXR form instruction. */
+/* An VXR form instruction. */
#define VXR(op, xop, rc) (OP (op) | (((rc) & 1) << 10) | (((unsigned long)(xop)) & 0x3ff))
-/* The mask for a VXR form instruction. */
+/* The mask for a VXR form instruction. */
#define VXR_MASK VXR(0x3f, 0x3ff, 1)
/* An X form instruction. */
/* An X_MASK with the RA and RB fields fixed. */
#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
-/* An XRARB_MASK, but with the L bit clear. */
+/* An XRARB_MASK, but with the L bit clear. */
#define XRLARB_MASK (XRARB_MASK & ~((unsigned long) 1 << 16))
/* An X_MASK with the RT and RA fields fixed. */
#define XS_MASK XS (0x3f, 0x1ff, 1)
/* A mask for the FXM version of an XFX form instruction. */
-#define XFXFXM_MASK (X_MASK | (((unsigned long)1) << 20) | (((unsigned long)1) << 11))
+#define XFXFXM_MASK (X_MASK | (1 << 11))
/* An XFX form instruction with the FXM field filled in. */
#define XFXM(op, xop, fxm) \
sorted by major opcode. */
const struct powerpc_opcode powerpc_opcodes[] = {
+{ "attn", X(0,256), X_MASK, POWER4, { 0 } },
{ "tdlgti", OPTO(2,TOLGT), OPTO_MASK, PPC64, { RA, SI } },
{ "tdllti", OPTO(2,TOLLT), OPTO_MASK, PPC64, { RA, SI } },
{ "tdeqi", OPTO(2,TOEQ), OPTO_MASK, PPC64, { RA, SI } },
{ "efsctuf", VX(4, 726), VX_MASK, PPCEFS, { RS, RB } },
{ "efsctsf", VX(4, 727), VX_MASK, PPCEFS, { RS, RB } },
-{ "evsabs", VX(4, 708), VX_MASK, PPCSPE, { RS, RA } },
-{ "evsnabs", VX(4, 709), VX_MASK, PPCSPE, { RS, RA } },
-{ "evsneg", VX(4, 710), VX_MASK, PPCSPE, { RS, RA } },
-{ "evsadd", VX(4, 704), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evssub", VX(4, 705), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evsmul", VX(4, 712), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evsdiv", VX(4, 713), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evscmpgt", VX(4, 716), VX_MASK, PPCSPE, { CRFD, RA, RB } },
-{ "evsgmplt", VX(4, 717), VX_MASK, PPCSPE, { CRFD, RA, RB } },
-{ "evsgmpeq", VX(4, 718), VX_MASK, PPCSPE, { CRFD, RA, RB } },
-{ "evststgt", VX(4, 732), VX_MASK, PPCSPE, { CRFD, RA, RB } },
-{ "evststlt", VX(4, 733), VX_MASK, PPCSPE, { CRFD, RA, RB } },
-{ "evststeq", VX(4, 734), VX_MASK, PPCSPE, { CRFD, RA, RB } },
-{ "evscfui", VX(4, 720), VX_MASK, PPCSPE, { RS, RB } },
-{ "evscfsi", VX(4, 721), VX_MASK, PPCSPE, { RS, RB } },
-{ "evscfuf", VX(4, 722), VX_MASK, PPCSPE, { RS, RB } },
-{ "evscfsf", VX(4, 723), VX_MASK, PPCSPE, { RS, RB } },
-{ "evsctui", VX(4, 724), VX_MASK, PPCSPE, { RS, RB } },
-{ "evsctuiz", VX(4, 728), VX_MASK, PPCSPE, { RS, RB } },
-{ "evsctsi", VX(4, 725), VX_MASK, PPCSPE, { RS, RB } },
-{ "evsctsiz", VX(4, 730), VX_MASK, PPCSPE, { RS, RB } },
-{ "evsctuf", VX(4, 726), VX_MASK, PPCSPE, { RS, RB } },
-{ "evsctsf", VX(4, 727), VX_MASK, PPCSPE, { RS, RB } },
-
{ "evmhossf", VX(4, 1031), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmhossfa", VX(4, 1063), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmhosmf", VX(4, 1039), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwlumi", VX(4, 1096), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwlumia", VX(4, 1128), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhssfaa",VX(4, 1351), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhssmaa",VX(4, 1349), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhsmfaa",VX(4, 1359), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhsmiaa",VX(4, 1357), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhusiaa",VX(4, 1348), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhumiaa",VX(4, 1356), VX_MASK, PPCSPE, { RS, RA, RB } },
-
{ "evmwlssiaaw",VX(4, 1345), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwlsmiaaw",VX(4, 1353), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwlusiaaw",VX(4, 1344), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwlumiaaw",VX(4, 1352), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhssfan",VX(4, 1479), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhssian",VX(4, 1477), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhsmfan",VX(4, 1487), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhsmian",VX(4, 1485), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhusian",VX(4, 1476), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhumian",VX(4, 1484), VX_MASK, PPCSPE, { RS, RA, RB } },
-
{ "evmwlssianw",VX(4, 1473), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwlsmianw",VX(4, 1481), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwlusianw",VX(4, 1472), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwlumianw",VX(4, 1480), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhgssfaa",VX(4, 1383), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhgsmfaa",VX(4, 1391), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhgsmiaa",VX(4, 1381), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhgumiaa",VX(4, 1380), VX_MASK, PPCSPE, { RS, RA, RB } },
-
-{ "evmwhgssfan",VX(4, 1511), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhgsmfan",VX(4, 1519), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhgsmian",VX(4, 1509), VX_MASK, PPCSPE, { RS, RA, RB } },
-{ "evmwhgumian",VX(4, 1508), VX_MASK, PPCSPE, { RS, RA, RB } },
-
{ "evmwssf", VX(4, 1107), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwssfa", VX(4, 1139), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "evmwsmf", VX(4, 1115), VX_MASK, PPCSPE, { RS, RA, RB } },
{ "cau", OP(15), OP_MASK, PWRCOM, { RT,RA,SISIGNOPT } },
{ "subis", OP(15), OP_MASK, PPCCOM, { RT, RA, NSI } },
-{ "bdnz-", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDM } },
-{ "bdnz+", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDP } },
-{ "bdnz", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BD } },
-{ "bdn", BBO(16,BODNZ,0,0), BBOATBI_MASK, PWRCOM, { BD } },
-{ "bdnzl-", BBO(16,BODNZ,0,1), BBOATBI_MASK, PPCCOM, { BDM } },
-{ "bdnzl+", BBO(16,BODNZ,0,1), BBOATBI_MASK, PPCCOM, { BDP } },
-{ "bdnzl", BBO(16,BODNZ,0,1), BBOATBI_MASK, PPCCOM, { BD } },
-{ "bdnl", BBO(16,BODNZ,0,1), BBOATBI_MASK, PWRCOM, { BD } },
-{ "bdnza-", BBO(16,BODNZ,1,0), BBOATBI_MASK, PPCCOM, { BDMA } },
-{ "bdnza+", BBO(16,BODNZ,1,0), BBOATBI_MASK, PPCCOM, { BDPA } },
-{ "bdnza", BBO(16,BODNZ,1,0), BBOATBI_MASK, PPCCOM, { BDA } },
-{ "bdna", BBO(16,BODNZ,1,0), BBOATBI_MASK, PWRCOM, { BDA } },
-{ "bdnzla-", BBO(16,BODNZ,1,1), BBOATBI_MASK, PPCCOM, { BDMA } },
-{ "bdnzla+", BBO(16,BODNZ,1,1), BBOATBI_MASK, PPCCOM, { BDPA } },
-{ "bdnzla", BBO(16,BODNZ,1,1), BBOATBI_MASK, PPCCOM, { BDA } },
-{ "bdnla", BBO(16,BODNZ,1,1), BBOATBI_MASK, PWRCOM, { BDA } },
-{ "bdz-", BBO(16,BODZ,0,0), BBOATBI_MASK, PPCCOM, { BDM } },
-{ "bdz+", BBO(16,BODZ,0,0), BBOATBI_MASK, PPCCOM, { BDP } },
-{ "bdz", BBO(16,BODZ,0,0), BBOATBI_MASK, COM, { BD } },
-{ "bdzl-", BBO(16,BODZ,0,1), BBOATBI_MASK, PPCCOM, { BDM } },
-{ "bdzl+", BBO(16,BODZ,0,1), BBOATBI_MASK, PPCCOM, { BDP } },
-{ "bdzl", BBO(16,BODZ,0,1), BBOATBI_MASK, COM, { BD } },
-{ "bdza-", BBO(16,BODZ,1,0), BBOATBI_MASK, PPCCOM, { BDMA } },
-{ "bdza+", BBO(16,BODZ,1,0), BBOATBI_MASK, PPCCOM, { BDPA } },
-{ "bdza", BBO(16,BODZ,1,0), BBOATBI_MASK, COM, { BDA } },
-{ "bdzla-", BBO(16,BODZ,1,1), BBOATBI_MASK, PPCCOM, { BDMA } },
-{ "bdzla+", BBO(16,BODZ,1,1), BBOATBI_MASK, PPCCOM, { BDPA } },
-{ "bdzla", BBO(16,BODZ,1,1), BBOATBI_MASK, COM, { BDA } },
+{ "bdnz-", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDM } },
+{ "bdnz+", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDP } },
+{ "bdnz", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BD } },
+{ "bdn", BBO(16,BODNZ,0,0), BBOATBI_MASK, PWRCOM, { BD } },
+{ "bdnzl-", BBO(16,BODNZ,0,1), BBOATBI_MASK, PPCCOM, { BDM } },
+{ "bdnzl+", BBO(16,BODNZ,0,1), BBOATBI_MASK, PPCCOM, { BDP } },
+{ "bdnzl", BBO(16,BODNZ,0,1), BBOATBI_MASK, PPCCOM, { BD } },
+{ "bdnl", BBO(16,BODNZ,0,1), BBOATBI_MASK, PWRCOM, { BD } },
+{ "bdnza-", BBO(16,BODNZ,1,0), BBOATBI_MASK, PPCCOM, { BDMA } },
+{ "bdnza+", BBO(16,BODNZ,1,0), BBOATBI_MASK, PPCCOM, { BDPA } },
+{ "bdnza", BBO(16,BODNZ,1,0), BBOATBI_MASK, PPCCOM, { BDA } },
+{ "bdna", BBO(16,BODNZ,1,0), BBOATBI_MASK, PWRCOM, { BDA } },
+{ "bdnzla-", BBO(16,BODNZ,1,1), BBOATBI_MASK, PPCCOM, { BDMA } },
+{ "bdnzla+", BBO(16,BODNZ,1,1), BBOATBI_MASK, PPCCOM, { BDPA } },
+{ "bdnzla", BBO(16,BODNZ,1,1), BBOATBI_MASK, PPCCOM, { BDA } },
+{ "bdnla", BBO(16,BODNZ,1,1), BBOATBI_MASK, PWRCOM, { BDA } },
+{ "bdz-", BBO(16,BODZ,0,0), BBOATBI_MASK, PPCCOM, { BDM } },
+{ "bdz+", BBO(16,BODZ,0,0), BBOATBI_MASK, PPCCOM, { BDP } },
+{ "bdz", BBO(16,BODZ,0,0), BBOATBI_MASK, COM, { BD } },
+{ "bdzl-", BBO(16,BODZ,0,1), BBOATBI_MASK, PPCCOM, { BDM } },
+{ "bdzl+", BBO(16,BODZ,0,1), BBOATBI_MASK, PPCCOM, { BDP } },
+{ "bdzl", BBO(16,BODZ,0,1), BBOATBI_MASK, COM, { BD } },
+{ "bdza-", BBO(16,BODZ,1,0), BBOATBI_MASK, PPCCOM, { BDMA } },
+{ "bdza+", BBO(16,BODZ,1,0), BBOATBI_MASK, PPCCOM, { BDPA } },
+{ "bdza", BBO(16,BODZ,1,0), BBOATBI_MASK, COM, { BDA } },
+{ "bdzla-", BBO(16,BODZ,1,1), BBOATBI_MASK, PPCCOM, { BDMA } },
+{ "bdzla+", BBO(16,BODZ,1,1), BBOATBI_MASK, PPCCOM, { BDPA } },
+{ "bdzla", BBO(16,BODZ,1,1), BBOATBI_MASK, COM, { BDA } },
{ "blt-", BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDM } },
{ "blt+", BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, PPCCOM, { CR, BDP } },
{ "blt", BBOCB(16,BOT,CBLT,0,0), BBOATCB_MASK, COM, { CR, BD } },
{ "ba", B(18,1,0), B_MASK, COM, { LIA } },
{ "bla", B(18,1,1), B_MASK, COM, { LIA } },
-{ "mcrf", XL(19,0), XLBB_MASK|(3<<21)|(3<<16), COM, { BF, BFA } },
+{ "mcrf", XL(19,0), XLBB_MASK|(3 << 21)|(3 << 16), COM, { BF, BFA } },
{ "blr", XLO(19,BOU,16,0), XLBOBIBB_MASK, PPCCOM, { 0 } },
{ "br", XLO(19,BOU,16,0), XLBOBIBB_MASK, PWRCOM, { 0 } },
{ "crnot", XL(19,33), XL_MASK, PPCCOM, { BT, BA, BBA } },
{ "crnor", XL(19,33), XL_MASK, COM, { BT, BA, BB } },
-{ "rfmci", X(19,38), 0xffffffff, PPCRFMCI, { 0 } },
-
+{ "rfmci", X(19,38), 0xffffffff, PPCRFMCI, { 0 } },
{ "rfi", XL(19,50), 0xffffffff, COM, { 0 } },
{ "rfci", XL(19,51), 0xffffffff, PPC403, { 0 } },
{ "iseleq", X(31,79), X_MASK, PPCISEL, { RT, RA, RB } },
{ "isel", XISEL(31,15), XISEL_MASK, PPCISEL, { RT, RA, RB, CRB } },
-{ "mfcr", X(31,19), XRARB_MASK, COM, { RT } },
+{ "mfcr", X(31,19), XRARB_MASK, NOPOWER4, { RT } },
+{ "mfcr", X(31,19), XFXFXM_MASK, POWER4, { RT, FXM4 } },
{ "lwarx", X(31,20), X_MASK, PPC, { RT, RA, RB } },
{ "dcbtstlse",X(31,142),X_MASK, PPCCHLK64, { CT, RA, RB }},
-{ "mtcr", XFXM(31,144,0xff), XFXFXM_MASK|FXM_MASK, COM, { RS }},
+{ "mtcr", XFXM(31,144,0xff), XRARB_MASK, COM, { RS }},
{ "mtcrf", X(31,144), XFXFXM_MASK, COM, { FXM, RS } },
{ "mtmsr", X(31,146), XRARB_MASK, COM, { RS } },
{ "mftbl", XSPR(31,371,268), XSPR_MASK, CLASSIC, { RT } },
{ "mftbu", XSPR(31,371,269), XSPR_MASK, CLASSIC, { RT } },
+{ "mftb", X(31,371), X_MASK, CLASSIC, { RT, TBR } },
{ "lwaux", X(31,373), X_MASK, PPC64, { RT, RAL, RB } },
{ "mtivor13", XSPR(31,467,413), XSPR_MASK, BOOKE, { RS } },
{ "mtivor14", XSPR(31,467,414), XSPR_MASK, BOOKE, { RS } },
{ "mtivor15", XSPR(31,467,415), XSPR_MASK, BOOKE, { RS } },
-{ "mtspefscr", XSPR(31,467,512), XSPR_MASK, PPCSPE, { RT } },
+{ "mtspefscr", XSPR(31,467,512), XSPR_MASK, PPCSPE, { RS } },
{ "mtbbear", XSPR(31,467,513), XSPR_MASK, PPCBRLK, { RS } },
{ "mtbbtar", XSPR(31,467,514), XSPR_MASK, PPCBRLK, { RS } },
{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
{ "tlbrehi", XTLB(31,946,0), XTLB_MASK, PPC403, { RT, RA } },
{ "tlbrelo", XTLB(31,946,1), XTLB_MASK, PPC403, { RT, RA } },
+{ "tlbre", X(31,946), X_MASK, PPC403, { RS, RA, SH } },
{ "sraiq", XRC(31,952,0), X_MASK, M601, { RA, RS, SH } },
{ "sraiq.", XRC(31,952,1), X_MASK, M601, { RA, RS, SH } },
{ "stfdu", OP(55), OP_MASK, COM, { FRS, D, RAS } },
+{ "lq", OP(56), OP_MASK, POWER4, { RTQ, DQ, RAQ } },
+
{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA } },
{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA } },
{ "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS } },
+{ "stq", DSO(62,2), DS_MASK, POWER4, { RSQ, DS, RA } },
+
{ "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } },
{ "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } },
{ "extlwi", 4, PPCCOM, "rlwinm %0,%1,%3,0,(%2)-1" },
{ "extlwi.", 4, PPCCOM, "rlwinm. %0,%1,%3,0,(%2)-1" },
-{ "extrwi", 4, PPCCOM, "rlwinm %0,%1,(%2)+(%3),32-(%2),31" },
-{ "extrwi.", 4, PPCCOM, "rlwinm. %0,%1,(%2)+(%3),32-(%2),31" },
+{ "extrwi", 4, PPCCOM, "rlwinm %0,%1,((%2)+(%3))&((%2)+(%3)<>32),32-(%2),31" },
+{ "extrwi.", 4, PPCCOM, "rlwinm. %0,%1,((%2)+(%3))&((%2)+(%3)<>32),32-(%2),31" },
{ "inslwi", 4, PPCCOM, "rlwimi %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1" },
{ "inslwi.", 4, PPCCOM, "rlwimi. %0,%1,(-(%3)!31)&((%3)|31),%3,(%2)+(%3)-1"},
{ "insrwi", 4, PPCCOM, "rlwimi %0,%1,32-((%2)+(%3)),%3,(%2)+(%3)-1" },