Added support for MC68881 floating point processor
authorceriel <none@none>
Thu, 8 Jun 1989 12:46:17 +0000 (12:46 +0000)
committerceriel <none@none>
Thu, 8 Jun 1989 12:46:17 +0000 (12:46 +0000)
mach/m68020/as/mach1.c
mach/m68020/as/mach2.c
mach/m68020/as/mach3.c
mach/m68020/as/mach4.c
mach/m68020/as/mach5.c

index 0e71ea6..1056737 100644 (file)
 #define        low4(z)         ((short)(z) & 017)
 #define        low5(z)         ((short)(z) & 037)
 #define        low6(z)         ((short)(z) & 077)
+#define        low7(z)         ((short)(z) & 0177)
 
 #define        fit3(z)         ((((z)-1) & ~07) == 0)
 #define        fit4(z)         (((z) & ~017) == 0)
 #define        fit5(z)         (((z) & ~037) == 0)
 #define        fit6(z)         (((z) & ~077) == 0)
+#define        fit7(z)         (((z) & ~0177) == 0)
+#define        sfit7(z)        (fit7((z)+64))
 #define        fit8(z)         (((z) & ~0xFF) == 0)
 #define        fit16(z)        (((z) & ~0xFFFF) == 0)
 
 #define        SIZE_NON        0300
 #define        SIZE_DEF        SIZE_W
 
+#define FSIZE_L                00
+#define FSIZE_S                01
+#define FSIZE_X                02
+#define FSIZE_P                03
+#define FSIZE_W                04
+#define FSIZE_D                05
+#define FSIZE_B                06
+
+#define        DEF_FP          01000   /* default floating point processor */
+#define        DEF_MM          00000   /* default memory management */
+extern int     co_id;          /* coprocessor id */
+
 extern int     mrg_1,mrg_2;    /* Mode and ReGister */
 extern short   ffew_1, ffew_2; /* Full Format Extension Word */
 extern expr_t  bd_1,bd_2,od_1,od_2; /* base and outer displacements */
index 8b9d73e..3306ba0 100644 (file)
 %token <y_word> CPSAVE
 %token <y_word> CPSCC
 %token <y_word> CPTRAPCC
+%token <y_word> FPCR
+%token <y_word> FPREG
+%token <y_word> FMOVE
+%token <y_word> FMOVECR
+%token <y_word> FMOVEM
+%token <y_word> FDYADIC
+%token <y_word> FMONADIC
+%token <y_word> FSINCOS
+%token <y_word> FBCC
+%token <y_word> FDBCC
+%token <y_word> FNOP
+%token <y_word> FSCC
+%token <y_word> FTST
+%token <y_word> FSAVRES
+%token <y_word> FTRAPCC
+%token <y_word> FSIZE
 
 %type <y_word> bcdx op_ea regs rrange 
 %type <y_word> reg sizedef sizenon creg
 %type <y_word> off_width abs31 bd_areg_index
 %type <y_word> areg_index areg scale cp_cond
+%type <y_word> fsize fregs fcregs frlist frrange
index 40ebff0..1db445a 100644 (file)
                                                */
 0,     CPSAVE,         0170400,        ".save",
 0,     CPRESTORE,      0170500,        ".restore",
+
+/* floating point coprocessor ... */
+
+0,     FSIZE,          FSIZE_S,        ".s",
+0,     FSIZE,          FSIZE_X,        ".x",
+0,     FSIZE,          FSIZE_P,        ".p",
+0,     FSIZE,          FSIZE_D,        ".d",
+
+0,     FPREG,          0,              "fp0",
+0,     FPREG,          1,              "fp1",
+0,     FPREG,          2,              "fp2",
+0,     FPREG,          3,              "fp3",
+0,     FPREG,          4,              "fp4",
+0,     FPREG,          5,              "fp5",
+0,     FPREG,          6,              "fp6",
+0,     FPREG,          7,              "fp7",
+
+0,     FPCR,           1,              "fpiar",
+0,     FPCR,           2,              "fpsr",
+0,     FPCR,           4,              "fpcr",
+
+0,     FMOVE,          0,              "fmove",
+0,     FMOVECR,        0,              "fmovecr",
+0,     FMOVEM,         0,              "fmovem",
+
+0,     FDYADIC,        042,            "fadd",
+0,     FDYADIC,        070,            "fcmp",
+0,     FDYADIC,        040,            "fdiv",
+0,     FDYADIC,        041,            "fmod",
+0,     FDYADIC,        043,            "fmul",
+0,     FDYADIC,        045,            "frem",
+0,     FDYADIC,        046,            "fscale",
+0,     FDYADIC,        044,            "fsgldiv",
+0,     FDYADIC,        047,            "fsglmul",
+0,     FDYADIC,        050,            "fsub",
+
+0,     FMONADIC,       030,            "fabs",
+0,     FMONADIC,       034,            "facos",
+0,     FMONADIC,       014,            "fasin",
+0,     FMONADIC,       012,            "fatan",
+0,     FMONADIC,       015,            "fatanh",
+0,     FMONADIC,       035,            "fcos",
+0,     FMONADIC,       031,            "fcosh",
+0,     FMONADIC,       020,            "fetox",
+0,     FMONADIC,       010,            "fetoxm1",
+0,     FMONADIC,       036,            "fgetexp",
+0,     FMONADIC,       037,            "fgetman",
+0,     FMONADIC,       001,            "fint",
+0,     FMONADIC,       003,            "fintrz",
+0,     FMONADIC,       024,            "flogn",
+0,     FMONADIC,       006,            "flognp1",
+0,     FMONADIC,       025,            "flog10",
+0,     FMONADIC,       026,            "flog2",
+0,     FMONADIC,       032,            "fneg",
+0,     FMONADIC,       016,            "fsin",
+0,     FMONADIC,       002,            "fsinh",
+0,     FMONADIC,       004,            "fsqrt",
+0,     FMONADIC,       017,            "ftan",
+0,     FMONADIC,       011,            "ftanh",
+0,     FMONADIC,       022,            "ftentox",
+0,     FMONADIC,       021,            "ftwotox",
+
+0,     FSINCOS,        060,            "fsincos",
+
+0,     FBCC,           001,            "fbeq",
+0,     FBCC,           016,            "fbne",
+0,     FBCC,           022,            "fbgt",
+0,     FBCC,           035,            "fbngt",
+0,     FBCC,           023,            "fbge",
+0,     FBCC,           034,            "fbnge",
+0,     FBCC,           024,            "fblt",
+0,     FBCC,           033,            "fbnlt",
+0,     FBCC,           025,            "fble",
+0,     FBCC,           032,            "fbnle",
+0,     FBCC,           026,            "fbgl",
+0,     FBCC,           031,            "fbngl",
+0,     FBCC,           027,            "fbgle",
+0,     FBCC,           030,            "fbngle",
+0,     FBCC,           002,            "fbogt",
+0,     FBCC,           015,            "fbule",
+0,     FBCC,           003,            "fboge",
+0,     FBCC,           014,            "fbult",
+0,     FBCC,           004,            "fbolt",
+0,     FBCC,           013,            "fbuge",
+0,     FBCC,           005,            "fbole",
+0,     FBCC,           012,            "fbugt",
+0,     FBCC,           006,            "fbogl",
+0,     FBCC,           011,            "fbueq",
+0,     FBCC,           007,            "fbor",
+0,     FBCC,           010,            "fbun",
+0,     FBCC,           000,            "fbf",
+0,     FBCC,           017,            "fbt",
+0,     FBCC,           020,            "fbsf",
+0,     FBCC,           037,            "fbst",
+0,     FBCC,           021,            "fbseq",
+0,     FBCC,           036,            "fbsne",
+
+0,     FDBCC,          001,            "fdbeq",
+0,     FDBCC,          016,            "fdbne",
+0,     FDBCC,          022,            "fdbgt",
+0,     FDBCC,          035,            "fdbngt",
+0,     FDBCC,          023,            "fdbge",
+0,     FDBCC,          034,            "fdbnge",
+0,     FDBCC,          024,            "fdblt",
+0,     FDBCC,          033,            "fdbnlt",
+0,     FDBCC,          025,            "fdble",
+0,     FDBCC,          032,            "fdbnle",
+0,     FDBCC,          026,            "fdbgl",
+0,     FDBCC,          031,            "fdbngl",
+0,     FDBCC,          027,            "fdbgle",
+0,     FDBCC,          030,            "fdbngle",
+0,     FDBCC,          002,            "fdbogt",
+0,     FDBCC,          015,            "fdbule",
+0,     FDBCC,          003,            "fdboge",
+0,     FDBCC,          014,            "fdbult",
+0,     FDBCC,          004,            "fdbolt",
+0,     FDBCC,          013,            "fdbuge",
+0,     FDBCC,          005,            "fdbole",
+0,     FDBCC,          012,            "fdbugt",
+0,     FDBCC,          006,            "fdbogl",
+0,     FDBCC,          011,            "fdbueq",
+0,     FDBCC,          007,            "fdbor",
+0,     FDBCC,          010,            "fdbun",
+0,     FDBCC,          000,            "fdbf",
+0,     FDBCC,          017,            "fdbt",
+0,     FDBCC,          020,            "fdbsf",
+0,     FDBCC,          037,            "fdbst",
+0,     FDBCC,          021,            "fdbseq",
+0,     FDBCC,          036,            "fdbsne",
+
+0,     FNOP,           0,              "fnop",
+
+0,     FSCC,           001,            "fseq",
+0,     FSCC,           016,            "fsne",
+0,     FSCC,           022,            "fsgt",
+0,     FSCC,           035,            "fsngt",
+0,     FSCC,           023,            "fsge",
+0,     FSCC,           034,            "fsnge",
+0,     FSCC,           024,            "fslt",
+0,     FSCC,           033,            "fsnlt",
+0,     FSCC,           025,            "fsle",
+0,     FSCC,           032,            "fsnle",
+0,     FSCC,           026,            "fsgl",
+0,     FSCC,           031,            "fsngl",
+0,     FSCC,           027,            "fsgle",
+0,     FSCC,           030,            "fsngle",
+0,     FSCC,           002,            "fsogt",
+0,     FSCC,           015,            "fsule",
+0,     FSCC,           003,            "fsoge",
+0,     FSCC,           014,            "fsult",
+0,     FSCC,           004,            "fsolt",
+0,     FSCC,           013,            "fsuge",
+0,     FSCC,           005,            "fsole",
+0,     FSCC,           012,            "fsugt",
+0,     FSCC,           006,            "fsogl",
+0,     FSCC,           011,            "fsueq",
+0,     FSCC,           007,            "fsor",
+0,     FSCC,           010,            "fsun",
+0,     FSCC,           000,            "fsf",
+0,     FSCC,           017,            "fst",
+0,     FSCC,           020,            "fssf",
+0,     FSCC,           037,            "fsst",
+0,     FSCC,           021,            "fsseq",
+0,     FSCC,           036,            "fssne",
+
+0,     FTST,           0,              "ftst",
+
+0,     FSAVRES,        MEM|ALT|0430,   "fsave",
+0,     FSAVRES,        MEM|0540,       "frestore",
+
+0,     FTRAPCC,        001,            "ftrapeq",
+0,     FTRAPCC,        016,            "ftrapne",
+0,     FTRAPCC,        022,            "ftrapgt",
+0,     FTRAPCC,        035,            "ftrapngt",
+0,     FTRAPCC,        023,            "ftrapge",
+0,     FTRAPCC,        034,            "ftrapnge",
+0,     FTRAPCC,        024,            "ftraplt",
+0,     FTRAPCC,        033,            "ftrapnlt",
+0,     FTRAPCC,        025,            "ftraple",
+0,     FTRAPCC,        032,            "ftrapnle",
+0,     FTRAPCC,        026,            "ftrapgl",
+0,     FTRAPCC,        031,            "ftrapngl",
+0,     FTRAPCC,        027,            "ftrapgle",
+0,     FTRAPCC,        030,            "ftrapngle",
+0,     FTRAPCC,        002,            "ftrapogt",
+0,     FTRAPCC,        015,            "ftrapule",
+0,     FTRAPCC,        003,            "ftrapoge",
+0,     FTRAPCC,        014,            "ftrapult",
+0,     FTRAPCC,        004,            "ftrapolt",
+0,     FTRAPCC,        013,            "ftrapuge",
+0,     FTRAPCC,        005,            "ftrapole",
+0,     FTRAPCC,        012,            "ftrapugt",
+0,     FTRAPCC,        006,            "ftrapogl",
+0,     FTRAPCC,        011,            "ftrapueq",
+0,     FTRAPCC,        007,            "ftrapor",
+0,     FTRAPCC,        010,            "ftrapun",
+0,     FTRAPCC,        000,            "ftrapf",
+0,     FTRAPCC,        017,            "ftrapt",
+0,     FTRAPCC,        020,            "ftrapsf",
+0,     FTRAPCC,        037,            "ftrapst",
+0,     FTRAPCC,        021,            "ftrapseq",
+0,     FTRAPCC,        036,            "ftrapsne",
index 87a6850..4ea8138 100644 (file)
@@ -125,14 +125,10 @@ instruction
                        {       move($2);}
        |       MOVEP sizedef ea_ea
                        {       movep($2);}
-       |       MOVEM sizedef regs ',' 
-                       {       mrg_2 = 0; ffew_2 = 0400; /* initialization */}
-               notimmreg
+       |       MOVEM sizedef regs ',' notimmreg
                        {       movem(0, $2, $3);}
-       |       MOVEM sizedef 
-                       {       mrg_2 = 0; ffew_2 = 0400; /* initialization */}
-               notimmreg ',' regs
-                       {       movem(1, $2, $6);}
+       |       MOVEM sizedef notimmreg ',' regs
+                       {       movem(1, $2, $5);}
        |       MOVES sizedef ea_ea
                        {       if (mrg_1 <= 017) {
                                        T_EMIT2(007000 | $2 | mrg_2,0,0,0);
@@ -209,54 +205,8 @@ instruction
                                T_EMIT2($3 | ($7<<6) | ($12<<12),0,0,0);
                                T_EMIT2($5 | ($9<<6) | ($16<<12),0,0,0);
                        }
-       |   /* Coprocessor instructions; syntax may be changed (please).
-            * No coprocessor defined extension words are emitted.
-            */
-               CP CPBCC cp_cond expr
-                       {       cpbcc($2 | $1 | $3, $4);
-                       }
-       |       CP CPDBCC cp_cond DREG ',' expr
-                       {       T_EMIT2($2 | $1 | $4,0,0,0);
-                               $6.val -= (DOTVAL+dot_offset);
-                               fit(fitw($6.val));
-                               T_EMIT2(loww($6.val), $6.typ,
-                                               RELPC|RELO2, relonami);
-                       }
-       |       CP CPGEN
-                       {       T_EMIT2($2 | $1,0,0,0);
-                               /* NO COMMAND WORD IS EMITTED;
-                                * THIS INSTRUCTIONS IS (STILL) ONE BIG RIDDLE.
-                                * NO EFFECTIVE ADDRESS IS CALCULATED (SYNTAX ?)
-                                */
-                       }
-       |       CP CPRESTORE ea
-                       {       T_EMIT2($2 | $1 | mrg_2,0,0,0);
-                               ea_2(SIZE_W, (mrg_2 & 070)==030 ? 0 : CTR);
-                       }
-       |       CP CPSAVE ea
-                       {       T_EMIT2($2 | $1 | mrg_2,0,0,0);
-                               ea_2(SIZE_W,(mrg_2 & 070)==020 ? 0 : CTR|ALT);
-                       }
-       |       CP CPSCC cp_cond ea
-                       {       T_EMIT2($2 | $1 | mrg_2,0,0,0);
-                               T_EMIT2($3,0,0,0);
-                               ea_2(SIZE_B,DTA|ALT);
-                       }
-       |       CP CPTRAPCC cp_cond SIZE imm
-                       {       checksize($4,2|4);
-                               T_EMIT2($2 | $1 | ($4>>6)+1,0,0,0);
-                               T_EMIT2($3,0,0,0);
-                               ea_2($4, 0);
-                       }
-       |       CP TRAPCC cp_cond
-                       {       T_EMIT2($2 | $1 | 4,0,0,0);
-                               T_EMIT2($3,0,0,0);
-                       }
-       ;
-cp_cond        :       '.' absexp
-                       {       fit(fit6($2));
-                               $$ = low6($2);
-                       }
+       |       fp_op
+       |       mm_op
        ;
 bcdx   :       ABCD
        |       ADDX sizedef
@@ -303,11 +253,15 @@ ea        :       DREG
                        {       mrg_2 = 010 | $1;}
        |       SPEC
                        {       mrg_2 = $1;}
-       |               {       mrg_2 = 0; ffew_2 = 0400; /* initialization */}
-               notimmreg
+       |       notimmreg
        |       imm
        ;
 notimmreg
+       :
+                       {       mrg_2 = 0; ffew_2 = 0400; /* initialization */}
+       notimmreg1
+       ;
+notimmreg1
        :       '(' AREG ')'
                        {       mrg_2 = 020 | $2;}
        |       '(' AREG ')' '+'
@@ -434,3 +388,277 @@ ea_ea     :       ea ','
                        }
                ea
        ;
+fp_op  :       CP
+                       {       co_id = $1; }
+               fp_op1
+       |               {       co_id = DEF_FP; }
+               fp_op1
+       ;
+fp_op1 :       FMOVE fsize ea ',' FPCR
+                       {       check_fsize($2, FSIZE_L);
+                               if ((mrg_2&070) == 010 && $5 != 001)
+                                       badoperand();
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0100000|($5<<10)),0,0,0);
+                               ea_2(SIZE_L, 0);
+                       }
+       |       FMOVE fsize FPCR ',' ea
+                       {       check_fsize($2, FSIZE_L);
+                               if ((mrg_2&070) == 010 && $3 == 001)
+                                       badoperand();
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0120000|($3<<10)),0,0,0);
+                               ea_2(SIZE_L, ALT);
+                       }
+       |       FMOVE fsize FPREG ',' FPREG
+                       {       emit2(0170000|co_id);
+                               emit2(($3<<10)|($5<<7));
+                       }
+       |       FMOVE fsize ea ',' FPREG
+                       {       ch_sz_dreg($2, mrg_2&070);
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0040000|($2<<10)|($5<<7)),0,0,0);
+                               ea_2(SIZE_L, DTA);
+                       }
+       |       FMOVE fsize FPREG ',' ea
+                       {       ch_sz_dreg($2, mrg_2&070);
+                               if ($2 == FSIZE_P)
+                                       serror("packed decimal needs k-factor");
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0060000|($2<<10)|($3<<7)),0,0,0);
+                               ea_2(SIZE_L, DTA|ALT);
+                       }
+       |       FMOVE fsize FPREG ',' ea '{' '#' absexp '}'
+                       {       check_fsize($2, FSIZE_P);
+                               fit(sfit7($8));
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0066000|($3<<7)|low7($8)),0,0,0);
+                               ea_2(SIZE_L, MEM|DTA|ALT);
+                       }
+       |       FMOVE fsize FPREG ',' ea '{' DREG '}'
+                       {       check_fsize($2, FSIZE_P);
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0076000|($3<<7)|($7<<4)),0,0,0);
+                               ea_2(SIZE_L, MEM|DTA|ALT);
+                       }
+       |       FMOVECR fsize '#' absexp ',' FPREG
+                       {       fit(fit7($4));
+                               check_fsize($2, FSIZE_X);
+                               emit2(0170000|co_id);
+                               emit2(056000|($6<<7)|low7($4));
+                       } 
+       |       FMOVEM FSIZE fregs ',' notimmreg
+                       {       check_fsize($2, FSIZE_X);
+                               if ((mrg_2&070) == 030)
+                                       serror("bad addressing category");
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2(0160000 |
+                                       (((mrg_2&070)==040 || ($3&04000)) ?
+                                               $3 :
+                                               (010000|reverse($3,8))),
+                                       0,0,0);
+                               ea_2(SIZE_L, MEM|ALT);
+                       }
+       |       FMOVEM FSIZE notimmreg ',' fregs
+                       {       check_fsize($2, FSIZE_X);
+                               if ((mrg_2&070) == 040)
+                                       serror("bad addressing category");
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0150000|(($5&04000)?$5:reverse($5,8))),0,0,0);
+                               ea_2(SIZE_L, MEM);
+                       }
+       |       FMOVEM SIZE fcregs ',' ea
+                       {       checksize($2, 4);
+                               if ((mrg_2&070) == 1 && $3!= 02000)
+                                       serror("bad addressing category");
+                               if ((mrg_2 & 070) == 0 &&
+                                   $3 != 02000 && $3 != 04000 && $3 != 010000)
+                                       serror("bad addressing category");
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0120000|$3),0,0,0);
+                               ea_2(SIZE_L, ALT);
+                       }
+       |       FMOVEM SIZE ea ',' fcregs
+                       {       checksize($2, 4);
+                               if ((mrg_2&070) == 1 && $5!= 02000)
+                                       serror("bad addressing category");
+                               if ((mrg_2 & 070) == 0 &&
+                                   $5 != 02000 && $5 != 04000 && $5 != 010000)
+                                       serror("bad addressing category");
+                               T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0100000|$5),0,0,0);
+                               ea_2(SIZE_L, 0);
+                       }
+       |       FDYADIC fsize ea ',' FPREG
+                       {       T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0040000|($2<<10)|($5<<7)|$1),0,0,0);
+                               ch_sz_dreg($2, mrg_2&070);
+                               ea_2(SIZE_L, DTA);
+                       }
+       |       FDYADIC fsize FPREG ',' FPREG
+                       {       check_fsize($2, FSIZE_X);
+                               emit2(0170000|co_id);
+                               emit2(($3<<10)|($5<<7)|$1);
+                       }
+       |       FMONADIC fsize ea ',' FPREG
+                       {       T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0040000|($2<<10)|($5<<7)|$1),0,0,0);
+                               ch_sz_dreg($2, mrg_2&070);
+                               ea_2(SIZE_L, DTA);
+                       }
+       |       FMONADIC fsize FPREG ',' FPREG
+                       {       check_fsize($2, FSIZE_X);
+                               emit2(0170000|co_id);
+                               emit2(($3<<10)|($5<<7)|$1);
+                       }
+       |       FMONADIC fsize FPREG
+                       {       check_fsize($2, FSIZE_X);
+                               emit2(0170000|co_id);
+                               emit2(($3<<10)|($3<<7)|$1);
+                       }
+       |       FSINCOS fsize ea ',' FPREG ':' FPREG
+                       {       T_EMIT2(0170000|co_id|mrg_2,0,0,0);
+                               T_EMIT2(0040000|($2<<10)|($7<<7)|$1|$5,0,0,0);
+                               ea_2(SIZE_L, DTA);
+                       }
+       |       FSINCOS fsize FPREG ',' FPREG ':' FPREG
+                       {       check_fsize($2, FSIZE_X);
+                               emit2(0170000|co_id);
+                               emit2(($3<<10)|($7<<7)|$1|$5);
+                       }
+       |       FBCC expr
+                       {       fbranch($1, $2);}
+       |       FDBCC DREG ',' expr
+                       {       T_EMIT2(0170110|co_id|$2,0,0,0);
+                               T_EMIT2($1,0,0,0);
+                               $4.val -= (DOTVAL+dot_offset);
+                               fit(fitw($4.val));
+                               T_EMIT2(loww($4.val), $4.typ,
+                                       RELPC|RELO2,relonami);
+                       }
+       |       FNOP
+                       {       emit2(0170200|co_id);
+                               emit2(0);
+                       }
+       |       FSCC ea
+                       {       T_EMIT2(0170100|co_id|mrg_2,0,0,0);
+                               T_EMIT2($1,0,0,0);
+                               ea_2(SIZE_B, DTA|ALT);
+                       }
+       |       FTST fsize ea
+                       {       T_EMIT2((0170000|co_id|mrg_2),0,0,0);
+                               T_EMIT2((0040072|($2<<10)),0,0,0);
+                               ch_sz_dreg($2, mrg_2&070);
+                               ea_2(SIZE_L, DTA);
+                       }
+       |       FTST fsize FPREG
+                       {       check_fsize($2, FSIZE_X);
+                               emit2(0170000|co_id);
+                               emit2(($3<<10)|072);
+                       }
+       |       FSAVRES ea
+                       {       if ((mrg_2&070) == ($1&070))
+                                       badoperand();
+                               T_EMIT2((0170000|co_id|($1&0700)|mrg_2),0,0,0);
+                               ea_2(0, $1&07);
+                       }
+       |       FTRAPCC
+                       {       emit2(0170174|co_id);
+                               emit2($1);
+                       }
+       |       FTRAPCC SIZE imm
+                       {       checksize($2, 2|4);
+                               T_EMIT2((0170170|co_id|($2==SIZE_L?03:02)),
+                                       0,0,0);
+                               T_EMIT2($1,0,0,0);
+                               ea_2($2,0);
+                       }
+       ;
+fregs  :       DREG
+                       {       $$ = 04000 | $1 << 4; }
+       |       frlist
+       ;
+frlist :       frrange
+       |       frlist '/' frrange
+                       {       $$ = $1 | $3;}
+       ;
+frrange        :       FPREG
+                       {       $$ = 1 << $1; }
+       |       FPREG '-' FPREG
+                       {       if ($1 > $3)
+                                       badoperand();
+                               for ($$ = 0; $1 <= $3; $1++)
+                                       $$ |= (1 << $1);
+                       }
+       ;
+fcregs :       FPCR
+                       {       $$ = $1 << 10; }
+       |       fcregs '/' FPCR
+                       {       $$ = $1 | ($3 << 10); }
+       ;
+fsize  :       /*      empty */
+                       {       $$ = FSIZE_X; }
+       |       SIZE
+                       {       if ($1 == SIZE_L)
+                                       $$ = FSIZE_L;
+                               else if ($1 == SIZE_W)
+                                       $$ = FSIZE_W;
+                               else    $$ = FSIZE_B;
+                       }
+       |       FSIZE
+       ;
+mm_op  :       CP
+                       {       co_id = $1; }
+               mm_op1
+       |               {       co_id = DEF_MM; }
+               mm_op1
+       ;
+mm_op1 :   /* Coprocessor instructions; syntax may be changed (please).
+            * No coprocessor defined extension words are emitted.
+            */
+               CPBCC cp_cond expr
+                       {       cpbcc($1 | co_id | $2, $3);
+                       }
+       |       CPDBCC cp_cond DREG ',' expr
+                       {       T_EMIT2($1 | co_id | $3,0,0,0);
+                               $5.val -= (DOTVAL+dot_offset);
+                               fit(fitw($5.val));
+                               T_EMIT2(loww($5.val), $5.typ,
+                                               RELPC|RELO2, relonami);
+                       }
+       |       CPGEN
+                       {       T_EMIT2($1 | co_id,0,0,0);
+                               /* NO COMMAND WORD IS EMITTED;
+                                * THIS INSTRUCTIONS IS (STILL) ONE BIG RIDDLE.
+                                * NO EFFECTIVE ADDRESS IS CALCULATED (SYNTAX ?)
+                                */
+                       }
+       |       CPRESTORE ea
+                       {       T_EMIT2($1 | co_id | mrg_2,0,0,0);
+                               ea_2(SIZE_W, (mrg_2 & 070)==030 ? 0 : CTR);
+                       }
+       |       CPSAVE ea
+                       {       T_EMIT2($1 | co_id | mrg_2,0,0,0);
+                               ea_2(SIZE_W,(mrg_2 & 070)==020 ? 0 : CTR|ALT);
+                       }
+       |       CPSCC cp_cond ea
+                       {       T_EMIT2($1 | co_id | mrg_2,0,0,0);
+                               T_EMIT2($2,0,0,0);
+                               ea_2(SIZE_B,DTA|ALT);
+                       }
+       |       CPTRAPCC cp_cond SIZE imm
+                       {       checksize($3,2|4);
+                               T_EMIT2($1 | co_id | ($3>>6)+1,0,0,0);
+                               T_EMIT2($2,0,0,0);
+                               ea_2($3, 0);
+                       }
+       |       CPTRAPCC cp_cond
+                       {       T_EMIT2($1 | co_id | 4,0,0,0);
+                               T_EMIT2($2,0,0,0);
+                       }
+       ;
+cp_cond        :       '.' absexp
+                       {       fit(fit6($2));
+                               $$ = low6($2);
+                       }
+       ;
index 3973eec..93826e7 100644 (file)
@@ -208,6 +208,19 @@ checksize(sz, bits)
                serror("bad size");
 }
 
+check_fsize(sz, size)
+{
+       if (sz != size)
+               serror("bad size");
+}
+
+ch_sz_dreg(size, mode)
+{
+       if (mode == 0 &&
+           (size == FSIZE_X || size == FSIZE_P || size == FSIZE_D))
+               serror("illegal size for data register");
+}
+
 checkscale(val)
 valu_t val;
 {
@@ -225,7 +238,7 @@ valu_t val;
 
 badoperand()
 {
-       serror("bad operands");
+       serror("bad operand(s)");
 }
 
 shift_op(opc, sz)
@@ -466,16 +479,9 @@ move_special(sz)
 movem(dr, sz, regs)
 {
        register i;
-       register r;
 
        if ((mrg_2>>3) == 04) {
-               r = regs; regs = 0;
-               for (i = 0; i < 16; i++) {
-                       regs <<= 1;
-                       if (r & 1)
-                               regs++;
-                       r >>= 1;
-               }
+               regs = reverse(regs, 16);
        }
        checksize(sz, 2|4);
        if ((mrg_2>>3)-3 == dr)
@@ -492,6 +498,21 @@ movem(dr, sz, regs)
        ea_2(sz, i);
 }
 
+reverse(regs, max)
+       register int regs;
+{
+       register int r, i;
+
+       r = regs; regs = 0;
+       for (i = max; i > 0; i--) {
+               regs <<= 1;
+               if (r & 1)
+                       regs++;
+               r >>= 1;
+       }
+       return regs;
+}
+
 movep(sz)
 {
        checksize(sz, 2|4);
@@ -614,3 +635,28 @@ ea7071(sz)
                if (small(bd_2.typ == S_ABS && fitw(bd_2.val), 2))
                        mrg_2 = 070;
 }
+
+fbranch(opc, exp)
+expr_t exp;
+{
+       register sm;
+
+       exp.val -= (DOTVAL + 2);
+       if ((pass == PASS_2) 
+           &&
+           (exp.val > 0)
+           &&
+           ((exp.typ & S_DOT) == 0)
+          )
+               exp.val -= DOTGAIN;
+       sm = fitw(exp.val);
+       if ((exp.typ & ~S_DOT) != DOTTYP)
+               sm = 0;
+       if (small(sm,2)) {
+               T_EMIT2(0170200|co_id|opc, 0, 0, 0);
+               T_EMIT2(loww(exp.val), 0, 0, 0);
+               return;
+       }
+       T_EMIT2(0170300|co_id|opc, 0, 0, 0); /* 4 byte offset */
+       T_EMIT4(exp.val, exp.typ, RELPC|RELO4, relonami);
+}