snapshot
authorDoug Evans <dje@google.com>
Fri, 16 Jan 1998 22:21:16 +0000 (22:21 +0000)
committerDoug Evans <dje@google.com>
Fri, 16 Jan 1998 22:21:16 +0000 (22:21 +0000)
opcodes/txvu-opc.c

index bd64df53f643f980a69696fce2cbf4797b1aa476..07badf101faa6b683bd7dbd267f53d5611d56d02 100644 (file)
@@ -60,14 +60,31 @@ PRINT_FN (vfreg);
 PARSE_FN (bc);
 PRINT_FN (bc);
 
-PARSE_FN (ftregbc);
-PRINT_FN (ftregbc);
+PARSE_FN (bcftreg);
+PRINT_FN (bcftreg);
 
 PARSE_FN (accdest);
 PRINT_FN (accdest);
 
 PARSE_FN (xyz);
 
+PARSE_FN (ireg);
+PRINT_FN (ireg);
+
+PARSE_FN (freg);
+PRINT_FN (freg);
+
+PARSE_FN (ffstreg);
+INSERT_FN (ffstreg);
+EXTRACT_FN (ffstreg);
+PRINT_FN (ffstreg);
+
+PARSE_FN (vi01);
+PRINT_FN (vi01);
+
+INSERT_FN (limm12);
+EXTRACT_FN (limm12);
+
 /* Various types of TXVU operands, including insn suffixes.
 
    Fields are:
@@ -83,40 +100,80 @@ const struct txvu_operand txvu_operands[] =
 #define UNUSED 128
   { 0 },
 
+  /* Upper word operands.  */
+
   /* Destination indicator, with leading '.'.  */
-#define DOTDEST (UNUSED + 1)
+#define UDOTDEST (UNUSED + 1)
   { 4, TXVU_SHIFT_DEST, TXVU_OPERAND_SUFFIX,
       parse_dotdest, insert_dotdest, extract_dotdest, print_dotdest },
 
   /* ft reg */
-#define FTREG (DOTDEST + 1)
+#define UVFTREG (UDOTDEST + 1)
   { 5, TXVU_SHIFT_FTREG, 0, parse_vfreg, 0, 0, print_vfreg },
 
   /* fs reg */
-#define FSREG (FTREG + 1)
+#define UVFSREG (UVFTREG + 1)
   { 5, TXVU_SHIFT_FSREG, 0, parse_vfreg, 0, 0, print_vfreg },
 
   /* fd reg */
-#define FDREG (FSREG + 1)
+#define UVFDREG (UVFSREG + 1)
   { 5, TXVU_SHIFT_FDREG, 0, parse_vfreg, 0, 0, print_vfreg },
 
   /* broadcast */
-#define BC (FDREG + 1)
+#define UBC (UVFDREG + 1)
   { 2, 0, 0, parse_bc, 0, 0, print_bc },
 
   /* ftreg in broadcast case */
-#define FTREGBC (BC + 1)
-  { 5, TXVU_SHIFT_FTREG, 0, parse_ftregbc, 0, 0, print_ftregbc },
+#define UBCFTREG (UBC + 1)
+  { 5, TXVU_SHIFT_FTREG, 0, parse_bcftreg, 0, 0, print_bcftreg },
 
   /* accumulator dest */
-#define ACCDEST (FTREGBC + 1)
+#define UACCDEST (UBCFTREG + 1)
   { 0, 0, TXVU_OPERAND_FAKE, parse_accdest, 0, 0, print_accdest },
 
   /* The XYZ operand is a fake one that is used to ensure only "xyz" is
      specified.  It simplifies the opmula and opmsub entries.  */
-#define XYZ (FDREG + 1)
+#define UXYZ (UACCDEST + 1)
   { 0, 0, TXVU_OPERAND_FAKE, parse_xyz, 0, 0, 0 },
 
+  /* Lower word operands.  */
+
+  /* 11 bit immediate.  */
+#define LIMM11 (UXYZ + 1)
+  { 11, 0, 0, 0, 0, 0, 0 },
+
+  /* IS register.  */
+#define LISREG (LIMM11 + 1)
+  { 5, 11, 0, parse_ireg, 0, 0, print_ireg },
+
+  /* IT register.  */
+#define LITREG (LISREG + 1)
+  { 5, 16, 0, parse_ireg, 0, 0, print_ireg },
+
+  /* FS reg, with FSF field selector.  */
+#define LFSFFSREG (LITREG + 1)
+  { 5, 11, 0, parse_ffstreg, insert_ffstreg, extract_ffstreg, print_ffstreg },
+
+  /* FS reg, no selector (choice of x,y,z,w is provided by opcode).  */
+#define LFSREG (LFSFFSREG + 1)
+  { 5, 11, 0, parse_freg, 0, 0, print_freg },
+
+  /* FT reg, with FTF field selector.  */
+#define LFTFFTREG (LFSREG + 1)
+  { 5, 16, 0, parse_ffstreg, insert_ffstreg, extract_ffstreg, print_ffstreg },
+
+  /* VI01 register.  */
+#define LVI01 (LFTFFTREG + 1)
+  { 0, 0, TXVU_OPERAND_FAKE, parse_vi01, 0, 0, print_vi01 },
+
+  /* 24 bit immediate.  */
+#define LIMM24 (LVI01 + 1)
+  { 24, 0, 0, 0, 0, 0, 0 },
+
+  /* 12 bit immediate, split into 1 and 11 bit pieces.  */
+#define LIMM12 (LIMM24 + 1)
+  { 12, 0, 0, 0, insert_limm12, extract_limm12, 0 },
+
 /* end of list place holder */
   { 0 }
 };
@@ -124,46 +181,77 @@ const struct txvu_operand txvu_operands[] =
 /* Macros to put a field's value into the right place.  */
 /* FIXME: If assembler needs these, move to opcode/txvu.h.  */
 
-#define R(x,b,m) (((x) & (m)) << (b))  /* value X, mask M, at bit B */
+/* value X, B bits, shift S */
+#define R(x,b,s) (((x) & ((1 << (b)) - 1)) << (s))
+
+/* Upper instruction Value macros.  */
 
 /* Upper Flag bits.  */
-#define UF(x) R ((x), 27, 31)
+#define VUF(x) R ((x), 5, 27)
 /* Upper REServed two bits next to flag bits.  */
-#define URES(x) R ((x), 25, 3)
-/* The DEST field.  */
-#define UDEST(x) R ((x), 21, 15)
-/* The FT reg field.  */
-#define UFT(x) R ((x), TXVU_SHIFT_FTREG, TXVU_MASK_VFREG)
-/* The FS reg field.  */
-#define UFS(x) R ((x), TXVU_SHIFT_FSREG, TXVU_MASK_VFREG)
-/* The FD reg field.  */
-#define UFD(x) R ((x), TXVU_SHIFT_FDREG, TXVU_MASK_VFREG)
-/* The 4 bit opcode field.  */
-#define UOP4(x) R ((x), 2, 15)
-/* The 6 bit opcode field.  */
-#define UOP6(x) R ((x), 0, 63)
-/* The 9 bit opcode field.  */
-#define UOP9(x) R ((x), 2, 0x1ff)
-/* The 11 bit opcode field.  */
-#define UOP11(x) R ((x), 0, 0x7ff)
-/* The BroadCast field.  */
-#define UBC(x) R ((x), 0, 3)
-
-/* Macros for special field values.  */
-/* The upper 7 bits of the upper word.  */
-#define UUBITS (UF (0) + URES (0))
-/* Mask for UBITS.  */
-#define MUUBITS (UF (~0) + URES (~0))
-/* Mask for URES.  */
-#define MURES URES (~0)
-/* Mask for OP4.  */
-#define MUOP4 UOP4 (~0)
-/* Mask for OP6.  */
-#define MUOP6 UOP6 (~0)
-/* Mask for OP9.  */
-#define MUOP9 UOP9 (~0)
-/* Mask for OP11.  */
-#define MUOP11 UOP11 (~0)
+#define VURES(x) R ((x), 2, 25)
+/* DEST field.  */
+#define VUDEST(x) R ((x), 4, 21)
+/* FT reg field.  */
+#define VUFT(x) R ((x), 5, TXVU_SHIFT_FTREG)
+/* FS reg field.  */
+#define VUFS(x) R ((x), 5, TXVU_SHIFT_FSREG)
+/* FD reg field.  */
+#define VUFD(x) R ((x), 5, TXVU_SHIFT_FDREG)
+/* 4 bit opcode field.  */
+#define VUOP4(x) R ((x), 4, 2)
+/* 6 bit opcode field.  */
+#define VUOP6(x) R ((x), 6, 0)
+/* 9 bit opcode field.  */
+#define VUOP9(x) R ((x), 9, 2)
+/* 11 bit opcode field.  */
+#define VUOP11(x) R ((x), 11, 0)
+/* BroadCast field.  */
+#define VUBC(x) R ((x), 2, 0)
+
+/* Field masks.  */
+#define MUUBITS (VUF (~0) + VURES (~0))
+#define MURES VURES (~0)
+#define MUOP4 VUOP4 (~0)
+#define MUOP6 VUOP6 (~0)
+#define MUOP9 VUOP9 (~0)
+#define MUOP11 VUOP11 (~0)
+
+/* Lower instruction Value macros.  */
+
+/* 7 bit opcode.  */
+#define VLOP7(x) R ((x), 7, 25)
+/* 11 bit opcode.  */
+#define VLOP11(x) R ((x), 11, 0)
+/* dest field.  */
+#define VLDEST(x) R ((x), 4, 21)
+/* IT reg.  */
+#define VLIT(x) R ((x), 5, 16)
+/* IS reg.  */
+#define VLIS(x) R ((x), 5, 11)
+/* 11 bit immediate.  */
+#define VLIMM11(x) R ((x), 11, 0)
+/* FTF field.  */
+#define VLFTF(x) R ((x), 2, 23)
+/* FSF field.  */
+#define VLFSF(x) R ((x), 2, 21)
+/* FT reg.  */
+#define VLFT(x) R ((x), 5, 16)
+/* FS reg.  */
+#define VLFS(x) R ((x), 5, 11)
+
+/* Field masks.  */
+#define MLOP7 VLOP7 (~0)
+#define MLOP11 VLOP11 (~0)
+#define MLDEST VLDEST (~0)
+#define MLIT VLIT (~0)
+#define MLIS VLIS (~0)
+#define MLIMM11 VLIMM11 (~0)
+#define MLB24 R (1, 1, 24)
+/* 12 bit immediates are split into two parts, 1 bit and 11 bits.
+   The upper 1 bit is part of the `dest' field.  This mask is for the
+   other 3 bits of the dest field.  */
+#define MLIMM12TOP R (7, 3, 22)
 
 /* A space, separates instruction name (mnemonic + mnemonic operands) from operands.  */
 #define SP ' '
@@ -196,68 +284,69 @@ struct txvu_opcode txvu_upper_opcodes[] = {
 
   /* Macros appear first.  */
   /* ??? Any aliases?  */
+  /* FIXME: When close to being finished, clean up by aligning fields.  */
 
   /* The rest of these needn't be sorted, but it helps to find them if they are.  */
-  { "abs", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x1fd) },
-  { "add", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x28) },
-  { "addi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x22) },
-  { "addq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x20) },
-  { "add", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + UOP4 (~0), UOP4 (0) },
-  { "adda", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2bc) },
-  { "addai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x23e) },
-  { "addaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x23c) },
-  { "adda", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0xf) },
-  { "clip", { DOTDEST, SP, FSREG }, MURES + UDEST (~0) + UFT (~0) + MUOP11, UDEST (0xf) + UOP11 (0x1ff) },
-  { "ftoi0", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x17c) },
-  { "ftoi4", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x17d) },
-  { "ftoi12", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x17e) },
-  { "ftoi15", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x17f) },
-  { "itof0", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x13c) },
-  { "itof4", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x13d) },
-  { "itof12", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x13e) },
-  { "itof15", { DOTDEST, SP, FTREG, FSREG }, MURES + MUOP11, UOP11 (0x13f) },
-  { "madd", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x29) },
-  { "maddi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x23) },
-  { "maddq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x21) },
-  { "madd", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + MUOP4, UOP4 (0x2) },
-  { "madda", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2bd) },
-  { "maddai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x23f) },
-  { "maddaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x23d) },
-  { "madda", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0x2f) },
-  { "max", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2b) },
-  { "maxi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x2d) },
-  { "max", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + MUOP4, UOP4 (0x4) },
+  { "abs", { UDOTDEST, SP, UVFTREG, UVFSREG }, MURES + MUOP11, VUOP11 (0x1fd) },
+  { "add", { UDOTDEST, SP, UVFDREG, UVFSREG, UVFTREG }, MURES + MUOP6, VUOP6 (0x28) },
+  { "addi", { UDOTDEST, SP, UVFDREG, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x22) },
+  { "addq", { UDOTDEST, SP, UVFDREG, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x20) },
+  { "add", { UBC, UDOTDEST, SP, UVFDREG, UVFSREG, UBCFTREG }, MURES + VUOP4 (~0), VUOP4 (0) },
+  { "adda", { UDOTDEST, SP, UACCDEST, UVFSREG, UVFTREG }, MURES + MUOP11, VUOP11 (0x2bc) },
+  { "addai", { UDOTDEST, SP, UACCDEST, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x23e) },
+  { "addaq", { UDOTDEST, SP, UACCDEST, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x23c) },
+  { "adda", { UBC, UDOTDEST, SP, UACCDEST, UVFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0xf) },
+  { "clip", { UDOTDEST, SP, UVFSREG }, MURES + VUDEST (~0) + VUFT (~0) + MUOP11, VUDEST (0xf) + VUOP11 (0x1ff) },
+  { "ftoi0", { UDOTDEST, SP, UVFTREG, UVFSREG }, MURES + MUOP11, VUOP11 (0x17c) },
+  { "ftoi4", { UDOTDEST, SP, UVFTREG, UVFSREG }, MURES + MUOP11, VUOP11 (0x17d) },
+  { "ftoi12", { UDOTDEST, SP, UVFTREG, UVFSREG }, MURES + MUOP11, VUOP11 (0x17e) },
+  { "ftoi15", { UDOTDEST, SP, UVFTREG, UVFSREG }, MURES + MUOP11, VUOP11 (0x17f) },
+  { "itof0", { UDOTDEST, SP, UVFTREG, UVFSREG }, MURES + MUOP11, VUOP11 (0x13c) },
+  { "itof4", { UDOTDEST, SP, UVFTREG, UVFSREG }, MURES + MUOP11, VUOP11 (0x13d) },
+  { "itof12", { UDOTDEST, SP, UVFTREG, UVFSREG }, MURES + MUOP11, VUOP11 (0x13e) },
+  { "itof15", { UDOTDEST, SP, UVFTREG, UVFSREG }, MURES + MUOP11, VUOP11 (0x13f) },
+  { "madd", { UDOTDEST, SP, UVFDREG, UVFSREG, UVFTREG }, MURES + MUOP6, VUOP6 (0x29) },
+  { "maddi", { UDOTDEST, SP, UVFDREG, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x23) },
+  { "maddq", { UDOTDEST, SP, UVFDREG, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x21) },
+  { "madd", { UBC, UDOTDEST, SP, UVFDREG, UVFSREG, UBCFTREG }, MURES + MUOP4, VUOP4 (0x2) },
+  { "madda", { UDOTDEST, SP, UACCDEST, UVFSREG, UVFTREG }, MURES + MUOP11, VUOP11 (0x2bd) },
+  { "maddai", { UDOTDEST, SP, UACCDEST, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x23f) },
+  { "maddaq", { UDOTDEST, SP, UACCDEST, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x23d) },
+  { "madda", { UBC, UDOTDEST, SP, UACCDEST, UVFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0x2f) },
+  { "max", { UDOTDEST, SP, UVFDREG, UVFSREG, UVFTREG }, MURES + MUOP6, VUOP6 (0x2b) },
+  { "maxi", { UDOTDEST, SP, UVFDREG, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x2d) },
+  { "max", { UBC, UDOTDEST, SP, UVFDREG, UVFSREG, UBCFTREG }, MURES + MUOP4, VUOP4 (0x4) },
   /* FIXME: mini or min? */
-  { "mini", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2f) },
-  { "mini", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x1f) },
-  { "mini", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + MUOP4, UOP4 (0x5) },
-  { "msub", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2d) },
-  { "msubi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x27) },
-  { "msubq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x25) },
-  { "msub", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + MUOP4, UOP4 (0x3) },
-  { "msuba", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2fd) },
-  { "msubai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x27f) },
-  { "msubaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x27d) },
-  { "msuba", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0x3f) },
-  { "mul", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2a) },
-  { "muli", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x1e) },
-  { "mulq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x1c) },
-  { "mul", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + UOP4 (~0), UOP4 (6) },
-  { "mula", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2be) },
-  { "mulai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x1fe) },
-  { "mulaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x1fc) },
-  { "mula", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0x6f) },
-  { "nop", { 0 }, MURES + UDEST (~0) + UFT (~0) + UFS (~0) + MUOP11, UOP11 (0x2ff) },
-  { "opmula", { DOTDEST, SP, ACCDEST, FSREG, FTREG, XYZ }, MURES + MUOP11, UOP11 (0x2fe) },
-  { "opmsub", { DOTDEST, SP, FDREG, FSREG, FTREG, XYZ }, MURES + MUOP6, UOP6 (0x2e) },
-  { "sub", { DOTDEST, SP, FDREG, FSREG, FTREG }, MURES + MUOP6, UOP6 (0x2c) },
-  { "subi", { DOTDEST, SP, FDREG, FSREG, 'i' }, MURES + UFT (~0) + MUOP6, UOP6 (0x26) },
-  { "subq", { DOTDEST, SP, FDREG, FSREG, 'q' }, MURES + UFT (~0) + MUOP6, UOP6 (0x24) },
-  { "sub", { BC, DOTDEST, SP, FDREG, FSREG, FTREGBC }, MURES + UOP4 (~0), UOP4 (1) },
-  { "suba", { DOTDEST, SP, ACCDEST, FSREG, FTREG }, MURES + MUOP11, UOP11 (0x2fc) },
-  { "subai", { DOTDEST, SP, ACCDEST, FSREG, 'i' }, MURES + UFT (~0) + MUOP11, UOP11 (0x27e) },
-  { "subaq", { DOTDEST, SP, ACCDEST, FSREG, 'q' }, MURES + UFT (~0) + MUOP11, UOP11 (0x27c) },
-  { "suba", { BC, DOTDEST, SP, ACCDEST, FSREG, FTREGBC }, MURES + MUOP9, UOP9 (0x1f) }
+  { "mini", { UDOTDEST, SP, UVFDREG, UVFSREG, UVFTREG }, MURES + MUOP6, VUOP6 (0x2f) },
+  { "mini", { UDOTDEST, SP, UVFDREG, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x1f) },
+  { "mini", { UBC, UDOTDEST, SP, UVFDREG, UVFSREG, UBCFTREG }, MURES + MUOP4, VUOP4 (0x5) },
+  { "msub", { UDOTDEST, SP, UVFDREG, UVFSREG, UVFTREG }, MURES + MUOP6, VUOP6 (0x2d) },
+  { "msubi", { UDOTDEST, SP, UVFDREG, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x27) },
+  { "msubq", { UDOTDEST, SP, UVFDREG, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x25) },
+  { "msub", { UBC, UDOTDEST, SP, UVFDREG, UVFSREG, UBCFTREG }, MURES + MUOP4, VUOP4 (0x3) },
+  { "msuba", { UDOTDEST, SP, UACCDEST, UVFSREG, UVFTREG }, MURES + MUOP11, VUOP11 (0x2fd) },
+  { "msubai", { UDOTDEST, SP, UACCDEST, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x27f) },
+  { "msubaq", { UDOTDEST, SP, UACCDEST, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x27d) },
+  { "msuba", { UBC, UDOTDEST, SP, UACCDEST, UVFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0x3f) },
+  { "mul", { UDOTDEST, SP, UVFDREG, UVFSREG, UVFTREG }, MURES + MUOP6, VUOP6 (0x2a) },
+  { "muli", { UDOTDEST, SP, UVFDREG, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x1e) },
+  { "mulq", { UDOTDEST, SP, UVFDREG, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x1c) },
+  { "mul", { UBC, UDOTDEST, SP, UVFDREG, UVFSREG, UBCFTREG }, MURES + VUOP4 (~0), VUOP4 (6) },
+  { "mula", { UDOTDEST, SP, UACCDEST, UVFSREG, UVFTREG }, MURES + MUOP11, VUOP11 (0x2be) },
+  { "mulai", { UDOTDEST, SP, UACCDEST, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x1fe) },
+  { "mulaq", { UDOTDEST, SP, UACCDEST, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x1fc) },
+  { "mula", { UBC, UDOTDEST, SP, UACCDEST, UVFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0x6f) },
+  { "nop", { 0 }, MURES + VUDEST (~0) + VUFT (~0) + VUFS (~0) + MUOP11, VUOP11 (0x2ff) },
+  { "opmula", { UDOTDEST, SP, UACCDEST, UVFSREG, UVFTREG, UXYZ }, MURES + MUOP11, VUOP11 (0x2fe) },
+  { "opmsub", { UDOTDEST, SP, UVFDREG, UVFSREG, UVFTREG, UXYZ }, MURES + MUOP6, VUOP6 (0x2e) },
+  { "sub", { UDOTDEST, SP, UVFDREG, UVFSREG, UVFTREG }, MURES + MUOP6, VUOP6 (0x2c) },
+  { "subi", { UDOTDEST, SP, UVFDREG, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x26) },
+  { "subq", { UDOTDEST, SP, UVFDREG, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP6, VUOP6 (0x24) },
+  { "sub", { UBC, UDOTDEST, SP, UVFDREG, UVFSREG, UBCFTREG }, MURES + VUOP4 (~0), VUOP4 (1) },
+  { "suba", { UDOTDEST, SP, UACCDEST, UVFSREG, UVFTREG }, MURES + MUOP11, VUOP11 (0x2fc) },
+  { "subai", { UDOTDEST, SP, UACCDEST, UVFSREG, 'i' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x27e) },
+  { "subaq", { UDOTDEST, SP, UACCDEST, UVFSREG, 'q' }, MURES + VUFT (~0) + MUOP11, VUOP11 (0x27c) },
+  { "suba", { UBC, UDOTDEST, SP, UACCDEST, UVFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0x1f) }
 };
 const int txvu_upper_opcodes_count = sizeof (txvu_upper_opcodes) / sizeof (txvu_opcodes[0]);
 
@@ -266,10 +355,37 @@ struct txvu_opcode txvu_lower_opcodes[] = {
   /* Macros appear first.  */
   /* ??? Any aliases?  */
 
-  /* The rest of these needn't be sorted, but it helps to find them if they
-     are.  */
-  { "waitp", { 0 }, 0xffffffff, 0x800007bf, 0 },
-  { "waitq", { 0 }, 0xffffffff, 0x800003bf, 0 },
+  /* The rest of these needn't be sorted, but it helps to find them if they are.  */
+  { "b", { SP, LIMM11 }, MLOP7 + MLDEST + MLIT + MLIS, VLOP7 (0x20) },
+  { "bal", { SP, LITREG, LIMM11 }, MLOP7 + MLDEST + MLIS, VLOP7 (0x21) },
+  { "div", { 'q', LFSFFSREG, LFTFFTREG }, MLOP7 + MLOP11, VLOP7 (0x40) + VLOP11 (0x3bc) },
+  { "eatan", { 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLOP11 (0x7fd) },
+  { "eatanxy", { 'p', LFSREG }, MLOP7 + MLDEST + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLDEST (0xf) + VLOP11 (0x77c) },
+  { "eatanxz", { 'p', LFSREG }, MLOP7 + MLDEST + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLDEST (0xf) + VLOP11 (0x77d) },
+  { "eexp", { 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLOP11 (0x7fe) },
+  { "eleng", { 'p', LFSREG }, MLOP7 + MLDEST + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLDEST (0xf) + VLOP11 (0x74e) },
+  { "ercpr", { 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLOP11 (0x7be) },
+  { "erleng", { 'p', LFSREG }, MLOP7 + MLDEST + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLDEST (0xf) + VLOP11 (0x73f) },
+  { "ersadd", { 'p', LFSREG }, MLOP7 + MLDEST + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLDEST (0xf) + VLOP11 (0x73d) },
+  { "ersqrt", { 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLOP11 (0x7bd) },
+  { "esadd", { 'p', LFSREG }, MLOP7 + MLDEST + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLDEST (0xf) + VLOP11 (0x73c) },
+  { "esin", { 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLOP11 (0x7fc) },
+  { "esqrt", { 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLOP11 (0x7bc) },
+  { "esum", { 'p', LFSREG }, MLOP7 + MLDEST + VLFT (~0) + MLOP11, VLOP7 (0x40) + VLDEST (0xf) + VLOP11 (0x77e) },
+  { "fcand", { LVI01, LIMM24 }, MLOP7 + MLB24, VLOP7 (0x12) },
+  { "fceq", { LVI01, LIMM24 }, MLOP7 + MLB24, VLOP7 (0x10) },
+  { "fcget", { LITREG }, MLOP7 + MLDEST + MLIS + MLIMM11, VLOP7 (0x1c) },
+  { "fcor", { LVI01, LIMM24 }, MLOP7 + MLB24, VLOP7 (0x13) },
+  { "fcset", { LVI01, LIMM24 }, MLOP7 + MLB24, VLOP7 (0x11) },
+  { "fmand", { LITREG, LISREG }, MLOP7 + MLDEST + MLIMM11, VLOP7 (0x1a) },
+  { "fmeq", { LITREG, LISREG }, MLOP7 + MLDEST + MLIMM11, VLOP7 (0x18) },
+  { "fmor", { LITREG, LISREG }, MLOP7 + MLDEST + MLIMM11, VLOP7 (0x1b) },
+  { "fsand", { LITREG, LIMM12 }, MLOP7 + MLIMM12TOP + MLIS, VLOP7 (0x16) },
+  { "fseq", { LITREG, LIMM12 }, MLOP7 + MLIMM12TOP + MLIS, VLOP7 (0x14) },
+  { "fsor", { LITREG, LIMM12 }, MLOP7 + MLIMM12TOP + MLIS, VLOP7 (0x17) },
+  { "fsset", { LITREG, LIMM12 }, MLOP7 + MLIMM12TOP + MLIS, VLOP7 (0x15) },
+  { "waitp", { 0 }, 0xffffffff, 0x800007bf },
+  { "waitq", { 0 }, 0xffffffff, 0x800003bf },
 };
 const int txvu_lower_opcodes_count = sizeof (txvu_lower_opcodes) / sizeof (txvu_opcodes[0]);
 
@@ -607,7 +723,7 @@ print_bc (info, insn, value)
 /* FT register in broadcast case.  */
 
 static long
-parse_ftregbc (pstr, errmsg)
+parse_bcftreg (pstr, errmsg)
      char **pstr;
      const char **errmsg;
 {
@@ -642,7 +758,7 @@ parse_ftregbc (pstr, errmsg)
 }
 
 static void
-print_ftregbc (info, insn, value)
+print_bcftreg (info, insn, value)
      disassemble_info *info;
      TXVU_INSN insn;
      long value;
@@ -710,3 +826,240 @@ parse_xyz (pstr, errmsg)
     }
   return 0;
 }
+\f
+/* F[ST] register using selector in F[ST]F field.  */
+
+static long
+parse_ffstreg (pstr, errmsg)
+     char **pstr;
+     const char **errmsg;
+{
+  char *str = *pstr;
+  char *start;
+  long reg;
+  int reg_bc;
+
+  if (tolower (str[0]) != 'v'
+      || tolower (str[1]) != 'f')
+    {
+      *errmsg = "unknown register";
+      return 0;
+    }
+
+  /* FIXME: quick hack until the framework works.  */
+  start = str = str + 2;
+  while (*str && isdigit (*str))
+    ++str;
+  reg = atoi (start);
+  reg_bc = parse_bc (&str, errmsg);
+  if (*errmsg)
+    return 0;
+  if (reg_bc != bc)
+    {
+      *errmsg = "register `bc' does not match instruction `bc'";
+      return 0;
+    }
+  *pstr = str;
+  *errmsg = NULL;
+  return reg;
+}
+
+static void
+print_ffstreg (info, insn, value)
+     disassemble_info *info;
+     TXVU_INSN insn;
+     long value;
+{
+  (*info->fprintf_func) (info->stream, "vf%ld", value);
+  print_bc (info, insn, bc);
+}
+
+#define INSERT_FN(fn) \
+static TXVU_INSN CONCAT2 (insert_,fn) \
+     PARAMS ((TXVU_INSN, const struct txvu_operand *, \
+             int, long, const char **))
+#define EXTRACT_FN(fn) \
+static long CONCAT2 (extract_,fn) \
+     PARAMS ((TXVU_INSN, const struct txvu_operand *, \
+             int, int *))
+
+static TXVU_INSN
+insert_ffstreg (insn, operand, mods, value, errmsg)
+     TXVU_INSN insn;
+     const struct txvu_operand *operand;
+     int mods;
+     long value;
+     const char **errmsg;
+{
+}
+
+static long
+extract_ffstreg (insn, operand, mods, pinvalid)
+     TXVU_INSN insn;
+     const struct txvu_operand *operand;
+     int mods;
+     int *pinvalid;
+{
+}
+\f
+/* F register.  */
+
+static long
+parse_freg (pstr, errmsg)
+     char **pstr;
+     const char **errmsg;
+{
+  char *str = *pstr;
+  char *start;
+  long reg;
+  int reg_bc;
+
+  if (tolower (str[0]) != 'v'
+      || tolower (str[1]) != 'f')
+    {
+      *errmsg = "unknown register";
+      return 0;
+    }
+
+  /* FIXME: quick hack until the framework works.  */
+  start = str = str + 2;
+  while (*str && isdigit (*str))
+    ++str;
+  reg = atoi (start);
+  reg_bc = parse_bc (&str, errmsg);
+  if (*errmsg)
+    return 0;
+  if (reg_bc != bc)
+    {
+      *errmsg = "register `bc' does not match instruction `bc'";
+      return 0;
+    }
+  *pstr = str;
+  *errmsg = NULL;
+  return reg;
+}
+
+static void
+print_freg (info, insn, value)
+     disassemble_info *info;
+     TXVU_INSN insn;
+     long value;
+{
+  (*info->fprintf_func) (info->stream, "vf%ld", value);
+  print_bc (info, insn, bc);
+}
+\f
+/* I register.  */
+
+static long
+parse_ireg (pstr, errmsg)
+     char **pstr;
+     const char **errmsg;
+{
+  char *str = *pstr;
+  char *start;
+  long reg;
+  int reg_bc;
+
+  if (tolower (str[0]) != 'v'
+      || tolower (str[1]) != 'f')
+    {
+      *errmsg = "unknown register";
+      return 0;
+    }
+
+  /* FIXME: quick hack until the framework works.  */
+  start = str = str + 2;
+  while (*str && isdigit (*str))
+    ++str;
+  reg = atoi (start);
+  reg_bc = parse_bc (&str, errmsg);
+  if (*errmsg)
+    return 0;
+  if (reg_bc != bc)
+    {
+      *errmsg = "register `bc' does not match instruction `bc'";
+      return 0;
+    }
+  *pstr = str;
+  *errmsg = NULL;
+  return reg;
+}
+
+static void
+print_ireg (info, insn, value)
+     disassemble_info *info;
+     TXVU_INSN insn;
+     long value;
+{
+  (*info->fprintf_func) (info->stream, "vf%ld", value);
+  print_bc (info, insn, bc);
+}
+\f
+/* VI01 register.  */
+
+static long
+parse_vi01 (pstr, errmsg)
+     char **pstr;
+     const char **errmsg;
+{
+  char *str = *pstr;
+  char *start;
+  long reg;
+  int reg_bc;
+
+  if (tolower (str[0]) != 'v'
+      || tolower (str[1]) != 'f')
+    {
+      *errmsg = "unknown register";
+      return 0;
+    }
+
+  /* FIXME: quick hack until the framework works.  */
+  start = str = str + 2;
+  while (*str && isdigit (*str))
+    ++str;
+  reg = atoi (start);
+  reg_bc = parse_bc (&str, errmsg);
+  if (*errmsg)
+    return 0;
+  if (reg_bc != bc)
+    {
+      *errmsg = "register `bc' does not match instruction `bc'";
+      return 0;
+    }
+  *pstr = str;
+  *errmsg = NULL;
+  return reg;
+}
+
+static void
+print_vi01 (info, insn, value)
+     disassemble_info *info;
+     TXVU_INSN insn;
+     long value;
+{
+  (*info->fprintf_func) (info->stream, "vf%ld", value);
+  print_bc (info, insn, bc);
+}
+\f
+/* Lower instruction 12 bit immediate.  */
+
+static TXVU_INSN
+insert_limm12 (insn, operand, mods, value, errmsg)
+     TXVU_INSN insn;
+     const struct txvu_operand *operand;
+     int mods;
+     long value;
+     const char **errmsg;
+{
+}
+
+static long
+extract_limm12 (insn, operand, mods, pinvalid)
+     TXVU_INSN insn;
+     const struct txvu_operand *operand;
+     int mods;
+     int *pinvalid;
+{
+}