]> granicus.if.org Git - yasm/commitdiff
Added rest of floating point instructions. Needed to add new action to
authorPeter Johnson <peter@tortall.net>
Sun, 11 Aug 2002 01:07:20 +0000 (01:07 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 11 Aug 2002 01:07:20 +0000 (01:07 -0000)
add to opcode byte 1.

svn path=/trunk/yasm/; revision=683

modules/arch/x86/x86id.re
src/arch/x86/x86id.re

index 050062662d4d56722426621b81ed6790994d7fef..fd624fc42770d8892461dbbd2f1e8eebed2d82ff 100644 (file)
@@ -136,7 +136,8 @@ static unsigned long cpu_enabled = ~CPU_Any;
  *             3 = operand data goes into sign-extended imm field
  *             4 = operand data goes into "spare" field
  *             5 = operand data is added to opcode byte 0
- *             6 = operand data goes into BOTH ea and spare
+ *             6 = operand data is added to opcode byte 1
+ *             7 = operand data goes into BOTH ea and spare
  *                 [special case for imul opcode]
  * The below describes postponed actions: actions which can't be completed at
  * parse-time due to things like EQU and complex expressions.  For these, some
@@ -196,7 +197,8 @@ static unsigned long cpu_enabled = ~CPU_Any;
 #define OPA_SImm       (3<<12)
 #define OPA_Spare      (4<<12)
 #define OPA_Op0Add     (5<<12)
-#define OPA_SpareEA    (6<<12)
+#define OPA_Op1Add     (6<<12)
+#define OPA_SpareEA    (7<<12)
 #define OPA_MASK       (7<<12)
 
 #define OPAP_None      (0<<15)
@@ -726,6 +728,119 @@ static const x86_insn_info sldtmsw_insn[] = {
       {OPT_Reg|OPS_32|OPA_EA, 0, 0} }
 };
 
+/* Floating point instructions - load/store with pop (integer and normal) */
+static const x86_insn_info fldstp_insn[] = {
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xD9, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xDD, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 1, {0xDB, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_80|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xD9, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }
+};
+static const x86_insn_info fildstp_insn[] = {
+    { CPU_FPU, MOD_SpAdd, 0, 1, {0xDF, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_16|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_SpAdd, 0, 1, {0xDB, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xDF, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_64|OPA_EA, 0, 0} }
+};
+static const x86_insn_info fbldstp_insn[] = {
+    { CPU_FPU, MOD_SpAdd, 0, 1, {0xDF, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, 0, 0} }
+};
+/* Floating point instructions - store (normal) */
+static const x86_insn_info fst_insn[] = {
+    { CPU_FPU, 0, 0, 1, {0xD9, 0, 0}, 2, 1, {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, 0, 0, 1, {0xDD, 0, 0}, 2, 1, {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
+    { CPU_FPU, 0, 0, 2, {0xDD, 0xD0, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }
+};
+/* Floating point instructions - exchange (with ST0) */
+static const x86_insn_info fxch_insn[] = {
+    { CPU_FPU, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 2,
+      {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} },
+    { CPU_FPU, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 2,
+      {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} },
+    { CPU_FPU, 0, 0, 2, {0xD9, 0xC9, 0}, 0, 0, {0, 0, 0} }
+};
+/* Floating point instructions - comparisons */
+static const x86_insn_info fcom_insn[] = {
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xD8, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xDC, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 2,
+      {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} }
+};
+/* Floating point instructions - extended comparisons */
+static const x86_insn_info fcom2_insn[] = {
+    { CPU_286|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 2, {0x00, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_286|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 2, {0x00, 0x00, 0}, 0, 2,
+      {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} }
+};
+/* Floating point instructions - arithmetic */
+static const x86_insn_info farith_insn[] = {
+    { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 1, {0xD8, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 1, {0xDC, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 2,
+      {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDC, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPTM_To|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDC, 0x00, 0}, 0, 2,
+      {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} }
+};
+static const x86_insn_info farithp_insn[] = {
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDE, 0x01, 0}, 0, 0, {0, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDE, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDE, 0x00, 0}, 0, 2,
+      {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} }
+};
+/* Floating point instructions - integer arith/store wo pop/compare */
+static const x86_insn_info fiarith_insn[] = {
+    { CPU_FPU, MOD_Op0Add|MOD_SpAdd, 0, 1, {0x04, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_16|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Op0Add|MOD_SpAdd, 0, 1, {0x00, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} }
+};
+/* Floating point instructions - processor control */
+static const x86_insn_info fldnstcw_insn[] = {
+    { CPU_FPU, MOD_SpAdd, 0, 1, {0xD9, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }
+};
+static const x86_insn_info fstcw_insn[] = {
+    { CPU_FPU, 0, 0, 2, {0x9B, 0xD9, 0}, 7, 1,
+      {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }
+};
+static const x86_insn_info fnstsw_insn[] = {
+    { CPU_FPU, 0, 0, 1, {0xDD, 0, 0}, 7, 1,
+      {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} },
+    { CPU_FPU, 0, 0, 2, {0xDF, 0xE0, 0}, 0, 1,
+      {OPT_Areg|OPS_16|OPA_None, 0, 0} }
+};
+static const x86_insn_info fstsw_insn[] = {
+    { CPU_FPU, 0, 0, 2, {0x9B, 0xDD, 0}, 7, 1,
+      {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} },
+    { CPU_FPU, 0, 0, 3, {0x9B, 0xDF, 0xE0}, 0, 1,
+      {OPT_Areg|OPS_16|OPA_None, 0, 0} }
+};
+static const x86_insn_info ffree_insn[] = {
+    { CPU_FPU, MOD_Op0Add, 0, 2, {0x00, 0xC0, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }
+};
+
 
 bytecode *
 x86_new_insn(const unsigned long data[4], int num_operands,
@@ -1074,6 +1189,12 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                    else
                        InternalError(_("invalid operand conversion"));
                    break;
+               case OPA_Op1Add:
+                   if (op->type == INSN_OPERAND_REG)
+                       d.op[1] += (unsigned char)(op->data.reg&7);
+                   else
+                       InternalError(_("invalid operand conversion"));
+                   break;
                case OPA_SpareEA:
                    if (op->type == INSN_OPERAND_REG) {
                        d.spare = (unsigned char)(op->data.reg&7);
@@ -1629,22 +1750,22 @@ x86_check_identifier(unsigned long data[4], const char *id)
        V E R R { RET_INSN(prot286, 0x0400, CPU_286|CPU_Prot); }
        V E R W { RET_INSN(prot286, 0x0500, CPU_286|CPU_Prot); }
        /* Floating point instructions */
-       /* F L D */
-       /* F I L D */
-       /* F B L D */
-       /* F S T */
-       /* F I S T */
-       /* F S T P */
-       /* F I S T P */
-       /* F B S T P */
-       /* F X C H */
-       /* F C O M */
-       /* F I C O M */
-       /* F C O M P */
-       /* F I C O M P */
+       F L D { RET_INSN(fldstp, 0x0500C0, CPU_FPU); }
+       F I L D { RET_INSN(fildstp, 0x0500, CPU_FPU); }
+       F B L D { RET_INSN(fbldstp, 0x04, CPU_FPU); }
+       F S T { RET_INSN(fst, 0, CPU_FPU); }
+       F I S T { RET_INSN(fiarith, 0x02DB, CPU_FPU); }
+       F S T P { RET_INSN(fldstp, 0x0703D8, CPU_FPU); }
+       F I S T P { RET_INSN(fildstp, 0x0703, CPU_FPU); }
+       F B S T P { RET_INSN(fbldstp, 0x06, CPU_FPU); }
+       F X C H { RET_INSN(fxch, 0, CPU_FPU); }
+       F C O M { RET_INSN(fcom, 0x02D0, CPU_FPU); }
+       F I C O M { RET_INSN(fiarith, 0x02DA, CPU_FPU); }
+       F C O M P { RET_INSN(fcom, 0x03D8, CPU_FPU); }
+       F I C O M P { RET_INSN(fiarith, 0x03DA, CPU_FPU); }
        F C O M P P { RET_INSN(twobyte, 0xDED9, CPU_FPU); }
-       /* F U C O M */
-       /* F U C O M P */
+       F U C O M { RET_INSN(fcom2, 0xDDE0, CPU_286|CPU_FPU); }
+       F U C O M P { RET_INSN(fcom2, 0xDDE8, CPU_286|CPU_FPU); }
        F U C O M P P { RET_INSN(twobyte, 0xDAE9, CPU_286|CPU_FPU); }
        F T S T { RET_INSN(twobyte, 0xD9E4, CPU_FPU); }
        F X A M { RET_INSN(twobyte, 0xD9E5, CPU_FPU); }
@@ -1655,24 +1776,24 @@ x86_check_identifier(unsigned long data[4], const char *id)
        F L D L G "2" { RET_INSN(twobyte, 0xD9EC, CPU_FPU); }
        F L D L N "2" { RET_INSN(twobyte, 0xD9ED, CPU_FPU); }
        F L D Z { RET_INSN(twobyte, 0xD9EE, CPU_FPU); }
-       /* F A D D */
-       /* F A D D P */
-       /* F I A D D */
-       /* F S U B */
-       /* F I S U B */
-       /* F S U B P */
-       /* F S U B R */
-       /* F I S U B R */
-       /* F S U B R P */
-       /* F M U L */
-       /* F I M U L */
-       /* F M U L P */
-       /* F D I V */
-       /* F I D I V */
-       /* F D I V P */
-       /* F D I V R */
-       /* F I D I V R */
-       /* F D I V R P */
+       F A D D { RET_INSN(farith, 0x00C0C0, CPU_FPU); }
+       F A D D P { RET_INSN(farithp, 0xC0, CPU_FPU); }
+       F I A D D { RET_INSN(fiarith, 0x00DA, CPU_FPU); }
+       F S U B { RET_INSN(farith, 0x04E0E8, CPU_FPU); }
+       F I S U B { RET_INSN(fiarith, 0x04DA, CPU_FPU); }
+       F S U B P { RET_INSN(farithp, 0xE8, CPU_FPU); }
+       F S U B R { RET_INSN(farith, 0x05E8E0, CPU_FPU); }
+       F I S U B R { RET_INSN(fiarith, 0x05DA, CPU_FPU); }
+       F S U B R P { RET_INSN(farithp, 0xE0, CPU_FPU); }
+       F M U L { RET_INSN(farith, 0x01C8C8, CPU_FPU); }
+       F I M U L { RET_INSN(fiarith, 0x01DA, CPU_FPU); }
+       F M U L P { RET_INSN(farithp, 0xC8, CPU_FPU); }
+       F D I V { RET_INSN(farith, 0x06F0F8, CPU_FPU); }
+       F I D I V { RET_INSN(fiarith, 0x06DA, CPU_FPU); }
+       F D I V P { RET_INSN(farithp, 0xF8, CPU_FPU); }
+       F D I V R { RET_INSN(farith, 0x07F8F0, CPU_FPU); }
+       F I D I V R { RET_INSN(fiarith, 0x07DA, CPU_FPU); }
+       F D I V R P { RET_INSN(farithp, 0xF0, CPU_FPU); }
        F "2" X M "1" { RET_INSN(twobyte, 0xD9F0, CPU_FPU); }
        F Y L "2" X { RET_INSN(twobyte, 0xD9F1, CPU_FPU); }
        F P T A N { RET_INSN(twobyte, 0xD9F2, CPU_FPU); }
@@ -1693,11 +1814,11 @@ x86_check_identifier(unsigned long data[4], const char *id)
        F A B S { RET_INSN(twobyte, 0xD9E1, CPU_FPU); }
        F N I N I T { RET_INSN(twobyte, 0xDBE3, CPU_FPU); }
        F I N I T { RET_INSN(threebyte, 0x98DBE3, CPU_FPU); }
-       /* F L D C W */
-       /* F N S T C W */
-       /* F S T C W */
-       /* F N S T S W */
-       /* F S T S W */
+       F L D C W { RET_INSN(fldnstcw, 0x05, CPU_FPU); }
+       F N S T C W { RET_INSN(fldnstcw, 0x07, CPU_FPU); }
+       F S T C W { RET_INSN(fstcw, 0, CPU_FPU); }
+       F N S T S W { RET_INSN(fnstsw, 0, CPU_FPU); }
+       F S T S W { RET_INSN(fstsw, 0, CPU_FPU); }
        F N C L E X { RET_INSN(twobyte, 0xDBE2, CPU_FPU); }
        F C L E X { RET_INSN(threebyte, 0x98DBE2, CPU_FPU); }
        F N S T E N V { RET_INSN(onebytemem, 0x06D9, CPU_FPU); }
@@ -1706,8 +1827,8 @@ x86_check_identifier(unsigned long data[4], const char *id)
        F N S A V E { RET_INSN(onebytemem, 0x06DD, CPU_FPU); }
        F S A V E { RET_INSN(twobytemem, 0x069BDD, CPU_FPU); }
        F R S T O R { RET_INSN(onebytemem, 0x04DD, CPU_FPU); }
-       /* F F R E E */
-       /* F F R E E P */
+       F F R E E { RET_INSN(ffree, 0xDD, CPU_FPU); }
+       F F R E E P { RET_INSN(ffree, 0xDF, CPU_686|CPU_FPU|CPU_Undoc); }
        F N O P { RET_INSN(twobyte, 0xD9D0, CPU_FPU); }
        F W A I T { RET_INSN(onebyte, 0x009B, CPU_FPU); }
        /* Prefixes (should the others be here too? should wait be a prefix? */
@@ -1737,10 +1858,10 @@ x86_check_identifier(unsigned long data[4], const char *id)
        U D "1" { RET_INSN(twobyte, 0x0FB9, CPU_286|CPU_Undoc); }
        /* C M O V */
        /* F C M O V */
-       /* F C O M I */
-       /* F U C O M I */
-       /* F C O M I P */
-       /* F U C O M I P */
+       F C O M I { RET_INSN(fcom2, 0xDBF0, CPU_686|CPU_FPU); }
+       F U C O M I { RET_INSN(fcom2, 0xDBE8, CPU_686|CPU_FPU); }
+       F C O M I P { RET_INSN(fcom2, 0xDFF0, CPU_686|CPU_FPU); }
+       F U C O M I P { RET_INSN(fcom2, 0xDFE8, CPU_686|CPU_FPU); }
        /* Pentium4 extensions */
        /* M O V N T I */
        /* C L F L U S H */
index 050062662d4d56722426621b81ed6790994d7fef..fd624fc42770d8892461dbbd2f1e8eebed2d82ff 100644 (file)
@@ -136,7 +136,8 @@ static unsigned long cpu_enabled = ~CPU_Any;
  *             3 = operand data goes into sign-extended imm field
  *             4 = operand data goes into "spare" field
  *             5 = operand data is added to opcode byte 0
- *             6 = operand data goes into BOTH ea and spare
+ *             6 = operand data is added to opcode byte 1
+ *             7 = operand data goes into BOTH ea and spare
  *                 [special case for imul opcode]
  * The below describes postponed actions: actions which can't be completed at
  * parse-time due to things like EQU and complex expressions.  For these, some
@@ -196,7 +197,8 @@ static unsigned long cpu_enabled = ~CPU_Any;
 #define OPA_SImm       (3<<12)
 #define OPA_Spare      (4<<12)
 #define OPA_Op0Add     (5<<12)
-#define OPA_SpareEA    (6<<12)
+#define OPA_Op1Add     (6<<12)
+#define OPA_SpareEA    (7<<12)
 #define OPA_MASK       (7<<12)
 
 #define OPAP_None      (0<<15)
@@ -726,6 +728,119 @@ static const x86_insn_info sldtmsw_insn[] = {
       {OPT_Reg|OPS_32|OPA_EA, 0, 0} }
 };
 
+/* Floating point instructions - load/store with pop (integer and normal) */
+static const x86_insn_info fldstp_insn[] = {
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xD9, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xDD, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 1, {0xDB, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_80|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xD9, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }
+};
+static const x86_insn_info fildstp_insn[] = {
+    { CPU_FPU, MOD_SpAdd, 0, 1, {0xDF, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_16|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_SpAdd, 0, 1, {0xDB, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xDF, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_64|OPA_EA, 0, 0} }
+};
+static const x86_insn_info fbldstp_insn[] = {
+    { CPU_FPU, MOD_SpAdd, 0, 1, {0xDF, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_80|OPS_Relaxed|OPA_EA, 0, 0} }
+};
+/* Floating point instructions - store (normal) */
+static const x86_insn_info fst_insn[] = {
+    { CPU_FPU, 0, 0, 1, {0xD9, 0, 0}, 2, 1, {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, 0, 0, 1, {0xDD, 0, 0}, 2, 1, {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
+    { CPU_FPU, 0, 0, 2, {0xDD, 0xD0, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }
+};
+/* Floating point instructions - exchange (with ST0) */
+static const x86_insn_info fxch_insn[] = {
+    { CPU_FPU, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 2,
+      {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} },
+    { CPU_FPU, 0, 0, 2, {0xD9, 0xC8, 0}, 0, 2,
+      {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} },
+    { CPU_FPU, 0, 0, 2, {0xD9, 0xC9, 0}, 0, 0, {0, 0, 0} }
+};
+/* Floating point instructions - comparisons */
+static const x86_insn_info fcom_insn[] = {
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xD8, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_SpAdd, 0, 1, {0xDC, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 2,
+      {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} }
+};
+/* Floating point instructions - extended comparisons */
+static const x86_insn_info fcom2_insn[] = {
+    { CPU_286|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 2, {0x00, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_286|CPU_FPU, MOD_Op0Add|MOD_Op1Add, 0, 2, {0x00, 0x00, 0}, 0, 2,
+      {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} }
+};
+/* Floating point instructions - arithmetic */
+static const x86_insn_info farith_insn[] = {
+    { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 1, {0xD8, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_Gap1|MOD_SpAdd, 0, 1, {0xDC, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_64|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, MOD_Gap0|MOD_Op1Add, 0, 2, {0xD8, 0x00, 0}, 0, 2,
+      {OPT_ST0|OPS_80|OPA_None, OPT_Reg|OPS_80|OPA_Op1Add, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDC, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPTM_To|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDC, 0x00, 0}, 0, 2,
+      {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} }
+};
+static const x86_insn_info farithp_insn[] = {
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDE, 0x01, 0}, 0, 0, {0, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDE, 0x00, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} },
+    { CPU_FPU, MOD_Op1Add, 0, 2, {0xDE, 0x00, 0}, 0, 2,
+      {OPT_Reg|OPS_80|OPA_Op1Add, OPT_ST0|OPS_80|OPA_None, 0} }
+};
+/* Floating point instructions - integer arith/store wo pop/compare */
+static const x86_insn_info fiarith_insn[] = {
+    { CPU_FPU, MOD_Op0Add|MOD_SpAdd, 0, 1, {0x04, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_16|OPA_EA, 0, 0} },
+    { CPU_FPU, MOD_Op0Add|MOD_SpAdd, 0, 1, {0x00, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_32|OPA_EA, 0, 0} }
+};
+/* Floating point instructions - processor control */
+static const x86_insn_info fldnstcw_insn[] = {
+    { CPU_FPU, MOD_SpAdd, 0, 1, {0xD9, 0, 0}, 0, 1,
+      {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }
+};
+static const x86_insn_info fstcw_insn[] = {
+    { CPU_FPU, 0, 0, 2, {0x9B, 0xD9, 0}, 7, 1,
+      {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} }
+};
+static const x86_insn_info fnstsw_insn[] = {
+    { CPU_FPU, 0, 0, 1, {0xDD, 0, 0}, 7, 1,
+      {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} },
+    { CPU_FPU, 0, 0, 2, {0xDF, 0xE0, 0}, 0, 1,
+      {OPT_Areg|OPS_16|OPA_None, 0, 0} }
+};
+static const x86_insn_info fstsw_insn[] = {
+    { CPU_FPU, 0, 0, 2, {0x9B, 0xDD, 0}, 7, 1,
+      {OPT_Mem|OPS_16|OPS_Relaxed|OPA_EA, 0, 0} },
+    { CPU_FPU, 0, 0, 3, {0x9B, 0xDF, 0xE0}, 0, 1,
+      {OPT_Areg|OPS_16|OPA_None, 0, 0} }
+};
+static const x86_insn_info ffree_insn[] = {
+    { CPU_FPU, MOD_Op0Add, 0, 2, {0x00, 0xC0, 0}, 0, 1,
+      {OPT_Reg|OPS_80|OPA_Op1Add, 0, 0} }
+};
+
 
 bytecode *
 x86_new_insn(const unsigned long data[4], int num_operands,
@@ -1074,6 +1189,12 @@ x86_new_insn(const unsigned long data[4], int num_operands,
                    else
                        InternalError(_("invalid operand conversion"));
                    break;
+               case OPA_Op1Add:
+                   if (op->type == INSN_OPERAND_REG)
+                       d.op[1] += (unsigned char)(op->data.reg&7);
+                   else
+                       InternalError(_("invalid operand conversion"));
+                   break;
                case OPA_SpareEA:
                    if (op->type == INSN_OPERAND_REG) {
                        d.spare = (unsigned char)(op->data.reg&7);
@@ -1629,22 +1750,22 @@ x86_check_identifier(unsigned long data[4], const char *id)
        V E R R { RET_INSN(prot286, 0x0400, CPU_286|CPU_Prot); }
        V E R W { RET_INSN(prot286, 0x0500, CPU_286|CPU_Prot); }
        /* Floating point instructions */
-       /* F L D */
-       /* F I L D */
-       /* F B L D */
-       /* F S T */
-       /* F I S T */
-       /* F S T P */
-       /* F I S T P */
-       /* F B S T P */
-       /* F X C H */
-       /* F C O M */
-       /* F I C O M */
-       /* F C O M P */
-       /* F I C O M P */
+       F L D { RET_INSN(fldstp, 0x0500C0, CPU_FPU); }
+       F I L D { RET_INSN(fildstp, 0x0500, CPU_FPU); }
+       F B L D { RET_INSN(fbldstp, 0x04, CPU_FPU); }
+       F S T { RET_INSN(fst, 0, CPU_FPU); }
+       F I S T { RET_INSN(fiarith, 0x02DB, CPU_FPU); }
+       F S T P { RET_INSN(fldstp, 0x0703D8, CPU_FPU); }
+       F I S T P { RET_INSN(fildstp, 0x0703, CPU_FPU); }
+       F B S T P { RET_INSN(fbldstp, 0x06, CPU_FPU); }
+       F X C H { RET_INSN(fxch, 0, CPU_FPU); }
+       F C O M { RET_INSN(fcom, 0x02D0, CPU_FPU); }
+       F I C O M { RET_INSN(fiarith, 0x02DA, CPU_FPU); }
+       F C O M P { RET_INSN(fcom, 0x03D8, CPU_FPU); }
+       F I C O M P { RET_INSN(fiarith, 0x03DA, CPU_FPU); }
        F C O M P P { RET_INSN(twobyte, 0xDED9, CPU_FPU); }
-       /* F U C O M */
-       /* F U C O M P */
+       F U C O M { RET_INSN(fcom2, 0xDDE0, CPU_286|CPU_FPU); }
+       F U C O M P { RET_INSN(fcom2, 0xDDE8, CPU_286|CPU_FPU); }
        F U C O M P P { RET_INSN(twobyte, 0xDAE9, CPU_286|CPU_FPU); }
        F T S T { RET_INSN(twobyte, 0xD9E4, CPU_FPU); }
        F X A M { RET_INSN(twobyte, 0xD9E5, CPU_FPU); }
@@ -1655,24 +1776,24 @@ x86_check_identifier(unsigned long data[4], const char *id)
        F L D L G "2" { RET_INSN(twobyte, 0xD9EC, CPU_FPU); }
        F L D L N "2" { RET_INSN(twobyte, 0xD9ED, CPU_FPU); }
        F L D Z { RET_INSN(twobyte, 0xD9EE, CPU_FPU); }
-       /* F A D D */
-       /* F A D D P */
-       /* F I A D D */
-       /* F S U B */
-       /* F I S U B */
-       /* F S U B P */
-       /* F S U B R */
-       /* F I S U B R */
-       /* F S U B R P */
-       /* F M U L */
-       /* F I M U L */
-       /* F M U L P */
-       /* F D I V */
-       /* F I D I V */
-       /* F D I V P */
-       /* F D I V R */
-       /* F I D I V R */
-       /* F D I V R P */
+       F A D D { RET_INSN(farith, 0x00C0C0, CPU_FPU); }
+       F A D D P { RET_INSN(farithp, 0xC0, CPU_FPU); }
+       F I A D D { RET_INSN(fiarith, 0x00DA, CPU_FPU); }
+       F S U B { RET_INSN(farith, 0x04E0E8, CPU_FPU); }
+       F I S U B { RET_INSN(fiarith, 0x04DA, CPU_FPU); }
+       F S U B P { RET_INSN(farithp, 0xE8, CPU_FPU); }
+       F S U B R { RET_INSN(farith, 0x05E8E0, CPU_FPU); }
+       F I S U B R { RET_INSN(fiarith, 0x05DA, CPU_FPU); }
+       F S U B R P { RET_INSN(farithp, 0xE0, CPU_FPU); }
+       F M U L { RET_INSN(farith, 0x01C8C8, CPU_FPU); }
+       F I M U L { RET_INSN(fiarith, 0x01DA, CPU_FPU); }
+       F M U L P { RET_INSN(farithp, 0xC8, CPU_FPU); }
+       F D I V { RET_INSN(farith, 0x06F0F8, CPU_FPU); }
+       F I D I V { RET_INSN(fiarith, 0x06DA, CPU_FPU); }
+       F D I V P { RET_INSN(farithp, 0xF8, CPU_FPU); }
+       F D I V R { RET_INSN(farith, 0x07F8F0, CPU_FPU); }
+       F I D I V R { RET_INSN(fiarith, 0x07DA, CPU_FPU); }
+       F D I V R P { RET_INSN(farithp, 0xF0, CPU_FPU); }
        F "2" X M "1" { RET_INSN(twobyte, 0xD9F0, CPU_FPU); }
        F Y L "2" X { RET_INSN(twobyte, 0xD9F1, CPU_FPU); }
        F P T A N { RET_INSN(twobyte, 0xD9F2, CPU_FPU); }
@@ -1693,11 +1814,11 @@ x86_check_identifier(unsigned long data[4], const char *id)
        F A B S { RET_INSN(twobyte, 0xD9E1, CPU_FPU); }
        F N I N I T { RET_INSN(twobyte, 0xDBE3, CPU_FPU); }
        F I N I T { RET_INSN(threebyte, 0x98DBE3, CPU_FPU); }
-       /* F L D C W */
-       /* F N S T C W */
-       /* F S T C W */
-       /* F N S T S W */
-       /* F S T S W */
+       F L D C W { RET_INSN(fldnstcw, 0x05, CPU_FPU); }
+       F N S T C W { RET_INSN(fldnstcw, 0x07, CPU_FPU); }
+       F S T C W { RET_INSN(fstcw, 0, CPU_FPU); }
+       F N S T S W { RET_INSN(fnstsw, 0, CPU_FPU); }
+       F S T S W { RET_INSN(fstsw, 0, CPU_FPU); }
        F N C L E X { RET_INSN(twobyte, 0xDBE2, CPU_FPU); }
        F C L E X { RET_INSN(threebyte, 0x98DBE2, CPU_FPU); }
        F N S T E N V { RET_INSN(onebytemem, 0x06D9, CPU_FPU); }
@@ -1706,8 +1827,8 @@ x86_check_identifier(unsigned long data[4], const char *id)
        F N S A V E { RET_INSN(onebytemem, 0x06DD, CPU_FPU); }
        F S A V E { RET_INSN(twobytemem, 0x069BDD, CPU_FPU); }
        F R S T O R { RET_INSN(onebytemem, 0x04DD, CPU_FPU); }
-       /* F F R E E */
-       /* F F R E E P */
+       F F R E E { RET_INSN(ffree, 0xDD, CPU_FPU); }
+       F F R E E P { RET_INSN(ffree, 0xDF, CPU_686|CPU_FPU|CPU_Undoc); }
        F N O P { RET_INSN(twobyte, 0xD9D0, CPU_FPU); }
        F W A I T { RET_INSN(onebyte, 0x009B, CPU_FPU); }
        /* Prefixes (should the others be here too? should wait be a prefix? */
@@ -1737,10 +1858,10 @@ x86_check_identifier(unsigned long data[4], const char *id)
        U D "1" { RET_INSN(twobyte, 0x0FB9, CPU_286|CPU_Undoc); }
        /* C M O V */
        /* F C M O V */
-       /* F C O M I */
-       /* F U C O M I */
-       /* F C O M I P */
-       /* F U C O M I P */
+       F C O M I { RET_INSN(fcom2, 0xDBF0, CPU_686|CPU_FPU); }
+       F U C O M I { RET_INSN(fcom2, 0xDBE8, CPU_686|CPU_FPU); }
+       F C O M I P { RET_INSN(fcom2, 0xDFF0, CPU_686|CPU_FPU); }
+       F U C O M I P { RET_INSN(fcom2, 0xDFE8, CPU_686|CPU_FPU); }
        /* Pentium4 extensions */
        /* M O V N T I */
        /* C L F L U S H */