@@ -32,10 +32,109 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
3232#include < vector>
3333
3434using namespace std ;
35+ using namespace dppc_interpreter ;
3536
3637int ntested; // number of tested instructions
3738int nfailed; // number of failed instructions
3839
40+ // Hack to get floating point tests working again
41+ static PPCOpcode test_fp_grabber59[2048 ];
42+ static PPCOpcode test_fp_grabber63[2048 ];
43+
44+ #define FP_Insert (op, idx, fn ) \
45+ do { \
46+ if ((op) == 59 ) \
47+ test_fp_grabber59[(idx) & 2047 ] = (fn); \
48+ else \
49+ test_fp_grabber63[(idx) & 2047 ] = (fn); \
50+ } while (0 )
51+
52+ #define OPX_fp (op, subop, fn ) FP_Insert(op, (subop) << 1 , fn)
53+
54+ #define OPXd_fp (op, subop, fn ) \
55+ do { \
56+ FP_Insert (op, ((subop) << 1 ) | 0 , fn<RC0 >); \
57+ FP_Insert (op, ((subop) << 1 ) | 1 , fn<RC1 >); \
58+ } while (0 )
59+
60+ #define OPXdc_fp (op, subop, fn, carry ) \
61+ do { \
62+ FP_Insert (op, ((subop) << 1 ) | 0 , (fn<carry, RC0 >)); \
63+ FP_Insert (op, ((subop) << 1 ) | 1 , (fn<carry, RC1 >)); \
64+ } while (0 )
65+
66+ #define OP63 (subop, fn ) OPX_fp(63 , subop, fn)
67+ #define OP63d (subop, fn ) OPXd_fp(63 , subop, fn)
68+ #define OP63dc (subop, fn, carry ) OPXdc_fp(63 , subop, fn, carry)
69+
70+ #define OP59d (subop, fn ) OPXd_fp(59 , subop, fn)
71+
72+ #define OP59cd (subop, fn ) \
73+ do { \
74+ for (uint32_t c = 0 ; c < 32 ; c++) { \
75+ OPXd_fp (59 , (c << 5 ) | (subop), fn); \
76+ } \
77+ } while (0 )
78+
79+ static void init_fp_table () {
80+ OP59d (18 , ppc_fdivs);
81+ OP59d (20 , ppc_fsubs);
82+ OP59d (21 , ppc_fadds);
83+
84+ if (ppc_state.spr [SPR ::PVR ] == PPC_VER ::MPC970MP )
85+ OP59d (22 , ppc_fsqrts);
86+
87+ if (!is_601)
88+ OP59d (24 , ppc_fres);
89+
90+ OP59d (25 , ppc_fmuls);
91+ OP59d (28 , ppc_fmsubs);
92+ OP59d (29 , ppc_fmadds);
93+ OP59d (30 , ppc_fnmsubs);
94+ OP59d (31 , ppc_fnmadds);
95+
96+ OP63 (0 , ppc_fcmpu);
97+ OP63d (12 , ppc_frsp);
98+ OP63d (14 , ppc_fctiw);
99+ OP63d (15 , ppc_fctiwz);
100+ OP63d (18 , ppc_fdiv);
101+ OP63d (20 , ppc_fsub);
102+ OP63d (21 , ppc_fadd);
103+
104+ if (ppc_state.spr [SPR ::PVR ] == PPC_VER ::MPC970MP )
105+ OP63d (22 , ppc_fsqrt);
106+
107+ if (!is_601)
108+ OP63d (26 , ppc_frsqrte);
109+
110+ OP63 (32 , ppc_fcmpo);
111+ OP63d (38 , ppc_mtfsb1);
112+ OP63d (40 , ppc_fneg);
113+ OP63 (64 , ppc_mcrfs);
114+ OP63d (70 , ppc_mtfsb0);
115+ OP63d (72 , ppc_fmr);
116+ OP63d (134 , ppc_mtfsfi);
117+ OP63d (136 , ppc_fnabs);
118+ OP63d (264 , ppc_fabs);
119+
120+ if (is_601)
121+ OP63dc (583 , ppc_mffs, IS601 );
122+ else
123+ OP63dc (583 , ppc_mffs, NOT601 );
124+
125+ OP63d (711 , ppc_mtfsf);
126+
127+ for (int i = 0 ; i < 1024 ; i += 32 ) {
128+ if (!is_601)
129+ OP63d (i + 23 , ppc_fsel);
130+ OP63d (i + 25 , ppc_fmul);
131+ OP63d (i + 28 , ppc_fmsub);
132+ OP63d (i + 29 , ppc_fmadd);
133+ OP63d (i + 30 , ppc_fnmsub);
134+ OP63d (i + 31 , ppc_fnmadd);
135+ }
136+ }
137+
39138#if defined(PPC_TESTS)
40139void ppc_exception_handler (Except_Type exception_type, uint32_t srr1_bits) {
41140 power_on = false ;
@@ -209,6 +308,8 @@ static void read_test_float_data() {
209308 return ;
210309 }
211310
311+ init_fp_table ();
312+
212313 lineno = 0 ;
213314
214315 while (getline (tf2stream, line)) {
@@ -292,7 +393,12 @@ static void read_test_float_data() {
292393
293394 ppc_state.cr = 0 ;
294395
295- ppc_main_opcode (ppc_opcode_grabber, opcode);
396+ if ((opcode >> 26 ) & 63 ) {
397+ test_fp_grabber63[opcode & 2047 ];
398+ }
399+ else {
400+ test_fp_grabber59[opcode & 2047 ];
401+ }
296402
297403 ntested++;
298404
0 commit comments