2 // Aaron Giles GPU core
5 static UINT8 * condition_table = NULL;
6 static UINT16 * mirror_table = NULL;
7 static const UINT32 convert_zero[32] =
8 { 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
16 /* allocate the mirror table */
18 mirror_table = (UINT16 *)malloc(65536 * sizeof(mirror_table[0]));
20 /* fill in the mirror table */
22 for (i = 0; i < 65536; i++)
23 mirror_table[i] = ((i >> 15) & 0x0001) | ((i >> 13) & 0x0002) |
24 ((i >> 11) & 0x0004) | ((i >> 9) & 0x0008) |
25 ((i >> 7) & 0x0010) | ((i >> 5) & 0x0020) |
26 ((i >> 3) & 0x0040) | ((i >> 1) & 0x0080) |
27 ((i << 1) & 0x0100) | ((i << 3) & 0x0200) |
28 ((i << 5) & 0x0400) | ((i << 7) & 0x0800) |
29 ((i << 9) & 0x1000) | ((i << 11) & 0x2000) |
30 ((i << 13) & 0x4000) | ((i << 15) & 0x8000);
32 /* allocate the condition table */
34 condition_table = (UINT8 *)malloc(32 * 8 * sizeof(condition_table[0]));
36 /* fill in the condition table */
38 for (i = 0; i < 8; i++)
39 for (j = 0; j < 32; j++)
43 if (i & ZERO_FLAG) result = 0;
45 if (!(i & ZERO_FLAG)) result = 0;
47 if (i & (CARRY_FLAG << (j >> 4))) result = 0;
49 if (!(i & (CARRY_FLAG << (j >> 4)))) result = 0;
50 condition_table[i * 32 + j] = result;
54 /*###################################################################################################
56 **#################################################################################################*/
61 UINT32 res = gpu_reg[dreg];
65 gpu_reg[dreg] = res = -res;
74 UINT32 r1 = gpu_reg[IMM_1];
75 UINT32 r2 = gpu_reg[dreg];
78 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
84 UINT32 r1 = gpu_reg[IMM_1];
85 UINT32 r2 = gpu_reg[dreg];
86 UINT32 res = r2 + r1 + (gpu_flag_c);
88 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
94 UINT32 r1 = convert_zero[IMM_1];
95 UINT32 r2 = gpu_reg[dreg];
98 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
101 void addqmod_n_rn(void) /* DSP only */
104 UINT32 r1 = convert_zero[IMM_1];
105 UINT32 r2 = gpu_reg[dreg];
106 UINT32 res = r2 + r1;
107 res = (res & ~jaguar.ctrl[D_MOD]) | (r2 & ~jaguar.ctrl[D_MOD]);
109 CLR_ZNC; SET_ZNC_ADD(r2,r1,res);*/
112 void addqt_n_rn(void)
115 UINT32 r1 = convert_zero[IMM_1];
116 UINT32 r2 = gpu_reg[dreg];
117 UINT32 res = r2 + r1;
124 UINT32 r1 = gpu_reg[IMM_1];
125 UINT32 r2 = gpu_reg[dreg];
126 UINT32 res = r2 & r1;
135 UINT32 r2 = gpu_reg[dreg];
136 UINT32 res = r2 & ~(1 << r1);
145 UINT32 r2 = gpu_reg[dreg];
146 UINT32 res = r2 | (1 << r1);
154 UINT32 r2 = gpu_reg[IMM_2];
155 CLR_Z; gpu_flag_z = (~r2 >> r1) & 1;
160 UINT32 r1 = gpu_reg[IMM_1];
161 UINT32 r2 = gpu_reg[IMM_2];
162 UINT32 res = r2 - r1;
163 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
168 UINT32 r1 = (INT8)(gpu_instruction >> 2) >> 3;
169 UINT32 r2 = gpu_reg[IMM_2];
170 UINT32 res = r2 - r1;
171 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
177 UINT32 r1 = gpu_reg[IMM_1];
178 UINT32 r2 = gpu_reg[dreg];
181 if (gpu_div_control & 1)
183 gpu_reg[dreg] = ((UINT64)r2 << 16) / r1;
184 gpu_remain = ((UINT64)r2 << 16) % r1;
188 gpu_reg[dreg] = r2 / r1;
189 gpu_remain = r2 % r1;
193 gpu_reg[dreg] = 0xffffffff;
200 void imacn_rn_rn(void)
202 UINT32 r1 = gpu_reg[IMM_1];
203 UINT32 r2 = gpu_reg[IMM_2];
204 gpu_acc += (INT64)((INT16)r1 * (INT16)r2);
205 // logerror("Unexpected IMACN instruction!\n");
208 void imult_rn_rn(void)
211 UINT32 r1 = gpu_reg[IMM_1];
212 UINT32 r2 = gpu_reg[dreg];
213 UINT32 res = (INT16)r1 * (INT16)r2;
218 void imultn_rn_rn(void)
221 UINT32 r1 = gpu_reg[IMM_1];
222 UINT32 r2 = gpu_reg[dreg];
223 UINT32 res = (INT16)r1 * (INT16)r2;
224 gpu_acc = (INT32)res;
227 // gpu_instruction = ROPCODE(gpu_pc);
228 gpu_instruction = gpu_word_read(gpu_pc);
229 while ((gpu_instruction >> 10) == 20)
233 gpu_acc += (INT64)((INT16)r1 * (INT16)r2);
235 // gpu_instruction = ROPCODE(gpu_pc);
236 gpu_instruction = gpu_word_read(gpu_pc);
238 if ((gpu_instruction >> 10) == 19)
241 gpu_reg[IMM_2] = (UINT32)gpu_acc;
247 // if (CONDITION(IMM_2))
248 uint32 jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z;
249 if (BRANCH_CONDITION(IMM_2))
251 INT32 r1 = (INT8)((gpu_instruction >> 2) & 0xf8) >> 2;
252 UINT32 newpc = gpu_pc + r1;
254 gpu_instruction = ROPCODE(gpu_pc);
256 (*jaguar.table[gpu_instruction >> 10])();
258 jaguar_icount -= 3; // 3 wait states guaranteed*/
264 void jump_cc_rn(void)
266 // if (CONDITION(IMM_2))
267 uint32 jaguar_flags = (gpu_flag_n << 2) | (gpu_flag_c << 1) | gpu_flag_z;
268 if (BRANCH_CONDITION(IMM_2))
272 // special kludge for risky code in the cojag DSP interrupt handlers
273 /* UINT32 newpc = (jaguar_icount == bankswitch_icount) ? gpu_alternate_reg[reg] : gpu_reg[reg];
275 gpu_instruction = ROPCODE(gpu_pc);
277 (*jaguar.table[gpu_instruction >> 10])();
279 jaguar_icount -= 3; // 3 wait states guaranteed*/
280 UINT32 newpc = gpu_reg[reg];
286 void load_rn_rn(void)
288 UINT32 r1 = gpu_reg[IMM_1];
289 // gpu_reg[IMM_2] = READLONG(r1);
290 gpu_reg[IMM_2] = gpu_long_read(r1);
293 void load_r14n_rn(void)
295 UINT32 r1 = convert_zero[IMM_1];
296 // gpu_reg[IMM_2] = READLONG(gpu_reg[14] + 4 * r1);
297 gpu_reg[IMM_2] = gpu_long_read(gpu_reg[14] + 4 * r1);
300 void load_r15n_rn(void)
302 UINT32 r1 = convert_zero[IMM_1];
303 // gpu_reg[IMM_2] = READLONG(gpu_reg[15] + 4 * r1);
304 gpu_reg[IMM_2] = gpu_long_read(gpu_reg[15] + 4 * r1);
307 void load_r14rn_rn(void)
309 UINT32 r1 = gpu_reg[IMM_1];
310 // gpu_reg[IMM_2] = READLONG(gpu_reg[14] + r1);
311 gpu_reg[IMM_2] = gpu_long_read(gpu_reg[14] + r1);
314 void load_r15rn_rn(void)
316 UINT32 r1 = gpu_reg[IMM_1];
317 // gpu_reg[IMM_2] = READLONG(gpu_reg[15] + r1);
318 gpu_reg[IMM_2] = gpu_long_read(gpu_reg[15] + r1);
321 void loadb_rn_rn(void)
323 UINT32 r1 = gpu_reg[IMM_1];
324 // gpu_reg[IMM_2] = READBYTE(r1);
325 gpu_reg[IMM_2] = gpu_byte_read(r1);
328 void loadw_rn_rn(void)
330 UINT32 r1 = gpu_reg[IMM_1];
331 // gpu_reg[IMM_2] = READWORD(r1);
332 gpu_reg[IMM_2] = gpu_word_read(r1);
335 void loadp_rn_rn(void) /* GPU only */
337 UINT32 r1 = gpu_reg[IMM_1];
338 // Is this a bug? I'm sure he meant to read DWORDs here, not just WORDs...
339 // gpu_hidata = READWORD(r1);
340 // gpu_reg[IMM_2] = READWORD(r1+4);
341 gpu_hidata = gpu_long_read(r1);
342 gpu_reg[IMM_2] = gpu_long_read(r1+4);
345 void mirror_rn(void) /* DSP only */
348 UINT32 r1 = gpu_reg[dreg];
349 UINT32 res = (mirror_table[r1 & 0xffff] << 16) | mirror_table[r1 >> 16];
351 CLR_ZN; SET_ZN(res);*/
354 void mmult_rn_rn(void)
356 int count = gpu_matrix_control & 15, i;
359 UINT32 addr = gpu_pointer_to_matrix;
363 if (!(gpu_matrix_control & 0x10))
365 for (i = 0; i < count; i++)
367 // accum += (INT16)(gpu_reg_bank_1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)READWORD(addr);
368 accum += (INT16)(gpu_reg_bank_1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)gpu_word_read(addr);
374 for (i = 0; i < count; i++)
376 // accum += (INT16)(gpu_reg_bank_1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)READWORD(addr);
377 accum += (INT16)(gpu_reg_bank_1[sreg + i/2] >> (16 * ((i & 1) ^ 1))) * (INT16)gpu_word_read(addr);
381 gpu_reg[dreg] = res = (UINT32)accum;
385 void move_rn_rn(void)
387 gpu_reg[IMM_2] = gpu_reg[IMM_1];
390 void move_pc_rn(void)
392 // gpu_reg[IMM_2] = jaguar.ppc;
393 gpu_reg[IMM_2] = gpu_pc - 2;
396 void movefa_rn_rn(void)
398 gpu_reg[IMM_2] = gpu_alternate_reg[IMM_1];
401 void movei_n_rn(void)
403 // UINT32 res = ROPCODE(gpu_pc) | (ROPCODE(gpu_pc + 2) << 16);
404 UINT32 res = gpu_word_read(gpu_pc) | (gpu_word_read(gpu_pc + 2) << 16);
406 gpu_reg[IMM_2] = res;
409 void moveq_n_rn(void)
411 gpu_reg[IMM_2] = IMM_1;
414 void moveta_rn_rn(void)
416 gpu_alternate_reg[IMM_2] = gpu_reg[IMM_1];
419 void mtoi_rn_rn(void)
421 UINT32 r1 = gpu_reg[IMM_1];
422 gpu_reg[IMM_2] = (((INT32)r1 >> 8) & 0xff800000) | (r1 & 0x007fffff);
425 void mult_rn_rn(void)
428 UINT32 r1 = gpu_reg[IMM_1];
429 UINT32 r2 = gpu_reg[dreg];
430 UINT32 res = (UINT16)r1 * (UINT16)r2;
438 UINT32 r2 = gpu_reg[dreg];
441 CLR_ZNC; SET_ZNC_SUB(0,r2,res);
448 void normi_rn_rn(void)
450 UINT32 r1 = gpu_reg[IMM_1];
452 while ((r1 & 0xffc00000) == 0)
457 while ((r1 & 0xff800000) != 0)
462 gpu_reg[IMM_2] = res;
469 UINT32 res = ~gpu_reg[dreg];
477 UINT32 r1 = gpu_reg[IMM_1];
478 UINT32 r2 = gpu_reg[dreg];
479 UINT32 res = r1 | r2;
484 void pack_rn(void) /* GPU only */
487 UINT32 r1 = gpu_reg[IMM_1];
488 UINT32 r2 = gpu_reg[dreg];
490 if (r1 == 0) /* PACK */
491 res = ((r2 >> 10) & 0xf000) | ((r2 >> 5) & 0x0f00) | (r2 & 0xff);
493 res = ((r2 & 0xf000) << 10) | ((r2 & 0x0f00) << 5) | (r2 & 0xff);
500 gpu_reg[IMM_2] = (UINT32)gpu_acc;
506 UINT32 r1 = gpu_reg[IMM_1] & 31;
507 UINT32 r2 = gpu_reg[dreg];
508 UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
510 CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01;
516 UINT32 r1 = convert_zero[IMM_1];
517 UINT32 r2 = gpu_reg[dreg];
518 UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
520 CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01;
523 void sat8_rn(void) /* GPU only */
526 INT32 r2 = gpu_reg[dreg];
527 UINT32 res = (r2 < 0) ? 0 : (r2 > 255) ? 255 : r2;
532 void sat16_rn(void) /* GPU only */
535 INT32 r2 = gpu_reg[dreg];
536 UINT32 res = (r2 < 0) ? 0 : (r2 > 65535) ? 65535 : r2;
541 void sat16s_rn(void) /* DSP only */
544 INT32 r2 = gpu_reg[dreg];
545 UINT32 res = (r2 < -32768) ? -32768 : (r2 > 32767) ? 32767 : r2;
547 CLR_ZN; SET_ZN(res);*/
550 void sat24_rn(void) /* GPU only */
553 INT32 r2 = gpu_reg[dreg];
554 UINT32 res = (r2 < 0) ? 0 : (r2 > 16777215) ? 16777215 : r2;
559 void sat32s_rn(void) /* DSP only */
562 INT32 r2 = (UINT32)gpu_reg[dreg];
563 INT32 temp = gpu_acc >> 32;
564 UINT32 res = (temp < -1) ? (INT32)0x80000000 : (temp > 0) ? (INT32)0x7fffffff : r2;
566 CLR_ZN; SET_ZN(res);*/
572 INT32 r1 = (INT32)gpu_reg[IMM_1];
573 UINT32 r2 = gpu_reg[dreg];
579 res = (r1 <= -32) ? 0 : (r2 << -r1);
580 gpu_flag_c = (r2 >> 31) & 0x01;
584 res = (r1 >= 32) ? 0 : (r2 >> r1);
585 gpu_flag_c = r2 & 0x01;
594 INT32 r1 = (INT32)gpu_reg[IMM_1];
595 UINT32 r2 = gpu_reg[dreg];
601 res = (r1 <= -32) ? 0 : (r2 << -r1);
602 gpu_flag_c = (r2 >> 31) & 0x01;
606 res = (r1 >= 32) ? ((INT32)r2 >> 31) : ((INT32)r2 >> r1);
607 // jaguar.FLAGS |= (r2 << 1) & 2;
608 gpu_flag_c = r2 & 0x01;
614 void sharq_n_rn(void)
617 INT32 r1 = convert_zero[IMM_1];
618 UINT32 r2 = gpu_reg[dreg];
619 UINT32 res = (INT32)r2 >> r1;
621 // CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2;
622 CLR_ZNC; SET_ZN(res); gpu_flag_c = r2 & 0x01;
628 INT32 r1 = convert_zero[IMM_1];
629 UINT32 r2 = gpu_reg[dreg];
630 UINT32 res = r2 << (32 - r1);
632 CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01;
638 INT32 r1 = convert_zero[IMM_1];
639 UINT32 r2 = gpu_reg[dreg];
640 UINT32 res = r2 >> r1;
642 // CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2;
643 CLR_ZNC; SET_ZN(res); gpu_flag_c = r2 & 0x01;
646 void store_rn_rn(void)
648 UINT32 r1 = gpu_reg[IMM_1];
649 // WRITELONG(r1, gpu_reg[IMM_2]);
650 gpu_long_write(r1, gpu_reg[IMM_2]);
653 void store_rn_r14n(void)
655 UINT32 r1 = convert_zero[IMM_1];
656 // WRITELONG(gpu_reg[14] + r1 * 4, gpu_reg[IMM_2]);
657 gpu_long_write(gpu_reg[14] + r1 * 4, gpu_reg[IMM_2]);
660 void store_rn_r15n(void)
662 UINT32 r1 = convert_zero[IMM_1];
663 // WRITELONG(gpu_reg[15] + r1 * 4, gpu_reg[IMM_2]);
664 gpu_long_write(gpu_reg[15] + r1 * 4, gpu_reg[IMM_2]);
667 void store_rn_r14rn(void)
669 UINT32 r1 = gpu_reg[IMM_1];
670 // WRITELONG(gpu_reg[14] + r1, gpu_reg[IMM_2]);
671 gpu_long_write(gpu_reg[14] + r1, gpu_reg[IMM_2]);
674 void store_rn_r15rn(void)
676 UINT32 r1 = gpu_reg[IMM_1];
677 // WRITELONG(gpu_reg[15] + r1, gpu_reg[IMM_2]);
678 gpu_long_write(gpu_reg[15] + r1, gpu_reg[IMM_2]);
681 void storeb_rn_rn(void)
683 UINT32 r1 = gpu_reg[IMM_1];
684 // WRITEBYTE(r1, gpu_reg[IMM_2]);
685 gpu_byte_write(r1, gpu_reg[IMM_2]);
688 void storew_rn_rn(void)
690 UINT32 r1 = gpu_reg[IMM_1];
691 // WRITEWORD(r1, gpu_reg[IMM_2]);
692 gpu_word_write(r1, gpu_reg[IMM_2]);
695 void storep_rn_rn(void) /* GPU only */
697 UINT32 r1 = gpu_reg[IMM_1];
698 // WRITELONG(r1, gpu_hidata);
699 // WRITELONG(r1+4, gpu_reg[IMM_2]);
700 gpu_long_write(r1, gpu_hidata);
701 gpu_long_write(r1+4, gpu_reg[IMM_2]);
707 UINT32 r1 = gpu_reg[IMM_1];
708 UINT32 r2 = gpu_reg[dreg];
709 UINT32 res = r2 - r1;
711 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
714 void subc_rn_rn(void)
717 UINT32 r1 = gpu_reg[IMM_1];
718 UINT32 r2 = gpu_reg[dreg];
719 UINT32 res = r2 - r1 - (gpu_flag_c);
721 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
727 UINT32 r1 = convert_zero[IMM_1];
728 UINT32 r2 = gpu_reg[dreg];
729 UINT32 res = r2 - r1;
731 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
734 void subqmod_n_rn(void) /* DSP only */
737 UINT32 r1 = convert_zero[IMM_1];
738 UINT32 r2 = gpu_reg[dreg];
739 UINT32 res = r2 - r1;
740 res = (res & ~jaguar.ctrl[D_MOD]) | (r2 & ~jaguar.ctrl[D_MOD]);
742 CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/
745 void subqt_n_rn(void)
748 UINT32 r1 = convert_zero[IMM_1];
749 UINT32 r2 = gpu_reg[dreg];
750 UINT32 res = r2 - r1;
757 UINT32 r1 = gpu_reg[IMM_1];
758 UINT32 r2 = gpu_reg[dreg];
759 UINT32 res = r1 ^ r2;