From e64fb88a5d51a9f6fd521418b3701e4577ed575e Mon Sep 17 00:00:00 2001 From: ceriel Date: Fri, 1 Feb 1991 12:51:48 +0000 Subject: [PATCH] Added support for floating point processor --- mach/m68k2/as/mach1.c | 14 +++ mach/m68k2/as/mach2.c | 18 ++++ mach/m68k2/as/mach3.c | 211 ++++++++++++++++++++++++++++++++++++++++ mach/m68k2/as/mach4.c | 220 ++++++++++++++++++++++++++++++++++++++++++ mach/m68k2/as/mach5.c | 64 ++++++++++-- 5 files changed, 519 insertions(+), 8 deletions(-) diff --git a/mach/m68k2/as/mach1.c b/mach/m68k2/as/mach1.c index 20d09fcb6..88acece95 100644 --- a/mach/m68k2/as/mach1.c +++ b/mach/m68k2/as/mach1.c @@ -10,9 +10,12 @@ #define low3(z) ((short)(z) & 07) #define low4(z) ((short)(z) & 017) +#define low7(z) ((short)(z) & 0177) #define fit3(z) ((((z)-1) & ~((int)07)) == 0) #define fit4(z) (((z) & ~((int)017)) == 0) +#define fit7(z) (((z) & ~((int)0177)) == 0) +#define sfit7(z) (fit7((z)+64)) #define fit8(z) (((z) & ~((int)0xFF)) == 0) #define fit16(z) (((z) & ~(0xFFFFL)) == 0) @@ -22,6 +25,17 @@ #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 */ +extern int co_id; + extern int mrg_1,mrg_2; extern expr_t exp_1,exp_2; #ifndef ASLD diff --git a/mach/m68k2/as/mach2.c b/mach/m68k2/as/mach2.c index 8765f0ff1..49e7c74ed 100644 --- a/mach/m68k2/as/mach2.c +++ b/mach/m68k2/as/mach2.c @@ -42,6 +42,24 @@ %token OP_EXT %token RTD %token MODEL +%token FPCR +%token FPREG +%token FMOVE +%token FMOVECR +%token FMOVEM +%token FDYADIC +%token FMONADIC +%token FSINCOS +%token FBCC +%token FDBCC +%token FNOP +%token FSCC +%token FTST +%token FSAVRES +%token FTRAPCC +%token FSIZE +%token CP %type bcdx op_ea regs rrange %type reg sizedef sizenon creg +%type fsize fregs fcregs frlist frrange diff --git a/mach/m68k2/as/mach3.c b/mach/m68k2/as/mach3.c index 6143d5922..60741bed2 100644 --- a/mach/m68k2/as/mach3.c +++ b/mach/m68k2/as/mach3.c @@ -176,3 +176,214 @@ 0, LEA, 0, "lea", 0, RTD, 0, "rtd", + +/* 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", + +0, CP, 00000, "c0", +0, CP, 01000, "c1", +0, CP, 02000, "c2", +0, CP, 03000, "c3", +0, CP, 04000, "c4", +0, CP, 05000, "c5", +0, CP, 06000, "c6", +0, CP, 07000, "c7", diff --git a/mach/m68k2/as/mach4.c b/mach/m68k2/as/mach4.c index a8c0c36ff..9d47a9675 100644 --- a/mach/m68k2/as/mach4.c +++ b/mach/m68k2/as/mach4.c @@ -113,6 +113,7 @@ operation } | MODEL { model = $1;} + | fp_op ; bcdx : ABCD | ADDX sizedef @@ -198,3 +199,222 @@ 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(); + emit2((0170000|co_id|mrg_2)); + emit2((0100000|($5<<10))); + ea_2(SIZE_L, 0); + } + | FMOVE fsize FPCR ',' ea + { check_fsize($2, FSIZE_L); + if ((mrg_2&070) == 010 && $3 == 001) + badoperand(); + emit2((0170000|co_id|mrg_2)); + emit2((0120000|($3<<10))); + 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); + emit2((0170000|co_id|mrg_2)); + emit2((0040000|($2<<10)|($5<<7))); + 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"); + emit2((0170000|co_id|mrg_2)); + emit2((0060000|($2<<10)|($3<<7))); + ea_2(SIZE_L, DTA|ALT); + } + | FMOVE fsize FPREG ',' ea '{' '#' absexp '}' + { check_fsize($2, FSIZE_P); + fit(sfit7($8)); + emit2((0170000|co_id|mrg_2)); + emit2((0066000|($3<<7)|low7($8))); + ea_2(SIZE_L, MEM|DTA|ALT); + } + | FMOVE fsize FPREG ',' ea '{' DREG '}' + { check_fsize($2, FSIZE_P); + emit2((0170000|co_id|mrg_2)); + emit2((0076000|($3<<7)|($7<<4))); + 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"); + emit2((0170000|co_id|mrg_2)); + emit2(0160000 | + (((mrg_2&070)==040 || ($3&04000)) ? + $3 : + (010000|reverse($3,8)))); + ea_2(SIZE_L, MEM|ALT); + } + | FMOVEM FSIZE notimmreg ',' fregs + { check_fsize($2, FSIZE_X); + if ((mrg_2&070) == 040) + serror("bad addressing category"); + emit2((0170000|co_id|mrg_2)); + emit2((0150000|(($5&04000)?$5:reverse($5,8)))); + 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"); + emit2((0170000|co_id|mrg_2)); + emit2((0120000|$3)); + 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"); + emit2((0170000|co_id|mrg_2)); + emit2((0100000|$5)); + ea_2(SIZE_L, 0); + } + | FDYADIC fsize ea ',' FPREG + { emit2((0170000|co_id|mrg_2)); + emit2((0040000|($2<<10)|($5<<7)|$1)); + 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 + { emit2((0170000|co_id|mrg_2)); + emit2((0040000|($2<<10)|($5<<7)|$1)); + 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 + { emit2(0170000|co_id|mrg_2); + emit2(0040000|($2<<10)|($7<<7)|$1|$5); + 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 + { emit2(0170110|co_id|$2); + emit2($1); + $4.val -= DOTVAL; + fit(fitw($4.val)); +#ifdef RELOCATION + newrelo($4.typ, RELPC|RELO2|RELBR|RELWR); +#endif + emit2(loww($4.val)); + } + | FNOP + { emit2(0170200|co_id); + emit2(0); + } + | FSCC ea + { emit2(0170100|co_id|mrg_2); + emit2($1); + ea_2(SIZE_B, DTA|ALT); + } + | FTST fsize ea + { emit2((0170000|co_id|mrg_2)); + emit2((0040072|($2<<10))); + 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(); + emit2((0170000|co_id|($1&0700)|mrg_2)); + ea_2(0, $1&07); + } + | FTRAPCC + { emit2(0170174|co_id); + emit2($1); + } + | FTRAPCC SIZE imm + { checksize($2, 2|4); + emit2((0170170|co_id|($2==SIZE_L?03:02))); + emit2($1); + 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 + ; diff --git a/mach/m68k2/as/mach5.c b/mach/m68k2/as/mach5.c index e992aa662..bec345d22 100644 --- a/mach/m68k2/as/mach5.c +++ b/mach/m68k2/as/mach5.c @@ -286,19 +286,27 @@ move_special(sz) badoperand(); } +int +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; +} + 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) @@ -454,3 +462,43 @@ Xnofit() { if (pass == PASS_3) serror("too big"); } + +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)) { + emit2(0170200|co_id|opc); + emit2(loww(exp.val)); + return; + } + emit2(0170300|co_id|opc); /* 4 byte offset */ +#ifdef RELOCATION + newrelo(exp.typ, RELPC|RELO4|RELBR|RELWR); +#endif + emit4(exp.val); +} + +ch_sz_dreg(size, mode) +{ + if (mode == 0 && + (size == FSIZE_X || size == FSIZE_P || size == FSIZE_D)) + serror("illegal size for data register"); +} + +check_fsize(sz, size) +{ + if (sz != size) serror("bad size"); +} -- 2.34.1