]> Shamusworld >> Repos - virtualjaguar/blob - src/gpu3.cpp
a65345177c45a5d446bdd4a756e247f9c4be3bfb
[virtualjaguar] / src / gpu3.cpp
1 //
2 // Aaron Giles GPU core
3 //
4
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 };
9
10 // Initialization
11
12 void gpu3_init(void)
13 {
14         int i, j;
15
16         /* allocate the mirror table */
17         if (!mirror_table)
18                 mirror_table = (UINT16 *)malloc(65536 * sizeof(mirror_table[0]));
19
20         /* fill in the mirror table */
21         if (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);
31
32         /* allocate the condition table */
33         if (!condition_table)
34                 condition_table = (UINT8 *)malloc(32 * 8 * sizeof(condition_table[0]));
35
36         /* fill in the condition table */
37         if (condition_table)
38                 for (i = 0; i < 8; i++)
39                         for (j = 0; j < 32; j++)
40                         {
41                                 int result = 1;
42                                 if (j & 1)
43                                         if (i & ZERO_FLAG) result = 0;
44                                 if (j & 2)
45                                         if (!(i & ZERO_FLAG)) result = 0;
46                                 if (j & 4)
47                                         if (i & (CARRY_FLAG << (j >> 4))) result = 0;
48                                 if (j & 8)
49                                         if (!(i & (CARRY_FLAG << (j >> 4)))) result = 0;
50                                 condition_table[i * 32 + j] = result;
51                         }
52 }
53
54 /*###################################################################################################
55 **      OPCODES
56 **#################################################################################################*/
57
58 void abs_rn(void)
59 {
60         int dreg = IMM_2;
61         UINT32 res = gpu_reg[dreg];
62         CLR_ZNC;
63         if (res & 0x80000000)
64         {
65                 gpu_reg[dreg] = res = -res;
66                 gpu_flag_c = 1;
67         }
68         SET_Z(res);
69 }
70
71 void add_rn_rn(void)
72 {
73         int dreg = IMM_2;
74         UINT32 r1 = gpu_reg[IMM_1];
75         UINT32 r2 = gpu_reg[dreg];
76         UINT32 res = r2 + r1;
77         gpu_reg[dreg] = res;
78         CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
79 }
80
81 void addc_rn_rn(void)
82 {
83         int dreg = IMM_2;
84         UINT32 r1 = gpu_reg[IMM_1];
85         UINT32 r2 = gpu_reg[dreg];
86         UINT32 res = r2 + r1 + (gpu_flag_c);
87         gpu_reg[dreg] = res;
88         CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
89 }
90
91 void addq_n_rn(void)
92 {
93         int dreg = IMM_2;
94         UINT32 r1 = convert_zero[IMM_1];
95         UINT32 r2 = gpu_reg[dreg];
96         UINT32 res = r2 + r1;
97         gpu_reg[dreg] = res;
98         CLR_ZNC; SET_ZNC_ADD(r2,r1,res);
99 }
100
101 void addqmod_n_rn(void) /* DSP only */
102 {
103 /*      int dreg = IMM_2;
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]);
108         gpu_reg[dreg] = res;
109         CLR_ZNC; SET_ZNC_ADD(r2,r1,res);*/
110 }
111
112 void addqt_n_rn(void)
113 {
114         int dreg = IMM_2;
115         UINT32 r1 = convert_zero[IMM_1];
116         UINT32 r2 = gpu_reg[dreg];
117         UINT32 res = r2 + r1;
118         gpu_reg[dreg] = res;
119 }
120
121 void and_rn_rn(void)
122 {
123         int dreg = IMM_2;
124         UINT32 r1 = gpu_reg[IMM_1];
125         UINT32 r2 = gpu_reg[dreg];
126         UINT32 res = r2 & r1;
127         gpu_reg[dreg] = res;
128         CLR_ZN; SET_ZN(res);
129 }
130
131 void bclr_n_rn(void)
132 {
133         int dreg = IMM_2;
134         UINT32 r1 = IMM_1;
135         UINT32 r2 = gpu_reg[dreg];
136         UINT32 res = r2 & ~(1 << r1);
137         gpu_reg[dreg] = res;
138         CLR_ZN; SET_ZN(res);
139 }
140
141 void bset_n_rn(void)
142 {
143         int dreg = IMM_2;
144         UINT32 r1 = IMM_1;
145         UINT32 r2 = gpu_reg[dreg];
146         UINT32 res = r2 | (1 << r1);
147         gpu_reg[dreg] = res;
148         CLR_ZN; SET_ZN(res);
149 }
150
151 void btst_n_rn(void)
152 {
153         UINT32 r1 = IMM_1;
154         UINT32 r2 = gpu_reg[IMM_2];
155         CLR_Z; gpu_flag_z = (~r2 >> r1) & 1;
156 }
157
158 void cmp_rn_rn(void)
159 {
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);
164 }
165
166 void cmpq_n_rn(void)
167 {
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);
172 }
173
174 void div_rn_rn(void)
175 {
176         int dreg = IMM_2;
177         UINT32 r1 = gpu_reg[IMM_1];
178         UINT32 r2 = gpu_reg[dreg];
179         if (r1)
180         {
181                 if (gpu_div_control & 1)
182                 {
183                         gpu_reg[dreg] = ((UINT64)r2 << 16) / r1;
184                         gpu_remain = ((UINT64)r2 << 16) % r1;
185                 }
186                 else
187                 {
188                         gpu_reg[dreg] = r2 / r1;
189                         gpu_remain = r2 % r1;
190                 }
191         }
192         else
193                 gpu_reg[dreg] = 0xffffffff;
194 }
195
196 void illegal(void)
197 {
198 }
199
200 void imacn_rn_rn(void)
201 {
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");
206 }
207
208 void imult_rn_rn(void)
209 {
210         int dreg = IMM_2;
211         UINT32 r1 = gpu_reg[IMM_1];
212         UINT32 r2 = gpu_reg[dreg];
213         UINT32 res = (INT16)r1 * (INT16)r2;
214         gpu_reg[dreg] = res;
215         CLR_ZN; SET_ZN(res);
216 }
217
218 void imultn_rn_rn(void)
219 {
220         int dreg = IMM_2;
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;
225         CLR_ZN; SET_ZN(res);
226
227 //      gpu_instruction = ROPCODE(gpu_pc);
228         gpu_instruction = gpu_word_read(gpu_pc);
229         while ((gpu_instruction >> 10) == 20)
230         {
231                 r1 = gpu_reg[IMM_1];
232                 r2 = gpu_reg[IMM_2];
233                 gpu_acc += (INT64)((INT16)r1 * (INT16)r2);
234                 gpu_pc += 2;
235 //              gpu_instruction = ROPCODE(gpu_pc);
236                 gpu_instruction = gpu_word_read(gpu_pc);
237         }
238         if ((gpu_instruction >> 10) == 19)
239         {
240                 gpu_pc += 2;
241                 gpu_reg[IMM_2] = (UINT32)gpu_acc;
242         }
243 }
244
245 void jr_cc_n(void)
246 {
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))
250         {
251                 INT32 r1 = (INT8)((gpu_instruction >> 2) & 0xf8) >> 2;
252                 UINT32 newpc = gpu_pc + r1;
253 /*              CALL_MAME_DEBUG;
254                 gpu_instruction = ROPCODE(gpu_pc);
255                 gpu_pc = newpc;
256                 (*jaguar.table[gpu_instruction >> 10])();
257
258                 jaguar_icount -= 3;     // 3 wait states guaranteed*/
259                 gpu_exec(1);
260                 gpu_pc = newpc;
261         }
262 }
263
264 void jump_cc_rn(void)
265 {
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))
269         {
270                 UINT8 reg = IMM_1;
271
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];
274                 CALL_MAME_DEBUG;
275                 gpu_instruction = ROPCODE(gpu_pc);
276                 gpu_pc = newpc;
277                 (*jaguar.table[gpu_instruction >> 10])();
278
279                 jaguar_icount -= 3;     // 3 wait states guaranteed*/
280                 UINT32 newpc = gpu_reg[reg];
281                 gpu_exec(1);
282                 gpu_pc = newpc;
283         }
284 }
285
286 void load_rn_rn(void)
287 {
288         UINT32 r1 = gpu_reg[IMM_1];
289 //      gpu_reg[IMM_2] = READLONG(r1);
290         gpu_reg[IMM_2] = gpu_long_read(r1);
291 }
292
293 void load_r14n_rn(void)
294 {
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);
298 }
299
300 void load_r15n_rn(void)
301 {
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);
305 }
306
307 void load_r14rn_rn(void)
308 {
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);
312 }
313
314 void load_r15rn_rn(void)
315 {
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);
319 }
320
321 void loadb_rn_rn(void)
322 {
323         UINT32 r1 = gpu_reg[IMM_1];
324 //      gpu_reg[IMM_2] = READBYTE(r1);
325         gpu_reg[IMM_2] = gpu_byte_read(r1);
326 }
327
328 void loadw_rn_rn(void)
329 {
330         UINT32 r1 = gpu_reg[IMM_1];
331 //      gpu_reg[IMM_2] = READWORD(r1);
332         gpu_reg[IMM_2] = gpu_word_read(r1);
333 }
334
335 void loadp_rn_rn(void)  /* GPU only */
336 {
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);
343 }
344
345 void mirror_rn(void)    /* DSP only */
346 {
347 /*      int dreg = IMM_2;
348         UINT32 r1 = gpu_reg[dreg];
349         UINT32 res = (mirror_table[r1 & 0xffff] << 16) | mirror_table[r1 >> 16];
350         gpu_reg[dreg] = res;
351         CLR_ZN; SET_ZN(res);*/
352 }
353
354 void mmult_rn_rn(void)
355 {
356         int count = gpu_matrix_control & 15, i;
357         int sreg = IMM_1;
358         int dreg = IMM_2;
359         UINT32 addr = gpu_pointer_to_matrix;
360         INT64 accum = 0;
361         UINT32 res;
362
363         if (!(gpu_matrix_control & 0x10))
364         {
365                 for (i = 0; i < count; i++)
366                 {
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);
369                         addr += 2;
370                 }
371         }
372         else
373         {
374                 for (i = 0; i < count; i++)
375                 {
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);
378                         addr += 2 * count;
379                 }
380         }
381         gpu_reg[dreg] = res = (UINT32)accum;
382         CLR_ZN; SET_ZN(res);
383 }
384
385 void move_rn_rn(void)
386 {
387         gpu_reg[IMM_2] = gpu_reg[IMM_1];
388 }
389
390 void move_pc_rn(void)
391 {
392 //      gpu_reg[IMM_2] = jaguar.ppc;
393         gpu_reg[IMM_2] = gpu_pc - 2;
394 }
395
396 void movefa_rn_rn(void)
397 {
398         gpu_reg[IMM_2] = gpu_alternate_reg[IMM_1];
399 }
400
401 void movei_n_rn(void)
402 {
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);
405         gpu_pc += 4;
406         gpu_reg[IMM_2] = res;
407 }
408
409 void moveq_n_rn(void)
410 {
411         gpu_reg[IMM_2] = IMM_1;
412 }
413
414 void moveta_rn_rn(void)
415 {
416         gpu_alternate_reg[IMM_2] = gpu_reg[IMM_1];
417 }
418
419 void mtoi_rn_rn(void)
420 {
421         UINT32 r1 = gpu_reg[IMM_1];
422         gpu_reg[IMM_2] = (((INT32)r1 >> 8) & 0xff800000) | (r1 & 0x007fffff);
423 }
424
425 void mult_rn_rn(void)
426 {
427         int dreg = IMM_2;
428         UINT32 r1 = gpu_reg[IMM_1];
429         UINT32 r2 = gpu_reg[dreg];
430         UINT32 res = (UINT16)r1 * (UINT16)r2;
431         gpu_reg[dreg] = res;
432         CLR_ZN; SET_ZN(res);
433 }
434
435 void neg_rn(void)
436 {
437         int dreg = IMM_2;
438         UINT32 r2 = gpu_reg[dreg];
439         UINT32 res = -r2;
440         gpu_reg[dreg] = res;
441         CLR_ZNC; SET_ZNC_SUB(0,r2,res);
442 }
443
444 void nop(void)
445 {
446 }
447
448 void normi_rn_rn(void)
449 {
450         UINT32 r1 = gpu_reg[IMM_1];
451         UINT32 res = 0;
452         while ((r1 & 0xffc00000) == 0)
453         {
454                 r1 <<= 1;
455                 res--;
456         }
457         while ((r1 & 0xff800000) != 0)
458         {
459                 r1 >>= 1;
460                 res++;
461         }
462         gpu_reg[IMM_2] = res;
463         CLR_ZN; SET_ZN(res);
464 }
465
466 void not_rn(void)
467 {
468         int dreg = IMM_2;
469         UINT32 res = ~gpu_reg[dreg];
470         gpu_reg[dreg] = res;
471         CLR_ZN; SET_ZN(res);
472 }
473
474 void or_rn_rn(void)
475 {
476         int dreg = IMM_2;
477         UINT32 r1 = gpu_reg[IMM_1];
478         UINT32 r2 = gpu_reg[dreg];
479         UINT32 res = r1 | r2;
480         gpu_reg[dreg] = res;
481         CLR_ZN; SET_ZN(res);
482 }
483
484 void pack_rn(void)              /* GPU only */
485 {
486         int dreg = IMM_2;
487         UINT32 r1 = gpu_reg[IMM_1];
488         UINT32 r2 = gpu_reg[dreg];
489         UINT32 res;
490         if (r1 == 0)    /* PACK */
491                 res = ((r2 >> 10) & 0xf000) | ((r2 >> 5) & 0x0f00) | (r2 & 0xff);
492         else                    /* UNPACK */
493                 res = ((r2 & 0xf000) << 10) | ((r2 & 0x0f00) << 5) | (r2 & 0xff);
494         gpu_reg[dreg] = res;
495         CLR_ZN; SET_ZN(res);
496 }
497
498 void resmac_rn(void)
499 {
500         gpu_reg[IMM_2] = (UINT32)gpu_acc;
501 }
502
503 void ror_rn_rn(void)
504 {
505         int dreg = IMM_2;
506         UINT32 r1 = gpu_reg[IMM_1] & 31;
507         UINT32 r2 = gpu_reg[dreg];
508         UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
509         gpu_reg[dreg] = res;
510         CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01;
511 }
512
513 void rorq_n_rn(void)
514 {
515         int dreg = IMM_2;
516         UINT32 r1 = convert_zero[IMM_1];
517         UINT32 r2 = gpu_reg[dreg];
518         UINT32 res = (r2 >> r1) | (r2 << (32 - r1));
519         gpu_reg[dreg] = res;
520         CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01;
521 }
522
523 void sat8_rn(void)              /* GPU only */
524 {
525         int dreg = IMM_2;
526         INT32 r2 = gpu_reg[dreg];
527         UINT32 res = (r2 < 0) ? 0 : (r2 > 255) ? 255 : r2;
528         gpu_reg[dreg] = res;
529         CLR_ZN; SET_ZN(res);
530 }
531
532 void sat16_rn(void)             /* GPU only */
533 {
534         int dreg = IMM_2;
535         INT32 r2 = gpu_reg[dreg];
536         UINT32 res = (r2 < 0) ? 0 : (r2 > 65535) ? 65535 : r2;
537         gpu_reg[dreg] = res;
538         CLR_ZN; SET_ZN(res);
539 }
540
541 void sat16s_rn(void)            /* DSP only */
542 {
543 /*      int dreg = IMM_2;
544         INT32 r2 = gpu_reg[dreg];
545         UINT32 res = (r2 < -32768) ? -32768 : (r2 > 32767) ? 32767 : r2;
546         gpu_reg[dreg] = res;
547         CLR_ZN; SET_ZN(res);*/
548 }
549
550 void sat24_rn(void)                     /* GPU only */
551 {
552         int dreg = IMM_2;
553         INT32 r2 = gpu_reg[dreg];
554         UINT32 res = (r2 < 0) ? 0 : (r2 > 16777215) ? 16777215 : r2;
555         gpu_reg[dreg] = res;
556         CLR_ZN; SET_ZN(res);
557 }
558
559 void sat32s_rn(void)            /* DSP only */
560 {
561 /*      int dreg = IMM_2;
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;
565         gpu_reg[dreg] = res;
566         CLR_ZN; SET_ZN(res);*/
567 }
568
569 void sh_rn_rn(void)
570 {
571         int dreg = IMM_2;
572         INT32 r1 = (INT32)gpu_reg[IMM_1];
573         UINT32 r2 = gpu_reg[dreg];
574         UINT32 res;
575
576         CLR_ZNC;
577         if (r1 < 0)
578         {
579                 res = (r1 <= -32) ? 0 : (r2 << -r1);
580                 gpu_flag_c = (r2 >> 31) & 0x01;
581         }
582         else
583         {
584                 res = (r1 >= 32) ? 0 : (r2 >> r1);
585                 gpu_flag_c = r2 & 0x01;
586         }
587         gpu_reg[dreg] = res;
588         SET_ZN(res);
589 }
590
591 void sha_rn_rn(void)
592 {
593         int dreg = IMM_2;
594         INT32 r1 = (INT32)gpu_reg[IMM_1];
595         UINT32 r2 = gpu_reg[dreg];
596         UINT32 res;
597
598         CLR_ZNC;
599         if (r1 < 0)
600         {
601                 res = (r1 <= -32) ? 0 : (r2 << -r1);
602                 gpu_flag_c = (r2 >> 31) & 0x01;
603         }
604         else
605         {
606                 res = (r1 >= 32) ? ((INT32)r2 >> 31) : ((INT32)r2 >> r1);
607 //              jaguar.FLAGS |= (r2 << 1) & 2;
608                 gpu_flag_c = r2 & 0x01;
609         }
610         gpu_reg[dreg] = res;
611         SET_ZN(res);
612 }
613
614 void sharq_n_rn(void)
615 {
616         int dreg = IMM_2;
617         INT32 r1 = convert_zero[IMM_1];
618         UINT32 r2 = gpu_reg[dreg];
619         UINT32 res = (INT32)r2 >> r1;
620         gpu_reg[dreg] = res;
621 //      CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2;
622         CLR_ZNC; SET_ZN(res); gpu_flag_c = r2 & 0x01;
623 }
624
625 void shlq_n_rn(void)
626 {
627         int dreg = IMM_2;
628         INT32 r1 = convert_zero[IMM_1];
629         UINT32 r2 = gpu_reg[dreg];
630         UINT32 res = r2 << (32 - r1);
631         gpu_reg[dreg] = res;
632         CLR_ZNC; SET_ZN(res); gpu_flag_c = (r2 >> 31) & 0x01;
633 }
634
635 void shrq_n_rn(void)
636 {
637         int dreg = IMM_2;
638         INT32 r1 = convert_zero[IMM_1];
639         UINT32 r2 = gpu_reg[dreg];
640         UINT32 res = r2 >> r1;
641         gpu_reg[dreg] = res;
642 //      CLR_ZNC; SET_ZN(res); jaguar.FLAGS |= (r2 << 1) & 2;
643         CLR_ZNC; SET_ZN(res); gpu_flag_c = r2 & 0x01;
644 }
645
646 void store_rn_rn(void)
647 {
648         UINT32 r1 = gpu_reg[IMM_1];
649 //      WRITELONG(r1, gpu_reg[IMM_2]);
650         gpu_long_write(r1, gpu_reg[IMM_2]);
651 }
652
653 void store_rn_r14n(void)
654 {
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]);
658 }
659
660 void store_rn_r15n(void)
661 {
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]);
665 }
666
667 void store_rn_r14rn(void)
668 {
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]);
672 }
673
674 void store_rn_r15rn(void)
675 {
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]);
679 }
680
681 void storeb_rn_rn(void)
682 {
683         UINT32 r1 = gpu_reg[IMM_1];
684 //      WRITEBYTE(r1, gpu_reg[IMM_2]);
685         gpu_byte_write(r1, gpu_reg[IMM_2]);
686 }
687
688 void storew_rn_rn(void)
689 {
690         UINT32 r1 = gpu_reg[IMM_1];
691 //      WRITEWORD(r1, gpu_reg[IMM_2]);
692         gpu_word_write(r1, gpu_reg[IMM_2]);
693 }
694
695 void storep_rn_rn(void) /* GPU only */
696 {
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]);
702 }
703
704 void sub_rn_rn(void)
705 {
706         int dreg = IMM_2;
707         UINT32 r1 = gpu_reg[IMM_1];
708         UINT32 r2 = gpu_reg[dreg];
709         UINT32 res = r2 - r1;
710         gpu_reg[dreg] = res;
711         CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
712 }
713
714 void subc_rn_rn(void)
715 {
716         int dreg = IMM_2;
717         UINT32 r1 = gpu_reg[IMM_1];
718         UINT32 r2 = gpu_reg[dreg];
719         UINT32 res = r2 - r1 - (gpu_flag_c);
720         gpu_reg[dreg] = res;
721         CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
722 }
723
724 void subq_n_rn(void)
725 {
726         int dreg = IMM_2;
727         UINT32 r1 = convert_zero[IMM_1];
728         UINT32 r2 = gpu_reg[dreg];
729         UINT32 res = r2 - r1;
730         gpu_reg[dreg] = res;
731         CLR_ZNC; SET_ZNC_SUB(r2,r1,res);
732 }
733
734 void subqmod_n_rn(void) /* DSP only */
735 {
736 /*      int dreg = IMM_2;
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]);
741         gpu_reg[dreg] = res;
742         CLR_ZNC; SET_ZNC_SUB(r2,r1,res);*/
743 }
744
745 void subqt_n_rn(void)
746 {
747         int dreg = IMM_2;
748         UINT32 r1 = convert_zero[IMM_1];
749         UINT32 r2 = gpu_reg[dreg];
750         UINT32 res = r2 - r1;
751         gpu_reg[dreg] = res;
752 }
753
754 void xor_rn_rn(void)
755 {
756         int dreg = IMM_2;
757         UINT32 r1 = gpu_reg[IMM_1];
758         UINT32 r2 = gpu_reg[dreg];
759         UINT32 res = r1 ^ r2;
760         gpu_reg[dreg] = res;
761         CLR_ZN; SET_ZN(res);
762 }