Kaynağa Gözat

Added support for MC68881 floating point processor

ceriel 35 yıl önce
ebeveyn
işleme
1ccb8e2aa2

+ 15 - 0
mach/m68020/as/mach1.c

@@ -11,11 +11,14 @@
 #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)
 
@@ -25,6 +28,18 @@
 #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 */

+ 17 - 0
mach/m68020/as/mach2.c

@@ -62,8 +62,25 @@
 %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

+ 202 - 0
mach/m68020/as/mach3.c

@@ -240,3 +240,205 @@
 					        */
 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",

+ 285 - 57
mach/m68020/as/mach4.c

@@ -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);
+			}
+	;

+ 55 - 9
mach/m68020/as/mach5.c

@@ -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);
+}