Teach the assembler about PowerPC extended mnemonics.
authorGeorge Koehler <xkernigh@netscape.net>
Sun, 22 Jan 2017 04:49:29 +0000 (23:49 -0500)
committerGeorge Koehler <xkernigh@netscape.net>
Sun, 22 Jan 2017 04:49:29 +0000 (23:49 -0500)
Also make a few changes to basic mnemonics.  Fix typo in name of the
basic "creqv".  Add the basic "addc" and relatives, because it would
be odd to have the extended "subc" without "addc".  Fix the basic
"rldicl", "rldicr", "rldic", "rldimi" to correctly encode the 6-bit MB
field.  Fix "slw" and relatives to correctly swap their RA and RS
operands.

Add many, but not all, of the extended mnemonics from IBM's Power ISA
Version 2.06 Book I Appendix E.  (I used 2.06, published 2009, just
because I already had the PDF of it.)  This commit includes mnemonics
for branching, subtraction, traps, bit rotation, and a few others,
like "mflr" and "nop".  The assembler now understands branches like
`beq cr7, label` and bit shifts like `slwi r7, r7, 2`.  These encode
the same machine instructions as the basic "bc" and "rlwinm".

Some operands to basic names become optional.  The assembler no longer
requires the level in "sc" or the branch hint in "bcctr" and "bclr";
they default to zero.  Some extended names take an optional branch
hint or condition register.

Some extended names are still missing.  I don't provide names with
static branch prediction, like "beq+" or "bge-", because the assembler
parses '+' and '-' as operators, not as part of an instruction name.
I also don't provide some names that 2.06 has for moving to or from
the condition register or some special purpose registers, names like
"mtcr" or "mfuamr".

This commit also deletes some unused tokens and one unused yacc rule.

mach/powerpc/as/mach0.c
mach/powerpc/as/mach2.c
mach/powerpc/as/mach3.c
mach/powerpc/as/mach4.c

index 325c089..3246828 100644 (file)
@@ -31,3 +31,9 @@ typedef uint32_t quad;
 #define VALWIDTH       8
 
 #define FIXUPFLAGS (RELBR | RELWR)
+
+/* 6-bit mb (mask begin) or me (mask end) field */
+#define MB6(v) (((v) & 0x1F)<<6 | ((v) & 0x20)>>0)
+
+/* 6-bit sh (shift) field */
+#define SH6(v) (((v) & 0x1F)<<11 | ((v) & 0x20)>>4)
index 3ecaf10..555b92c 100644 (file)
@@ -8,20 +8,35 @@
 %token <y_word> FPR
 %token <y_word> CR
 %token <y_word> C
+%token <y_word> OP_HI OP_HA OP_LO
 
 %token <y_word> OP
+%token <y_word> OP_BDA
+%token <y_word> OP_BDL
 %token <y_word> OP_BF
 %token <y_word> OP_BF_BFA
 %token <y_word> OP_BF_FRA_FRB
 %token <y_word> OP_BF_L_RA_RB
 %token <y_word> OP_BF_L_RA_SI
 %token <y_word> OP_BF_L_RA_UI
+%token <y_word> OP_BF_RA_RB
+%token <y_word> OP_BF_RA_SI
+%token <y_word> OP_BF_RA_UI
 %token <y_word> OP_BF_U_C
+%token <y_word> OP_BH
+%token <y_word> OP_BI_BDA
+%token <y_word> OP_BI_BDL
+%token <y_word> OP_BI_BH
+%token <y_word> OP_BICR_BDA
+%token <y_word> OP_BICR_BDL
+%token <y_word> OP_BICR_BH
 %token <y_word> OP_BO_BI_BDA
 %token <y_word> OP_BO_BI_BDL
 %token <y_word> OP_BO_BI_BH
 %token <y_word> OP_BT_C
+%token <y_word> OP_BT_BA_BA
 %token <y_word> OP_BT_BA_BB
+%token <y_word> OP_BT_BT_BT
 %token <y_word> OP_FLM_FRB_C
 %token <y_word> OP_FRS_RA_D
 %token <y_word> OP_FRS_RA_RB
 %token <y_word> OP_FRT_FRB_C
 %token <y_word> OP_FRT_RA_D
 %token <y_word> OP_FRT_RA_RB
-%token <y_word> OP_L
 %token <y_word> OP_LEV
 %token <y_word> OP_LIA
 %token <y_word> OP_LIL
-%token <y_word> OP_L_RB
-%token <y_word> OP_RA_RB
-%token <y_word> OP_RB
-%token <y_word> OP_RS
+%token <y_word> OP_LI32
+%token <y_word> OP_RA_RS_RB_C
+%token <y_word> OP_RA_RS_RB_MB5_ME5_C
+%token <y_word> OP_RA_RS_RB_MB6_C
+%token <y_word> OP_RA_RS_SH5_C
+%token <y_word> OP_RA_RS_SH5_MB5_ME5_C
+%token <y_word> OP_RA_RS_SH6_C
+%token <y_word> OP_RA_RS_SH6_MB6_C
 %token <y_word> OP_RS_FXM
-%token <y_word> OP_RS_L
 %token <y_word> OP_RS_RA
 %token <y_word> OP_RS_RA_C
 %token <y_word> OP_RS_RA_D
 %token <y_word> OP_RS_RA_RB
 %token <y_word> OP_RS_RA_RB_C
 %token <y_word> OP_RS_RA_RA_C
-%token <y_word> OP_RS_RA_RB_MB5_ME5_C
-%token <y_word> OP_RS_RA_RB_MB6_C
-%token <y_word> OP_RS_RA_RB_ME6_C
-%token <y_word> OP_RS_RA_SH_MB5_ME5_C
-%token <y_word> OP_RS_RA_SH_MB6_SH_C
-%token <y_word> OP_RS_RA_SH_ME6_SH_C
-%token <y_word> OP_RS_RA_SH5_C
-%token <y_word> OP_RS_RA_SH6_C
 %token <y_word> OP_RS_RA_UI
 %token <y_word> OP_RS_RA_UI_CC
 %token <y_word> OP_RS_RB
 %token <y_word> OP_RT_RA_RB_C
 %token <y_word> OP_RT_RA_SI
 %token <y_word> OP_RT_RA_SI_addic
+%token <y_word> OP_RT_RA_SI_subi
+%token <y_word> OP_RT_RA_SI_subic
 %token <y_word> OP_RT_RB
+%token <y_word> OP_RT_RB_RA_C
+%token <y_word> OP_RT_SI
 %token <y_word> OP_RT_SPR
 %token <y_word> OP_RT_SR
 %token <y_word> OP_RT_TBR
 %token <y_word> OP_TH_RA_RB
 %token <y_word> OP_TO_RA_RB
 %token <y_word> OP_TO_RA_SI
-
-%token <y_word> OP_LA
-%token <y_word> OP_LI32
-
-%token <y_word> OP_POWERPC_FIXUP
-%token <y_word> OP_HI OP_HA OP_LO
+%token <y_word> OP_TOX_RA_RB
+%token <y_word> OP_TOX_RA_SI
+%token <y_word> OP_clrlsldi OP_clrldi OP_clrrdi OP_extldi OP_extrdi
+%token <y_word> OP_insrdi OP_rotrdi OP_sldi OP_srdi
+%token <y_word> OP_clrlslwi OP_clrlwi OP_clrrwi OP_extlwi OP_extrwi
+%token <y_word> OP_inslwi OP_insrwi OP_rotlwi OP_rotrwi OP_slwi OP_srwi
 
 /* Other token types */
 
 %type <y_word> c
-%type <y_word> e16 u8 u7 u6 u5 u4 u2 u1
-%type <y_word> nb ds bda bdl lia lil spr_num
+%type <y_word> e16 negate16 u8 u7 u6 u5 u4 u2 u1
+%type <y_word> opt_bh cr_opt nb ds bda bdl lia lil spr_num
index 724ba73..16c1e6a 100644 (file)
@@ -99,9 +99,6 @@
 /* Special instructions */
 
 0,     OP_LI32,               0,                                       "li32",
-0,     OP_LA,                 0,                                       "la",
-0,     OP_LA,                 0,                                       "li",
-0,     OP_RS_RA_RA_C,         31<<26 | 444<<1,                         "mr",
 0,     OP_HI,                 0,                                       "hi16",
 0,     OP_HA,                0,                                        "ha16",
 0,     OP_LO,                 0,                                       "lo16",
 0,     OP_BT_BA_BB,           19<<26 | 193<<1,                         "crxor",
 0,     OP_BT_BA_BB,           19<<26 | 225<<1,                         "crnand",
 0,     OP_BT_BA_BB,           19<<26 | 33<<1,                          "crnor",
-0,     OP_BT_BA_BB,           19<<26 | 289<<1,                         "crneqv",
+0,     OP_BT_BA_BB,           19<<26 | 289<<1,                         "creqv",
 0,     OP_BT_BA_BB,           19<<26 | 129<<1,                         "crandc",
 0,     OP_BT_BA_BB,           19<<26 | 417<<1,                         "crorc",
 0,     OP_BF_BFA,             19<<26 | 0<<1,                           "mcrf",
 
+/* extended mnemonics for bc, bcctr, bclr */
+0,     OP_BH,       19<<26 | 20<<21 | 528<<1 | 0<<0,            "bctr",
+0,     OP_BH,       19<<26 | 20<<21 | 528<<1 | 1<<0,            "bctrl",
+0,     OP_BDL,      16<<26 | 16<<21 | 0<<1 | 0<<0,              "bdnz",
+0,     OP_BDA,      16<<26 | 16<<21 | 1<<1 | 0<<0,              "bdnza",
+0,     OP_BH,       19<<26 | 16<<21 | 16<<1 | 0<<0,             "bdnzlr",
+0,     OP_BDL,      16<<26 | 16<<21 | 0<<1 | 1<<0,              "bdnzl",
+0,     OP_BDA,      16<<26 | 16<<21 | 1<<1 | 1<<0,              "bdnzla",
+0,     OP_BH,       19<<26 | 16<<21 | 16<<1 | 1<<0,             "bdnzlrl",
+0,     OP_BI_BDL,   16<<26 | 0<<21 | 0<<1 | 0<<0,               "bdnzf",
+0,     OP_BI_BDA,   16<<26 | 0<<21 | 1<<1 | 0<<0,               "bdnzfa",
+0,     OP_BI_BH,    19<<26 | 0<<21 | 16<<1 | 0<<0,              "bdnzflr",
+0,     OP_BI_BDL,   16<<26 | 0<<21 | 0<<1 | 1<<0,               "bdnzfl",
+0,     OP_BI_BDA,   16<<26 | 0<<21 | 1<<1 | 1<<0,               "bdnzfla",
+0,     OP_BI_BH,    19<<26 | 0<<21 | 16<<1 | 1<<0,              "bdnzflrl",
+0,     OP_BI_BDL,   16<<26 | 8<<21 | 0<<1 | 0<<0,               "bdnzt",
+0,     OP_BI_BDA,   16<<26 | 8<<21 | 1<<1 | 0<<0,               "bdnzta",
+0,     OP_BI_BH,    19<<26 | 8<<21 | 16<<1 | 0<<0,              "bdnztlr",
+0,     OP_BI_BDL,   16<<26 | 8<<21 | 0<<1 | 1<<0,               "bdnztl",
+0,     OP_BI_BDA,   16<<26 | 8<<21 | 1<<1 | 1<<0,               "bdnztla",
+0,     OP_BI_BH,    19<<26 | 8<<21 | 16<<1 | 1<<0,              "bdnztlrl",
+0,     OP_BDL,      16<<26 | 18<<21 | 0<<1 | 0<<0,              "bdz",
+0,     OP_BDA,      16<<26 | 18<<21 | 1<<1 | 0<<0,              "bdza",
+0,     OP_BH,       19<<26 | 18<<21 | 16<<1 | 0<<0,             "bdzlr",
+0,     OP_BDL,      16<<26 | 18<<21 | 0<<1 | 1<<0,              "bdzl",
+0,     OP_BDA,      16<<26 | 18<<21 | 1<<1 | 1<<0,              "bdzla",
+0,     OP_BH,       19<<26 | 18<<21 | 16<<1 | 1<<0,             "bdzlrl",
+0,     OP_BI_BDL,   16<<26 | 2<<21 | 0<<1 | 0<<0,               "bdzf",
+0,     OP_BI_BDA,   16<<26 | 2<<21 | 1<<1 | 0<<0,               "bdzfa",
+0,     OP_BI_BH,    19<<26 | 2<<21 | 16<<1 | 0<<0,              "bdzflr",
+0,     OP_BI_BDL,   16<<26 | 2<<21 | 0<<1 | 1<<0,               "bdzfl",
+0,     OP_BI_BDA,   16<<26 | 2<<21 | 1<<1 | 1<<0,               "bdzfla",
+0,     OP_BI_BH,    19<<26 | 2<<21 | 16<<1 | 1<<0,              "bdzflrl",
+0,     OP_BI_BDL,   16<<26 | 10<<21 | 0<<1 | 0<<0,              "bdzt",
+0,     OP_BI_BDA,   16<<26 | 10<<21 | 1<<1 | 0<<0,              "bdzta",
+0,     OP_BI_BH,    19<<26 | 10<<21 | 16<<1 | 0<<0,             "bdztlr",
+0,     OP_BI_BDL,   16<<26 | 10<<21 | 0<<1 | 1<<0,              "bdztl",
+0,     OP_BI_BDA,   16<<26 | 10<<21 | 1<<1 | 1<<0,              "bdztla",
+0,     OP_BI_BH,    19<<26 | 10<<21 | 16<<1 | 1<<0,             "bdztlrl",
+0,     OP_BI_BDL,   16<<26 | 4<<21 | 0<<1 | 0<<0,               "bf",
+0,     OP_BI_BDA,   16<<26 | 4<<21 | 1<<1 | 0<<0,               "bfa",
+0,     OP_BI_BH,    19<<26 | 4<<21 | 528<<1 | 0<<0,             "bfctr",
+0,     OP_BI_BH,    19<<26 | 4<<21 | 528<<1 | 1<<0,             "bfctrl",
+0,     OP_BI_BDL,   16<<26 | 4<<21 | 0<<1 | 1<<0,               "bfl",
+0,     OP_BI_BDA,   16<<26 | 4<<21 | 0<<1 | 1<<0,               "bfla",
+0,     OP_BI_BH,    19<<26 | 4<<21 | 16<<1 | 0<<0,              "bflr",
+0,     OP_BI_BH,    19<<26 | 4<<21 | 16<<1 | 1<<0,              "bflrl",
+0,     OP_BH,       19<<26 | 20<<21 | 16<<1 | 0<<0,             "blr",
+0,     OP_BH,       19<<26 | 20<<21 | 16<<1 | 1<<0,             "blrl",
+0,     OP_BI_BDL,   16<<26 | 12<<21 | 0<<1 | 0<<0,              "bt",
+0,     OP_BI_BDA,   16<<26 | 12<<21 | 1<<1 | 0<<0,              "bta",
+0,     OP_BI_BH,    19<<26 | 12<<21 | 528<<1 | 0<<0,            "btctr",
+0,     OP_BI_BH,    19<<26 | 12<<21 | 528<<1 | 1<<0,            "btctrl",
+0,     OP_BI_BDL,   16<<26 | 12<<21 | 0<<1 | 1<<0,              "btl",
+0,     OP_BI_BDA,   16<<26 | 12<<21 | 0<<1 | 1<<0,              "btla",
+0,     OP_BI_BH,    19<<26 | 12<<21 | 16<<1 | 0<<0,             "btlr",
+0,     OP_BI_BH,    19<<26 | 12<<21 | 16<<1 | 1<<0,             "btlrl",
+
+/* extended m with condition in BI */
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 2<<16 | 0<<1 | 0<<0,     "beq",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 2<<16 | 1<<1 | 0<<0,     "beqa",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 2<<16 | 528<<1 | 0<<0,   "beqctr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 2<<16 | 528<<1 | 1<<0,   "beqctrl",
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 2<<16 | 0<<1 | 1<<0,     "beql",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 2<<16 | 1<<1 | 1<<0,     "beqla",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 2<<16 | 16<<1 | 0<<0,    "beqlr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 2<<16 | 16<<1 | 1<<0,    "beqlrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 0<<16 | 0<<1 | 0<<0,      "bge",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 0<<16 | 1<<1 | 0<<0,      "bgea",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 0<<16 | 528<<1 | 0<<0,    "bgectr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 0<<16 | 528<<1 | 1<<0,    "bgectrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 0<<16 | 0<<1 | 1<<0,      "bgel",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 0<<16 | 1<<1 | 1<<0,      "bgela",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 0<<16 | 16<<1 | 0<<0,     "bgelr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 0<<16 | 16<<1 | 1<<0,     "bgelrl",
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 1<<16 | 0<<1 | 0<<0,     "bgt",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 1<<16 | 1<<1 | 0<<0,     "bgta",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 1<<16 | 528<<1 | 0<<0,   "bgtctr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 1<<16 | 528<<1 | 1<<0,   "bgtctrl",
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 1<<16 | 0<<1 | 1<<0,     "bgtl",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 1<<16 | 1<<1 | 1<<0,     "bgtla",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 1<<16 | 16<<1 | 0<<0,    "bgtlr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 1<<16 | 16<<1 | 1<<0,    "bgtlrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 1<<16 | 0<<1 | 0<<0,      "ble",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 1<<16 | 1<<1 | 0<<0,      "blea",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 1<<16 | 528<<1 | 0<<0,    "blectr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 1<<16 | 528<<1 | 1<<0,    "blectrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 1<<16 | 0<<1 | 1<<0,      "blel",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 1<<16 | 1<<1 | 1<<0,      "blela",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 1<<16 | 16<<1 | 0<<0,     "blelr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 1<<16 | 16<<1 | 1<<0,     "blelrl",
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 0<<16 | 0<<1 | 0<<0,     "blt",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 0<<16 | 1<<1 | 0<<0,     "blta",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 0<<16 | 528<<1 | 0<<0,   "bltctr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 0<<16 | 528<<1 | 1<<0,   "bltctrl",
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 0<<16 | 0<<1 | 1<<0,     "bltl",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 0<<16 | 1<<1 | 1<<0,     "bltla",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 0<<16 | 16<<1 | 0<<0,    "bltlr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 0<<16 | 16<<1 | 1<<0,    "bltlrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 2<<16 | 0<<1 | 0<<0,      "bne",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 2<<16 | 1<<1 | 0<<0,      "bnea",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 2<<16 | 528<<1 | 0<<0,    "bnectr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 2<<16 | 528<<1 | 1<<0,    "bnectrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 2<<16 | 0<<1 | 1<<0,      "bnel",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 2<<16 | 1<<1 | 1<<0,      "bnela",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 2<<16 | 16<<1 | 0<<0,     "bnelr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 2<<16 | 16<<1 | 1<<0,     "bnelrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 1<<16 | 0<<1 | 0<<0,      "bng",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 1<<16 | 1<<1 | 0<<0,      "bnga",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 1<<16 | 528<<1 | 0<<0,    "bngctr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 1<<16 | 528<<1 | 1<<0,    "bngctrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 1<<16 | 0<<1 | 1<<0,      "bngl",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 1<<16 | 1<<1 | 1<<0,      "bngla",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 1<<16 | 16<<1 | 0<<0,     "bnglr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 1<<16 | 16<<1 | 1<<0,     "bnglrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 0<<16 | 0<<1 | 0<<0,      "bnl",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 0<<16 | 1<<1 | 0<<0,      "bnla",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 0<<16 | 528<<1 | 0<<0,    "bnlctr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 0<<16 | 528<<1 | 1<<0,    "bnlctrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 0<<16 | 0<<1 | 1<<0,      "bnll",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 0<<16 | 1<<1 | 1<<0,      "bnlla",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 0<<16 | 16<<1 | 0<<0,     "bnllr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 0<<16 | 16<<1 | 1<<0,     "bnllrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 3<<16 | 0<<1 | 0<<0,      "bns",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 3<<16 | 1<<1 | 0<<0,      "bnsa",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 3<<16 | 528<<1 | 0<<0,    "bnsctr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 3<<16 | 528<<1 | 1<<0,    "bnsctrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 3<<16 | 0<<1 | 1<<0,      "bnsl",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 3<<16 | 1<<1 | 1<<0,      "bnsla",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 3<<16 | 16<<1 | 0<<0,     "bnslr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 3<<16 | 16<<1 | 1<<0,     "bnslrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 3<<16 | 0<<1 | 0<<0,      "bnu",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 3<<16 | 1<<1 | 0<<0,      "bnua",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 3<<16 | 528<<1 | 0<<0,    "bnuctr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 3<<16 | 528<<1 | 1<<0,    "bnuctrl",
+0,     OP_BICR_BDL,  16<<26 | 4<<21 | 3<<16 | 0<<1 | 1<<0,      "bnul",
+0,     OP_BICR_BDA,  16<<26 | 4<<21 | 3<<16 | 1<<1 | 1<<0,      "bnula",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 3<<16 | 16<<1 | 0<<0,     "bnulr",
+0,     OP_BICR_BH,   19<<26 | 4<<21 | 3<<16 | 16<<1 | 1<<0,     "bnulrl",
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 3<<16 | 0<<1 | 0<<0,     "bso",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 3<<16 | 1<<1 | 0<<0,     "bsoa",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 3<<16 | 528<<1 | 0<<0,   "bsoctr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 3<<16 | 528<<1 | 1<<0,   "bsoctrl",
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 3<<16 | 0<<1 | 1<<0,     "bsol",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 3<<16 | 1<<1 | 1<<0,     "bsola",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 3<<16 | 16<<1 | 0<<0,    "bsolr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 3<<16 | 16<<1 | 1<<0,    "bsolrl",
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 3<<16 | 0<<1 | 0<<0,     "bun",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 3<<16 | 1<<1 | 0<<0,     "buna",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 3<<16 | 528<<1 | 0<<0,   "bunctr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 3<<16 | 528<<1 | 1<<0,   "bunctrl",
+0,     OP_BICR_BDL,  16<<26 | 12<<21 | 3<<16 | 0<<1 | 1<<0,     "bunl",
+0,     OP_BICR_BDA,  16<<26 | 12<<21 | 3<<16 | 1<<1 | 1<<0,     "bunla",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 3<<16 | 16<<1 | 0<<0,    "bunlr",
+0,     OP_BICR_BH,   19<<26 | 12<<21 | 3<<16 | 16<<1 | 1<<0,    "bunlrl",
+
+/* extended m for cr logic */
+0,     OP_BT_BT_BT,  19<<26 | 289<<1,                           "crset",
+0,     OP_BT_BT_BT,  19<<26 | 193<<1,                           "crclr",
+0,     OP_BT_BA_BA,  19<<26 | 449<<1,                           "crmove",
+0,     OP_BT_BA_BA,  19<<26 | 33<<1,                            "crnot",
+
 /* Fixed point instructions (page 29) */
 
 0,     OP_RT_RA_D,            34<<26,                                  "lbz",
 0,     OP_RT_RA_RB_C,         31<<26 | 1<<10 | 40<<1,                  "subfo",
 0,     OP_RT_RA_SI_addic,     12<<26,                                  "addic", /* special case C */
 0,     OP_RT_RA_SI,           8<<26,                                   "subfic",
+0,     OP_RT_RA_RB_C,         31<<26 | 0<<10 | 10<<1,                  "addc",
+0,     OP_RT_RA_RB_C,         31<<26 | 1<<10 | 10<<1,                  "addco",
+0,     OP_RT_RA_RB_C,         31<<26 | 0<<10 | 8<<1,                   "subfc",
+0,     OP_RT_RA_RB_C,         31<<26 | 1<<10 | 8<<1,                   "subfco",
 0,     OP_RT_RA_RB_C,         31<<26 | 0<<10 | 138<<1,                 "adde",
 0,     OP_RT_RA_RB_C,         31<<26 | 1<<10 | 138<<1,                 "addeo",
 0,     OP_RT_RA_RB_C,         31<<26 | 0<<10 | 136<<1,                 "subfe",
 0,     OP_RT_RA_C,            31<<26 | 0<<10 | 104<<1,                 "neg",
 0,     OP_RT_RA_C,            31<<26 | 1<<10 | 104<<1,                 "nego",
 
+/* extended m for addition */
+0,     OP_RT_RA_D,            14<<26,                       "la",
+0,     OP_RT_SI,              14<<26 | 0<<16,               "li",
+0,     OP_RT_SI,              15<<26 | 0<<16,               "lis",
+
+/* extended m for subtraction */
+0,     OP_RT_RB_RA_C,         31<<26 | 0<<10 | 40<<1,       "sub",
+0,     OP_RT_RB_RA_C,         31<<26 | 1<<10 | 40<<1,       "subo",
+0,     OP_RT_RB_RA_C,         31<<26 | 0<<10 | 8<<1,        "subc",
+0,     OP_RT_RB_RA_C,         31<<26 | 0<<10 | 8<<1,        "subco",
+0,     OP_RT_RA_SI_subi,      14<<26,                       "subi",
+0,     OP_RT_RA_SI_subi,      15<<26,                       "subis",
+0,     OP_RT_RA_SI_subic,     12<<26,                       "subic",
+
 /* page 54 */
 0,     OP_RT_RA_SI,           7<<26,                                   "mulli",
 0,     OP_RT_RA_RB_C,         31<<26 | 0<<10 | 233<<1,                 "mulld",
 0,     OP_BF_L_RA_UI,         10<<26,                                  "cmpli",
 0,     OP_BF_L_RA_RB,         31<<26 | 32<<1,                          "cmpl",
 
+/* extended m for comparison */
+0,     OP_BF_RA_SI,           11<<26 | 1<<21,               "cmpdi",
+0,     OP_BF_RA_RB,           31<<26 | 1<<21 | 0<<1,        "cmpd",
+0,     OP_BF_RA_UI,           10<<26 | 1<<21,               "cmpldi",
+0,     OP_BF_RA_RB,           31<<26 | 1<<21 | 32<<1,       "cmpld",
+0,     OP_BF_RA_SI,           11<<26 | 0<<21,               "cmpwi",
+0,     OP_BF_RA_RB,           31<<26 | 0<<21 | 0<<1,        "cmpw",
+0,     OP_BF_RA_UI,           10<<26 | 0<<21,               "cmplwi",
+0,     OP_BF_RA_RB,           31<<26 | 0<<21 | 32<<1,       "cmplw",
+
 /* page 60 */
 0,     OP_TO_RA_SI,           2<<26,                                   "tdi",
 0,     OP_TO_RA_SI,           3<<26,                                   "twi",
 0,     OP_TO_RA_RB,           31<<26 | 68<<1,                          "td",
 0,     OP_TO_RA_RB,           31<<26 | 4<<1,                           "tw",
 
+/* extended m for traps */
+0,     OP_TOX_RA_RB,          31<<26 | 4<<21 | 68<<1,       "tdeq",
+0,     OP_TOX_RA_SI,          2<<26 | 4<<21,                "tdeqi",
+0,     OP_TOX_RA_RB,          31<<26 | 12<<21 | 68<<1,      "tdge",
+0,     OP_TOX_RA_SI,          2<<26 | 12<<21,               "tdgei",
+0,     OP_TOX_RA_RB,          31<<26 | 8<<21 | 68<<1,       "tdgt",
+0,     OP_TOX_RA_SI,          2<<26 | 8<<21,                "tdgti",
+0,     OP_TOX_RA_RB,          31<<26 | 20<<21 | 68<<1,      "tdle",
+0,     OP_TOX_RA_SI,          2<<26 | 20<<21,               "tdlei",
+0,     OP_TOX_RA_RB,          31<<26 | 5<<21 | 68<<1,       "tdlge",
+0,     OP_TOX_RA_SI,          2<<26 | 5<<21,                "tdlgei",
+0,     OP_TOX_RA_RB,          31<<26 | 1<<21 | 68<<1,       "tdlgt",
+0,     OP_TOX_RA_SI,          2<<26 | 1<<21,                "tdlgti",
+0,     OP_TOX_RA_RB,          31<<26 | 6<<21 | 68<<1,       "tdlle",
+0,     OP_TOX_RA_SI,          2<<26 | 6<<21,                "tdllei",
+0,     OP_TOX_RA_RB,          31<<26 | 2<<21 | 68<<1,       "tdllt",
+0,     OP_TOX_RA_SI,          2<<26 | 2<<21,                "tdllti",
+0,     OP_TOX_RA_RB,          31<<26 | 6<<21 | 68<<1,       "tdlng",
+0,     OP_TOX_RA_SI,          2<<26 | 6<<21,                "tdlngi",
+0,     OP_TOX_RA_RB,          31<<26 | 5<<21 | 68<<1,       "tdlnl",
+0,     OP_TOX_RA_SI,          2<<26 | 5<<21,                "tdlnli",
+0,     OP_TOX_RA_RB,          31<<26 | 16<<21 | 68<<1,      "tdlt",
+0,     OP_TOX_RA_SI,          2<<26 | 16<<21,               "tdlti",
+0,     OP_TOX_RA_RB,          31<<26 | 24<<21 | 68<<1,      "tdne",
+0,     OP_TOX_RA_SI,          2<<26 | 24<<21,               "tdnei",
+0,     OP_TOX_RA_RB,          31<<26 | 20<<21 | 68<<1,      "tdng",
+0,     OP_TOX_RA_SI,          2<<26 | 20<<21,               "tdngi",
+0,     OP_TOX_RA_RB,          31<<26 | 12<<21 | 68<<1,      "tdnl",
+0,     OP_TOX_RA_SI,          2<<26 | 12<<21,               "tdnli",
+0,     OP_TOX_RA_RB,          31<<26 | 31<<21 | 68<<1,      "tdu",
+0,     OP_TOX_RA_SI,          2<<26 | 31<<21,               "tdui",
+0,     OP,                    31<<26 | 31<<21 | 4<<1,       "trap",
+0,     OP_TOX_RA_RB,          31<<26 | 4<<21 | 4<<1,        "tweq",
+0,     OP_TOX_RA_SI,          3<<26 | 4<<21,                "tweqi",
+0,     OP_TOX_RA_RB,          31<<26 | 12<<21 | 4<<1,       "twge",
+0,     OP_TOX_RA_SI,          3<<26 | 12<<21,               "twgei",
+0,     OP_TOX_RA_RB,          31<<26 | 8<<21 | 4<<1,        "twgt",
+0,     OP_TOX_RA_SI,          3<<26 | 8<<21,                "twgti",
+0,     OP_TOX_RA_RB,          31<<26 | 20<<21 | 4<<1,       "twle",
+0,     OP_TOX_RA_SI,          3<<26 | 20<<21,               "twlei",
+0,     OP_TOX_RA_RB,          31<<26 | 5<<21 | 4<<1,        "twlge",
+0,     OP_TOX_RA_SI,          3<<26 | 5<<21,                "twlgei",
+0,     OP_TOX_RA_RB,          31<<26 | 1<<21 | 4<<1,        "twlgt",
+0,     OP_TOX_RA_SI,          3<<26 | 1<<21,                "twlgti",
+0,     OP_TOX_RA_RB,          31<<26 | 6<<21 | 4<<1,        "twlle",
+0,     OP_TOX_RA_SI,          3<<26 | 6<<21,                "twllei",
+0,     OP_TOX_RA_RB,          31<<26 | 2<<21 | 4<<1,        "twllt",
+0,     OP_TOX_RA_SI,          3<<26 | 2<<21,                "twllti",
+0,     OP_TOX_RA_RB,          31<<26 | 6<<21 | 4<<1,        "twlng",
+0,     OP_TOX_RA_SI,          3<<26 | 6<<21,                "twlngi",
+0,     OP_TOX_RA_RB,          31<<26 | 5<<21 | 4<<1,        "twlnl",
+0,     OP_TOX_RA_SI,          3<<26 | 5<<21,                "twlnli",
+0,     OP_TOX_RA_RB,          31<<26 | 16<<21 | 4<<1,       "twlt",
+0,     OP_TOX_RA_SI,          3<<26 | 16<<21,               "twlti",
+0,     OP_TOX_RA_RB,          31<<26 | 24<<21 | 4<<1,       "twne",
+0,     OP_TOX_RA_SI,          3<<26 | 24<<21,               "twnei",
+0,     OP_TOX_RA_RB,          31<<26 | 20<<21 | 4<<1,       "twng",
+0,     OP_TOX_RA_SI,          3<<26 | 20<<21,               "twngi",
+0,     OP_TOX_RA_RB,          31<<26 | 12<<21 | 4<<1,       "twnl",
+0,     OP_TOX_RA_SI,          3<<26 | 12<<21,               "twnli",
+0,     OP_TOX_RA_RB,          31<<26 | 31<<21 | 4<<1,       "twu",
+0,     OP_TOX_RA_SI,          3<<26 | 31<<21,               "twui",
+
 /* page 62 */
 0,     OP_RS_RA_UI_CC,        28<<26,                                  "andi", /* C compulsory */
 0,     OP_RS_RA_UI_CC,        29<<26,                                  "andis", /* C compulsory */
 0,     OP_RS_RA_C,            31<<26 | 58<<1,                          "cntlzd",
 0,     OP_RS_RA_C,            31<<26 | 26<<1,                          "cntlzw",
 
+/* extended m using logic */
+0,     OP_RS_RA_RA_C,         31<<26 | 444<<1,              "mr",
+0,     OP,                    24<<26,                       "nop",
+0,     OP_RS_RA_RA_C,         31<<26 | 124<<1,              "not",
+0,     OP,                    26<<26,                       "xnop",
+
 /* page 69 */
-0,     OP_RS_RA_SH_MB6_SH_C,  30<<26 | 0<<2,                           "rldicl",
-0,     OP_RS_RA_SH_ME6_SH_C,  30<<26 | 1<<2,                           "rldicr",
-0,     OP_RS_RA_SH_MB6_SH_C,  30<<26 | 2<<2,                           "rldic",
-0,     OP_RS_RA_SH_MB5_ME5_C, 21<<26,                                  "rlwinm",
-0,     OP_RS_RA_RB_MB6_C,     30<<26 | 8<<1,                           "rldcl",
-0,     OP_RS_RA_RB_ME6_C,     30<<26 | 9<<1,                           "rldcr",
-0,     OP_RS_RA_RB_MB5_ME5_C, 23<<26,                                  "rlwnm",
-0,     OP_RS_RA_SH_MB6_SH_C,  30<<26 | 3<<2,                           "rldimi",
-0,     OP_RS_RA_SH_MB5_ME5_C, 20<<26,                                  "rlwimi",
+0,     OP_RA_RS_SH6_MB6_C,     30<<26 | 0<<2,               "rldicl",
+0,     OP_RA_RS_SH6_MB6_C,     30<<26 | 1<<2,               "rldicr",
+0,     OP_RA_RS_SH6_MB6_C,     30<<26 | 2<<2,               "rldic",
+0,     OP_RA_RS_SH5_MB5_ME5_C, 21<<26,                      "rlwinm",
+0,     OP_RA_RS_RB_MB6_C,      30<<26 | 8<<1,               "rldcl",
+0,     OP_RA_RS_RB_MB6_C,      30<<26 | 9<<1,               "rldcr",
+0,     OP_RA_RS_RB_MB5_ME5_C,  23<<26,                      "rlwnm",
+0,     OP_RA_RS_SH6_MB6_C,     30<<26 | 3<<2,               "rldimi",
+0,     OP_RA_RS_SH5_MB5_ME5_C, 20<<26,                      "rlwimi",
+
+/* extended m for doubleword rotation */
+0,     OP_clrlsldi,           30<<26 | 2<<2,                "clrlsldi",
+0,     OP_clrldi,             30<<26 | 0<<2,                "clrldi",
+0,     OP_clrrdi,             30<<26 | 1<<2,                "clrrdi",
+0,     OP_extldi,             30<<26 | 0<<2,                "extldi",
+0,     OP_extrdi,             30<<26 | 1<<2,                "extrdi",
+0,     OP_insrdi,             30<<26 | 3<<2,                "insrdi",
+0,     OP_RA_RS_RB_C,         30<<26 | MB6(0) | 8<<1,       "rotld",
+0,     OP_RA_RS_SH6_C,        30<<26 | MB6(0) | 0<<2,       "rotldi",
+0,     OP_rotrdi,             30<<26 | 0<<2,                "rotrdi",
+0,     OP_sldi,               30<<26 | 1<<2,                "sldi",
+0,     OP_srdi,               30<<26 | 0<<2,                "srdi",
+
+/* extended m for word rotation */
+0,     OP_clrlslwi,           21<<26,                       "clrlslwi",
+0,     OP_clrlwi,             21<<26,                       "clrlwi",
+0,     OP_clrrwi,             21<<26,                       "clrrwi",
+0,     OP_extlwi,             21<<26,                       "extlwi",
+0,     OP_extrwi,             21<<26,                       "extrwi",
+0,     OP_inslwi,             20<<26,                       "inslwi",
+0,     OP_insrwi,             20<<26,                       "insrwi",
+0,     OP_RA_RS_RB_C,         23<<26 | 0<<6 | 31<<1,        "rotlw",
+0,     OP_RA_RS_SH5_C,        21<<26 | 0<<6 | 31<<1,        "rotlwi",
+0,     OP_rotrwi,             21<<26,                       "rotrwi",
+0,     OP_slwi,               21<<26,                       "slwi",
+0,     OP_srwi,               21<<26,                       "srwi",
 
 /* page 74 */
-0,     OP_RS_RA_RB_C,         31<<26 | 27<<1,                          "sld",
-0,     OP_RS_RA_RB_C,         31<<26 | 24<<1,                          "slw",
-0,     OP_RS_RA_RB_C,         31<<26 | 539<<1,                         "srd",
-0,     OP_RS_RA_RB_C,         31<<26 | 536<<1,                         "srw",
-0,     OP_RS_RA_SH6_C,        31<<26 | 413<<2,                         "sradi",
-0,     OP_RS_RA_SH5_C,        31<<26 | 824<<1,                         "srawi",
-0,     OP_RS_RA_RB_C,         31<<26 | 794<<1,                         "srad",
-0,     OP_RS_RA_RB_C,         31<<26 | 792<<1,                         "sraw",
+0,     OP_RA_RS_RB_C,         31<<26 | 27<<1,               "sld",
+0,     OP_RA_RS_RB_C,         31<<26 | 24<<1,               "slw",
+0,     OP_RA_RS_RB_C,         31<<26 | 539<<1,              "srd",
+0,     OP_RA_RS_RB_C,         31<<26 | 536<<1,              "srw",
+0,     OP_RA_RS_SH6_C,        31<<26 | 413<<2,              "sradi",
+0,     OP_RA_RS_SH5_C,        31<<26 | 824<<1,              "srawi",
+0,     OP_RA_RS_RB_C,         31<<26 | 794<<1,              "srad",
+0,     OP_RA_RS_RB_C,         31<<26 | 792<<1,              "sraw",
 
 /* page 78 */
 0,     OP_RS_SPR,             31<<26 | 467<<1,                         "mtspr",
 0,     OP_RS_FXM,             31<<26 | 0<<21 | 144<<1,                 "mtcrf",
 0,     OP_RT,                 31<<26 | 0<<21 | 19<<1,                  "mfcr",
 
+/* extended m for special purpose registers */
+0,     OP_RT,       31<<26 | 9<<16 | 0<<11 | 339<<1,        "mfctr",
+0,     OP_RT,       31<<26 | 8<<16 | 0<<11 | 339<<1,        "mflr",
+0,     OP_RT,       31<<26 | 1<<16 | 0<<11 | 339<<1,        "mfxer",
+0,     OP_RT,       31<<26 | 9<<16 | 0<<11 | 467<<1,        "mtctr",
+0,     OP_RT,       31<<26 | 8<<16 | 0<<11 | 467<<1,        "mtlr",
+0,     OP_RT,       31<<26 | 1<<16 | 0<<11 | 467<<1,        "mtxer",
+
 /* Floating point instructions (page 83) */
 
 0,     OP_FRT_RA_D,           48<<26,                                  "lfs",
index 1ad180d..99f7f45 100644 (file)
@@ -4,16 +4,33 @@
  */
 
 operation
-       : OP_BF_BFA            CR ',' CR                  { emit4($1 | ($2<<23) | ($4<<18)); }
+       : OP                                              { emit4($1); }
+       | OP_BDA               bda                        { emit4($1 | $2); }
+       | OP_BDL               bdl                        { emit4($1 | $2); }
+       | OP_BF_BFA            CR ',' CR                  { emit4($1 | ($2<<23) | ($4<<18)); }
        | OP_BF_FRA_FRB        CR ',' FPR ',' FPR         { emit4($1 | ($2<<23) | ($4<<16) | ($6<<11)); }
        | OP_BF_L_RA_RB        CR ',' u1 ',' GPR ',' GPR  { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | ($8<<11)); }
        | OP_BF_L_RA_SI        CR ',' u1 ',' GPR ',' e16  { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); }
        | OP_BF_L_RA_UI        CR ',' u1 ',' GPR ',' e16  { emit4($1 | ($2<<23) | ($4<<21) | ($6<<16) | $8); }
+       | OP_BF_RA_RB          cr_opt GPR ',' GPR         { emit4($1 | ($2<<23) | ($3<<16) | ($5<<11)); }
+       | OP_BF_RA_SI          cr_opt GPR ',' e16         { emit4($1 | ($2<<23) | ($3<<16) | $5); }
+       | OP_BF_RA_UI          cr_opt GPR ',' e16         { emit4($1 | ($2<<23) | ($3<<16) | $5); }
        | OP_BF_U_C            c CR ',' u4                { emit4($1 | $2 | ($3<<23) | ($5<<12)); }
+       | OP_BH                                           { emit4($1); }
+       | OP_BH                u2                         { emit4($1 | ($2<<11)); }
+       | OP_BI_BDA            u5 ',' bda                 { emit4($1 | ($2<<16) | $4); }
+       | OP_BI_BDL            u5 ',' bdl                 { emit4($1 | ($2<<16) | $4); }
+       | OP_BI_BH             u5 opt_bh                  { emit4($1 | ($2<<16) | $3); }
+       | OP_BICR_BDA          cr_opt bda                 { emit4($1 | ($2<<18) | $3); }
+       | OP_BICR_BDL          cr_opt bdl                 { emit4($1 | ($2<<18) | $3); }
+       | OP_BICR_BH                                      { emit4($1); }
+       | OP_BICR_BH           CR opt_bh                  { emit4($1 | ($2<<18) | $3); }
        | OP_BO_BI_BDA         u5 ',' u5 ',' bda          { emit4($1 | ($2<<21) | ($4<<16) | $6); }
        | OP_BO_BI_BDL         u5 ',' u5 ',' bdl          { emit4($1 | ($2<<21) | ($4<<16) | $6); }
-       | OP_BO_BI_BH          u5 ',' u5 ',' u2           { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
+       | OP_BO_BI_BH          u5 ',' u5 opt_bh           { emit4($1 | ($2<<21) | ($4<<16) | $5); }
+       | OP_BT_BA_BA          u5 ',' u5                  { emit4($1 | ($2<<21) | ($4<<16) | ($4<<11)); }
        | OP_BT_BA_BB          u5 ',' u5 ',' u5           { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
+       | OP_BT_BT_BT          u5                         { emit4($1 | ($2<<21) | ($2<<16) | ($2<<11)); }
        | OP_BT_C              c u5                       { emit4($1 | $2 | ($3<<21)); }
        | OP_FLM_FRB_C         c u8 ',' FPR               { emit4($1 | $2 | ($3<<17) | ($5<<11)); }
        | OP_FRS_RA_D          FPR ',' e16 '(' GPR ')'    { emit4($1 | ($2<<21) | ($6<<16) | $4); }
@@ -25,15 +42,35 @@ operation
        | OP_FRT_RA_D          FPR ',' e16 '(' GPR ')'    { emit4($1 | ($2<<21) | ($6<<16) | $4); }
        | OP_FRT_RA_RB         FPR ',' GPR ',' GPR        { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
        | OP_FRT_C             c FPR                      { emit4($1 | $2 | ($3<<21)); }
+       | OP_RA_RS_RB_C        c GPR ',' GPR ',' GPR
+       { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
+       | OP_RA_RS_RB_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5
+       { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) |
+               ($9<<6) | ($11<<1)); }
+       | OP_RA_RS_RB_MB6_C    c GPR ',' GPR ',' GPR ',' u6
+       { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | MB6($9)); }
+       | OP_RA_RS_SH5_C       c GPR ',' GPR ',' u5
+       { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
+       | OP_RA_RS_SH5_MB5_ME5_C c GPR ',' GPR ',' u5 ',' u5 ',' u5
+       { emit4($1 | $2 | ($5<<21) | ($3<<16) |
+               ($7<<11) | ($9<<6) | ($11<<1)); }
+       | OP_RA_RS_SH6_C       c GPR ',' GPR ',' u6
+       { emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($7)); }
+       | OP_RA_RS_SH6_MB6_C   c GPR ',' GPR ',' u6 ',' u6
+       { emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($7) | MB6($9)); }
        | OP_RT                GPR                        { emit4($1 | ($2<<21)); }
        | OP_RT_RA_C           c GPR ',' GPR              { emit4($1 | $2 | ($3<<21) | ($5<<16)); }
        | OP_RT_RA_D           GPR ',' e16 '(' GPR ')'    { emit4($1 | ($2<<21) | ($6<<16) | $4); }
        | OP_RT_RA_DS          GPR ',' ds '(' GPR ')'     { emit4($1 | ($2<<21) | ($6<<16) | $4); }
        | OP_RT_RA_NB          GPR ',' GPR ',' nb         { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
        | OP_RT_RA_RB          GPR ',' GPR ',' GPR        { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
-    | OP_RT_RA_RB_C        c GPR ',' GPR ',' GPR      { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
+       | OP_RT_RA_RB_C        c GPR ',' GPR ',' GPR      { emit4($1 | $2 | ($3<<21) | ($5<<16) | ($7<<11)); }
        | OP_RT_RA_SI          GPR ',' GPR ',' e16        { emit4($1 | ($2<<21) | ($4<<16) | $6); }
        | OP_RT_RA_SI_addic    c GPR ',' GPR ',' e16      { emit4($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); }
+       | OP_RT_RA_SI_subi     GPR ',' GPR ',' negate16   { emit4($1 | ($2<<21) | ($4<<16) | $6); }
+       | OP_RT_RA_SI_subic    c GPR ',' GPR ',' negate16 { emit4($1 | ($2<<26) | ($3<<21) | ($5<<16) | $7); }
+       | OP_RT_RB_RA_C        c GPR ',' GPR ',' GPR      { emit4($1 | $2 | ($3<<21) | ($7<<16) | ($5<<11)); }
+       | OP_RT_SI             GPR ',' e16                { emit4($1 | ($2<<21) | $4); }
        | OP_RT_SPR            GPR ',' spr_num            { emit4($1 | ($2<<21) | ($4<<11)); }
        | OP_RS_FXM            u7 ',' GPR                 { emit4($1 | ($4<<21) | ($2<<12)); }
        | OP_RS_RA_C           c GPR ',' GPR              { emit4($1 | $2 | ($5<<21) | ($3<<16)); }
@@ -45,21 +82,127 @@ operation
        | OP_RS_RA_RB          GPR ',' GPR ',' GPR        { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
        | OP_RS_RA_RB_C        c GPR ',' GPR ',' GPR      { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
        | OP_RS_RA_RA_C        c GPR ',' GPR              { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($5<<11)); }
-       | OP_RS_RA_RB_MB5_ME5_C c GPR ',' GPR ',' GPR ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
-       | OP_RS_RA_RB_MB6_C    c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
-       | OP_RS_RA_RB_ME6_C    c GPR ',' GPR ',' GPR ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | (($9&0x1F)<<6) | (($9&0x20)>>0)); }
-       | OP_RS_RA_SH_MB5_ME5_C c GPR ',' GPR ',' u5 ',' u5 ',' u5 { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11) | ($9<<6) | ($11<<1)); }
-       | OP_RS_RA_SH_MB6_SH_C  c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
-       | OP_RS_RA_SH_ME6_SH_C  c GPR ',' GPR ',' u6 ',' u6 { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | ($9<<6) | (($7&0x20)>>4)); }
-       | OP_RS_RA_SH5_C       c GPR ',' GPR ',' u5       { emit4($1 | $2 | ($5<<21) | ($3<<16) | ($7<<11)); }
-       | OP_RS_RA_SH6_C       c GPR ',' GPR ',' u6       { emit4($1 | $2 | ($5<<21) | ($3<<16) | (($7&0x1F)<<11) | (($7&0x20)>>4)); }
        | OP_RS_SPR            spr_num ',' GPR            { emit4($1 | ($4<<21) | ($2<<11)); }
        | OP_TO_RA_RB          u5 ',' GPR ',' GPR         { emit4($1 | ($2<<21) | ($4<<16) | ($6<<11)); }
        | OP_TO_RA_SI          u5 ',' GPR ',' e16         { emit4($1 | ($2<<21) | ($4<<16) | $6); }
+       | OP_TOX_RA_RB         GPR ',' GPR                { emit4($1 | ($2<<16) | ($4<<11)); }
+       | OP_TOX_RA_SI         GPR ',' e16                { emit4($1 | ($2<<16) | $4); }
+       | OP_LEV                                          { emit4($1); }
        | OP_LEV               u7                         { emit4($1 | ($2<<5)); }
        | OP_LIA               lia                        { emit4($1 | $2); }
        | OP_LIL               lil                        { emit4($1 | $2); }
        | OP_LI32              li32                       /* emitted in subrule */
+       | OP_clrlsldi          c GPR ',' GPR ',' u6 ',' u6
+       {
+               quad mb = ($7 - $9) & 0x3f;
+               fit($9 <= $7);
+               emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($9) | MB6(mb));
+       }
+       | OP_clrldi            c GPR ',' GPR ',' u6
+       {
+               emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(0) | MB6($7));
+       }
+       | OP_clrrdi            c GPR ',' GPR ',' u6
+       {
+               quad me = 63 - $7;
+               emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(0) | MB6(me));
+       }
+       | OP_extldi            c GPR ',' GPR ',' u6 ',' u6
+       {
+               quad me = ($7 - 1) & 0x3f;
+               fit($7 > 0);
+               emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($9) | MB6(me));
+       }
+       | OP_extrdi            c GPR ',' GPR ',' u6 ',' u6
+       {
+               quad sh = ($9 + $7) & 0x3f;
+               quad mb = (64 - $7) & 0x3f;
+               fit($7 > 0);
+               emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(sh) | MB6(mb));
+       }
+       | OP_rotrdi            c GPR ',' GPR ',' u6
+       {
+               quad sh = (64 - $7) & 0x3f;
+               emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(sh) | MB6(0));
+       }
+       | OP_sldi              c GPR ',' GPR ',' u6
+       {
+               quad me = 63 - $7;
+               emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6($7) | MB6(me));
+       }
+       | OP_srdi              c GPR ',' GPR ',' u6
+       {
+               quad sh = (64 - $7) & 0x3f;
+               emit4($1 | $2 | ($5<<21) | ($3<<16) | SH6(sh) | MB6($7));
+       }
+       | OP_clrlslwi          c GPR ',' GPR ',' u5 ',' u5
+       {
+               quad mb = ($7 - $9) & 0x1f;
+               quad me = 31 - $9;
+               fit($9 <= $7);
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     ($9<<11) | (mb<<6) | (me<<1));
+       }
+       | OP_clrlwi            c GPR ',' GPR ',' u5
+       {
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     (0<<11) | ($7<<6) | (31<<1));
+       }
+       | OP_clrrwi            c GPR ',' GPR ',' u5
+       {
+               quad me = 31 - $7;
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     (0<<11) | (0<<6) | (me<<1));
+       }
+       | OP_extlwi            c GPR ',' GPR ',' u5 ',' u5
+       {
+               quad me = ($7 - 1) & 0x1f;
+               fit($7 > 0);
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     ($9<<11) | (0<<6) | (me<<1));
+       }
+       | OP_extrwi            c GPR ',' GPR ',' u5 ',' u5
+       {
+               quad sh = ($9 + $7) & 0x1f;
+               quad mb = (32 - $7) & 0x1f;
+               fit($7 > 0);
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     (sh<<11) | (mb<<6) | (31<<1));
+       }
+       | OP_inslwi            c GPR ',' GPR ',' u5 ',' u5
+       {
+               quad sh = (32 - $9) & 0x1f;
+               quad me = ($9 + $7 - 1) & 0x1f;
+               fit($7 > 0);
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     (sh<<11) | ($9<<6) | (me<<1));
+       }
+       | OP_insrwi            c GPR ',' GPR ',' u5 ',' u5
+       {
+               quad sh = (32 - $9 - $7) & 0x1f;
+               quad me = ($9 + $7 - 1) & 0x1f;
+               fit($7 > 0);
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     (sh<<11) | ($9<<6) | (me<<1));
+       }
+       | OP_rotrwi      c GPR ',' GPR ',' u5
+       {
+               quad sh = (32 - $7) & 0x1f;
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     (sh<<11) | (0<<6) | (31<<1));
+       }
+       | OP_slwi              c GPR ',' GPR ',' u5
+       {
+               quad me = 31 - $7;
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     ($7<<11) | (0<<6) | (me<<1));
+       }
+       | OP_srwi              c GPR ',' GPR ',' u5
+       {
+               quad sh = (32 - $7) & 0x1f;
+               emit4($1 | $2 | ($5<<21) | ($3<<16) |
+                     (sh<<11) | ($7<<6) | (31<<1));
+       }
        ;
 
 c
@@ -80,6 +223,17 @@ e16
        | OP_LO ASC_LPAR expr ASC_RPAR           { $$ = emit_lo(&$3); }
        ;
 
+negate16
+       : absexp
+       {
+               /* To encode subi, we negate the immediate value, then
+                * it must fit as signed 16-bit. */
+               $$ = -$1;
+               fit(fitx($$, 16));
+               $$ = (uint16_t) $$;
+       }
+       ;
+
 u8
        : absexp
        {
@@ -143,6 +297,19 @@ u2
        }
        ;
 
+/* Optional comma, branch hint. */
+opt_bh
+       : /* nothing */         { $$ = 0; }
+       | ',' u2                { $$ = ($2<<11); }
+
+/*
+ * Optional condition register, comma.  This checks if the token is a
+ * CR register name.  This wouldn't work if we allowed CR as a number.
+ */
+cr_opt
+       : /* nothing */         { $$ = 0; }
+       | CR ','                { $$ = $1; }
+
 ds
        : e16
        {
@@ -251,14 +418,3 @@ spr_num
                $$ = ($1 >> 5) | (($1 & 0x1f) << 5);
        }
        ;
-
-powerpcfixup
-       : expr
-       {
-               quad type = $1.typ & S_TYP;
-               quad val = $1.val;
-               if (type == S_ABS)
-                       serror(".powerpcfixup is useless on absolute values");
-               newrelo($1.typ, RELOPPC | FIXUPFLAGS);
-       }
-       ;