1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus - gcop1_d.c *
3
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4
* Copyright (C) 2002 Hacktarux *
6
* This program is free software; you can redistribute it and/or modify *
7
* it under the terms of the GNU General Public License as published by *
8
* the Free Software Foundation; either version 2 of the License, or *
9
* (at your option) any later version. *
11
* This program is distributed in the hope that it will be useful, *
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14
* GNU General Public License for more details. *
16
* You should have received a copy of the GNU General Public License *
17
* along with this program; if not, write to the *
18
* Free Software Foundation, Inc., *
19
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25
#include "interpret.h"
27
#include "../recomph.h"
33
#ifdef INTERPRET_ADD_D
34
gencallinterp((unsigned int)ADD_D, 0);
36
gencheck_cop1_unusable();
37
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
38
fld_preg32_qword(EAX);
39
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft]));
40
fadd_preg32_qword(EAX);
41
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
42
fstp_preg32_qword(EAX);
48
#ifdef INTERPRET_SUB_D
49
gencallinterp((unsigned int)SUB_D, 0);
51
gencheck_cop1_unusable();
52
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
53
fld_preg32_qword(EAX);
54
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft]));
55
fsub_preg32_qword(EAX);
56
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
57
fstp_preg32_qword(EAX);
63
#ifdef INTERPRET_MUL_D
64
gencallinterp((unsigned int)MUL_D, 0);
66
gencheck_cop1_unusable();
67
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
68
fld_preg32_qword(EAX);
69
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft]));
70
fmul_preg32_qword(EAX);
71
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
72
fstp_preg32_qword(EAX);
78
#ifdef INTERPRET_DIV_D
79
gencallinterp((unsigned int)DIV_D, 0);
81
gencheck_cop1_unusable();
82
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
83
fld_preg32_qword(EAX);
84
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.ft]));
85
fdiv_preg32_qword(EAX);
86
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
87
fstp_preg32_qword(EAX);
93
#ifdef INTERPRET_SQRT_D
94
gencallinterp((unsigned int)SQRT_D, 0);
96
gencheck_cop1_unusable();
97
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
98
fld_preg32_qword(EAX);
100
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
101
fstp_preg32_qword(EAX);
107
#ifdef INTERPRET_ABS_D
108
gencallinterp((unsigned int)ABS_D, 0);
110
gencheck_cop1_unusable();
111
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
112
fld_preg32_qword(EAX);
114
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
115
fstp_preg32_qword(EAX);
121
#ifdef INTERPRET_MOV_D
122
gencallinterp((unsigned int)MOV_D, 0);
124
gencheck_cop1_unusable();
125
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
126
mov_reg32_preg32(EBX, EAX);
127
mov_reg32_preg32pimm32(ECX, EAX, 4);
128
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
129
mov_preg32_reg32(EAX, EBX);
130
mov_preg32pimm32_reg32(EAX, 4, ECX);
136
#ifdef INTERPRET_NEG_D
137
gencallinterp((unsigned int)NEG_D, 0);
139
gencheck_cop1_unusable();
140
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fs]));
141
fld_preg32_qword(EAX);
143
mov_eax_memoffs32((unsigned int *)(®_cop1_double[dst->f.cf.fd]));
144
fstp_preg32_qword(EAX);
148
void genround_l_d(void)
150
#ifdef INTERPRET_ROUND_L_D
151
gencallinterp((unsigned int)ROUND_L_D, 0);
153
gencheck_cop1_unusable();
154
fldcw_m16((unsigned short*)&round_mode);
155
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
156
fld_preg32_qword(EAX);
157
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
158
fistp_preg32_qword(EAX);
159
fldcw_m16((unsigned short*)&rounding_mode);
163
void gentrunc_l_d(void)
165
#ifdef INTERPRET_TRUNC_L_D
166
gencallinterp((unsigned int)TRUNC_L_D, 0);
168
gencheck_cop1_unusable();
169
fldcw_m16((unsigned short*)&trunc_mode);
170
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
171
fld_preg32_qword(EAX);
172
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
173
fistp_preg32_qword(EAX);
174
fldcw_m16((unsigned short*)&rounding_mode);
178
void genceil_l_d(void)
180
#ifdef INTERPRET_CEIL_L_D
181
gencallinterp((unsigned int)CEIL_L_D, 0);
183
gencheck_cop1_unusable();
184
fldcw_m16((unsigned short*)&ceil_mode);
185
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
186
fld_preg32_qword(EAX);
187
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
188
fistp_preg32_qword(EAX);
189
fldcw_m16((unsigned short*)&rounding_mode);
193
void genfloor_l_d(void)
195
#ifdef INTERPRET_FLOOR_L_D
196
gencallinterp((unsigned int)FLOOR_L_D, 0);
198
gencheck_cop1_unusable();
199
fldcw_m16((unsigned short*)&floor_mode);
200
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
201
fld_preg32_qword(EAX);
202
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
203
fistp_preg32_qword(EAX);
204
fldcw_m16((unsigned short*)&rounding_mode);
208
void genround_w_d(void)
210
#ifdef INTERPRET_ROUND_W_D
211
gencallinterp((unsigned int)ROUND_W_D, 0);
213
gencheck_cop1_unusable();
214
fldcw_m16((unsigned short*)&round_mode);
215
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
216
fld_preg32_qword(EAX);
217
mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
218
fistp_preg32_dword(EAX);
219
fldcw_m16((unsigned short*)&rounding_mode);
223
void gentrunc_w_d(void)
225
#ifdef INTERPRET_TRUNC_W_D
226
gencallinterp((unsigned int)TRUNC_W_D, 0);
228
gencheck_cop1_unusable();
229
fldcw_m16((unsigned short*)&trunc_mode);
230
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
231
fld_preg32_qword(EAX);
232
mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
233
fistp_preg32_dword(EAX);
234
fldcw_m16((unsigned short*)&rounding_mode);
238
void genceil_w_d(void)
240
#ifdef INTERPRET_CEIL_W_D
241
gencallinterp((unsigned int)CEIL_W_D, 0);
243
gencheck_cop1_unusable();
244
fldcw_m16((unsigned short*)&ceil_mode);
245
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
246
fld_preg32_qword(EAX);
247
mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
248
fistp_preg32_dword(EAX);
249
fldcw_m16((unsigned short*)&rounding_mode);
253
void genfloor_w_d(void)
255
#ifdef INTERPRET_FLOOR_W_D
256
gencallinterp((unsigned int)FLOOR_W_D, 0);
258
gencheck_cop1_unusable();
259
fldcw_m16((unsigned short*)&floor_mode);
260
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
261
fld_preg32_qword(EAX);
262
mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
263
fistp_preg32_dword(EAX);
264
fldcw_m16((unsigned short*)&rounding_mode);
268
void gencvt_s_d(void)
270
#ifdef INTERPRET_CVT_S_D
271
gencallinterp((unsigned int)CVT_S_D, 0);
273
gencheck_cop1_unusable();
274
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
275
fld_preg32_qword(EAX);
276
mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
277
fstp_preg32_dword(EAX);
281
void gencvt_w_d(void)
283
#ifdef INTERPRET_CVT_W_D
284
gencallinterp((unsigned int)CVT_W_D, 0);
286
gencheck_cop1_unusable();
287
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
288
fld_preg32_qword(EAX);
289
mov_eax_memoffs32((unsigned int*)(®_cop1_simple[dst->f.cf.fd]));
290
fistp_preg32_dword(EAX);
294
void gencvt_l_d(void)
296
#ifdef INTERPRET_CVT_L_D
297
gencallinterp((unsigned int)CVT_L_D, 0);
299
gencheck_cop1_unusable();
300
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
301
fld_preg32_qword(EAX);
302
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fd]));
303
fistp_preg32_qword(EAX);
309
#ifdef INTERPRET_C_F_D
310
gencallinterp((unsigned int)C_F_D, 0);
312
gencheck_cop1_unusable();
313
and_m32_imm32((unsigned int*)&FCR31, ~0x800000);
319
#ifdef INTERPRET_C_UN_D
320
gencallinterp((unsigned int)C_UN_D, 0);
322
gencheck_cop1_unusable();
323
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
324
fld_preg32_qword(EAX);
325
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
326
fld_preg32_qword(EAX);
330
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
331
jmp_imm_short(10); // 2
332
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
338
#ifdef INTERPRET_C_EQ_D
339
gencallinterp((unsigned int)C_EQ_D, 0);
341
gencheck_cop1_unusable();
342
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
343
fld_preg32_qword(EAX);
344
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
345
fld_preg32_qword(EAX);
349
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
350
jmp_imm_short(10); // 2
351
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
355
void genc_ueq_d(void)
357
#ifdef INTERPRET_C_UEQ_D
358
gencallinterp((unsigned int)C_UEQ_D, 0);
360
gencheck_cop1_unusable();
361
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
362
fld_preg32_qword(EAX);
363
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
364
fld_preg32_qword(EAX);
369
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
370
jmp_imm_short(10); // 2
371
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
375
void genc_olt_d(void)
377
#ifdef INTERPRET_C_OLT_D
378
gencallinterp((unsigned int)C_OLT_D, 0);
380
gencheck_cop1_unusable();
381
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
382
fld_preg32_qword(EAX);
383
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
384
fld_preg32_qword(EAX);
388
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
389
jmp_imm_short(10); // 2
390
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
394
void genc_ult_d(void)
396
#ifdef INTERPRET_C_ULT_D
397
gencallinterp((unsigned int)C_ULT_D, 0);
399
gencheck_cop1_unusable();
400
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
401
fld_preg32_qword(EAX);
402
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
403
fld_preg32_qword(EAX);
408
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
409
jmp_imm_short(10); // 2
410
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
414
void genc_ole_d(void)
416
#ifdef INTERPRET_C_OLE_D
417
gencallinterp((unsigned int)C_OLE_D, 0);
419
gencheck_cop1_unusable();
420
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
421
fld_preg32_qword(EAX);
422
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
423
fld_preg32_qword(EAX);
427
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
428
jmp_imm_short(10); // 2
429
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
433
void genc_ule_d(void)
435
#ifdef INTERPRET_C_ULE_D
436
gencallinterp((unsigned int)C_ULE_D, 0);
438
gencheck_cop1_unusable();
439
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
440
fld_preg32_qword(EAX);
441
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
442
fld_preg32_qword(EAX);
447
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
448
jmp_imm_short(10); // 2
449
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
455
#ifdef INTERPRET_C_SF_D
456
gencallinterp((unsigned int)C_SF_D, 0);
458
gencheck_cop1_unusable();
459
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
460
fld_preg32_qword(EAX);
461
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
462
fld_preg32_qword(EAX);
465
and_m32_imm32((unsigned int*)&FCR31, ~0x800000);
469
void genc_ngle_d(void)
471
#ifdef INTERPRET_C_NGLE_D
472
gencallinterp((unsigned int)C_NGLE_D, 0);
474
gencheck_cop1_unusable();
475
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
476
fld_preg32_qword(EAX);
477
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
478
fld_preg32_qword(EAX);
482
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
483
jmp_imm_short(10); // 2
484
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
488
void genc_seq_d(void)
490
#ifdef INTERPRET_C_SEQ_D
491
gencallinterp((unsigned int)C_SEQ_D, 0);
493
gencheck_cop1_unusable();
494
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
495
fld_preg32_qword(EAX);
496
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
497
fld_preg32_qword(EAX);
501
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
502
jmp_imm_short(10); // 2
503
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
507
void genc_ngl_d(void)
509
#ifdef INTERPRET_C_NGL_D
510
gencallinterp((unsigned int)C_NGL_D, 0);
512
gencheck_cop1_unusable();
513
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
514
fld_preg32_qword(EAX);
515
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
516
fld_preg32_qword(EAX);
521
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
522
jmp_imm_short(10); // 2
523
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
529
#ifdef INTERPRET_C_LT_D
530
gencallinterp((unsigned int)C_LT_D, 0);
532
gencheck_cop1_unusable();
533
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
534
fld_preg32_qword(EAX);
535
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
536
fld_preg32_qword(EAX);
540
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
541
jmp_imm_short(10); // 2
542
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
546
void genc_nge_d(void)
548
#ifdef INTERPRET_C_NGE_D
549
gencallinterp((unsigned int)C_NGE_D, 0);
551
gencheck_cop1_unusable();
552
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
553
fld_preg32_qword(EAX);
554
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
555
fld_preg32_qword(EAX);
560
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
561
jmp_imm_short(10); // 2
562
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
568
#ifdef INTERPRET_C_LE_D
569
gencallinterp((unsigned int)C_LE_D, 0);
571
gencheck_cop1_unusable();
572
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
573
fld_preg32_qword(EAX);
574
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
575
fld_preg32_qword(EAX);
579
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
580
jmp_imm_short(10); // 2
581
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10
585
void genc_ngt_d(void)
587
#ifdef INTERPRET_C_NGT_D
588
gencallinterp((unsigned int)C_NGT_D, 0);
590
gencheck_cop1_unusable();
591
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.ft]));
592
fld_preg32_qword(EAX);
593
mov_eax_memoffs32((unsigned int*)(®_cop1_double[dst->f.cf.fs]));
594
fld_preg32_qword(EAX);
599
or_m32_imm32((unsigned int*)&FCR31, 0x800000); // 10
600
jmp_imm_short(10); // 2
601
and_m32_imm32((unsigned int*)&FCR31, ~0x800000); // 10