3 // Simulator definition for the MIPS DSP ASE.
4 // Copyright (C) 2005 Free Software Foundation, Inc.
5 // Contributed by MIPS Technologies, Inc. Written by Chao-ying Fu.
7 // This file is part of GDB, the GNU debugger.
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2, or (at your option)
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License along
20 // with this program; if not, write to the Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 // op: 0 = ADD, 1 = SUB
25 // sat: 0 = no saturation, 1 = saturation
26 :function:::void:do_ph_op:int rd, int rs, int rt, int op, int sat
31 unsigned32 v1 = GPR[rs];
32 unsigned32 v2 = GPR[rt];
33 unsigned32 result = 0;
34 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
36 h1 = (signed16)(v1 & 0xffff);
37 h2 = (signed16)(v2 & 0xffff);
39 h0 = (signed32)h1 + (signed32)h2;
41 h0 = (signed32)h1 - (signed32)h2;
42 if (((h0 & 0x10000) >> 1) != (h0 & 0x8000))
44 DSPCR |= DSPCR_OUFLAG4;
53 result |= ((unsigned32)((unsigned16)h0) << i);
55 GPR[rd] = EXTEND32 (result);
58 // op: 0 = ADD, 1 = SUB
59 :function:::void:do_w_op:int rd, int rs, int rt, int op
63 unsigned32 v1 = GPR[rs];
64 unsigned32 v2 = GPR[rt];
65 unsigned32 result = 0;
69 h0 = (signed64)h1 + (signed64)h2;
71 h0 = (signed64)h1 - (signed64)h2;
72 if (((h0 & 0x100000000) >> 1) != (h0 & 0x80000000))
74 DSPCR |= DSPCR_OUFLAG4;
80 GPR[rd] = EXTEND32 (h0);
83 // op: 0 = ADD, 1 = SUB
84 // sat: 0 = no saturation, 1 = saturation
85 :function:::void:do_qb_op:int rd, int rs, int rt, int op, int sat
90 unsigned32 v1 = GPR[rs];
91 unsigned32 v2 = GPR[rt];
92 unsigned32 result = 0;
93 for (i = 0; i < 32; i += 8, v1 >>= 8, v2 >>= 8)
95 h1 = (unsigned8)(v1 & 0xff);
96 h2 = (unsigned8)(v2 & 0xff);
98 h0 = (unsigned32)h1 + (unsigned32)h2;
100 h0 = (unsigned32)h1 - (unsigned32)h2;
103 DSPCR |= DSPCR_OUFLAG4;
112 result |= ((unsigned32)((unsigned8)h0) << i);
114 GPR[rd] = EXTEND32 (result);
117 // op: 0 = left, 1 = right
118 :function:::void:do_qb_shift:int rd, int rt, int shift, int op
122 unsigned32 v1 = GPR[rt];
123 unsigned32 result = 0;
124 for (i = 0; i < 32; i += 8, v1 >>= 8)
126 h0 = (unsigned8)(v1 & 0xff);
129 for (j = 7; j >= 8 - shift; j--)
133 DSPCR |= DSPCR_OUFLAG6;
141 result |= ((unsigned32)h0 << i);
143 GPR[rd] = EXTEND32 (result);
146 // op: 0 = left, 1 = right
147 // sat: 0 = no saturation/rounding, 1 = saturation/rounding
148 :function:::void:do_ph_shift:int rd, int rt, int shift, int op, int sat
152 unsigned32 v1 = GPR[rt];
153 unsigned32 result = 0;
155 for (i = 0; i < 32; i += 16, v1 >>= 16)
157 h0 = (signed16)(v1 & 0xffff);
163 for (j = 14; j >= 15 - shift; j--)
165 if (!(h0 & (1 << j)))
167 DSPCR |= DSPCR_OUFLAG6;
175 for (j = 14; j >= 15 - shift; j--)
179 DSPCR |= DSPCR_OUFLAG6;
190 else if (setcond == 1)
196 if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1))))
197 h0 = (h0 >> shift) + 1;
202 result |= ((unsigned32)((unsigned16)h0) << i);
204 GPR[rd] = EXTEND32 (result);
207 :function:::void:do_w_shll:int rd, int rt, int shift
210 unsigned32 v1 = GPR[rt];
211 unsigned32 result = 0;
215 for (i = 30; i >= 31 - shift; i--)
217 if (!(v1 & (1 << i)))
219 DSPCR |= DSPCR_OUFLAG6;
227 for (i = 30; i >= 31 - shift; i--)
231 DSPCR |= DSPCR_OUFLAG6;
239 else if (setcond == 1)
242 result = v1 << shift;
243 GPR[rd] = EXTEND32 (result);
246 :function:::void:do_w_shra:int rd, int rt, int shift
248 unsigned32 result = GPR[rt];
249 signed32 h0 = (signed32)result;
250 if (shift != 0 && (h0 & (1 << (shift-1))))
251 h0 = (h0 >> shift) + 1;
254 GPR[rd] = EXTEND32 (h0);
257 011111,5.RS,5.RT,5.RD,01010,010000:SPECIAL3:32::ADDQ.PH
258 "addq.ph r<RD>, r<RS>, r<RT>"
261 do_ph_op (SD_, RD, RS, RT, 0, 0);
264 011111,5.RS,5.RT,5.RD,01110,010000:SPECIAL3:32::ADDQ_S.PH
265 "addq_s.ph r<RD>, r<RS>, r<RT>"
268 do_ph_op (SD_, RD, RS, RT, 0, 1);
271 011111,5.RS,5.RT,5.RD,10110,010000:SPECIAL3:32::ADDQ_S.W
272 "addq_s.w r<RD>, r<RS>, r<RT>"
275 do_w_op (SD_, RD, RS, RT, 0);
278 011111,5.RS,5.RT,5.RD,00000,010000:SPECIAL3:32::ADDU.QB
279 "addu.qb r<RD>, r<RS>, r<RT>"
282 do_qb_op (SD_, RD, RS, RT, 0, 0);
285 011111,5.RS,5.RT,5.RD,00100,010000:SPECIAL3:32::ADDU_S.QB
286 "addu_s.qb r<RD>, r<RS>, r<RT>"
289 do_qb_op (SD_, RD, RS, RT, 0, 1);
292 011111,5.RS,5.RT,5.RD,01011,010000:SPECIAL3:32::SUBQ.PH
293 "subq.ph r<RD>, r<RS>, r<RT>"
296 do_ph_op (SD_, RD, RS, RT, 1, 0);
299 011111,5.RS,5.RT,5.RD,01111,010000:SPECIAL3:32::SUBQ_S.PH
300 "subq_s.ph r<RD>, r<RS>, r<RT>"
303 do_ph_op (SD_, RD, RS, RT, 1, 1);
306 011111,5.RS,5.RT,5.RD,10111,010000:SPECIAL3:32::SUBQ_S.W
307 "subq_s.w r<RD>, r<RS>, r<RT>"
310 do_w_op (SD_, RD, RS, RT, 1);
313 011111,5.RS,5.RT,5.RD,00001,010000:SPECIAL3:32::SUBU.QB
314 "subu.qb r<RD>, r<RS>, r<RT>"
317 do_qb_op (SD_, RD, RS, RT, 1, 0);
320 011111,5.RS,5.RT,5.RD,00101,010000:SPECIAL3:32::SUBU_S.QB
321 "subu_s.qb r<RD>, r<RS>, r<RT>"
324 do_qb_op (SD_, RD, RS, RT, 1, 1);
327 011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC
328 "addsc r<RD>, r<RS>, r<RT>"
331 unsigned32 v1 = GPR[RS];
332 unsigned32 v2 = GPR[RT];
334 h0 = (unsigned64)v1 + (unsigned64)v2;
335 if (h0 & 0x100000000LL)
336 DSPCR |= DSPCR_CARRY;
337 GPR[RD] = EXTEND32 (h0);
340 011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC
341 "addwc r<RD>, r<RS>, r<RT>"
344 unsigned32 v1 = GPR[RS];
345 unsigned32 v2 = GPR[RT];
347 signed32 h1 = (signed32) v1;
348 signed32 h2 = (signed32) v2;
349 h0 = (signed64)h1 + (signed64)h2
350 + (signed64)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK);
351 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
352 DSPCR |= DSPCR_OUFLAG4;
353 GPR[RD] = EXTEND32 (h0);
356 011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB
357 "modsub r<RD>, r<RS>, r<RT>"
360 unsigned32 result = 0;
361 unsigned32 v1 = GPR[RS];
362 unsigned32 v2 = GPR[RT];
363 unsigned32 decr = v2 & 0xff;
364 unsigned32 lastindex = (v2 & 0xffff00) >> 8;
369 GPR[RD] = EXTEND32 (result);
372 011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB
373 "raddu.w.qb r<RD>, r<RS>"
378 unsigned32 v1 = GPR[RS];
379 unsigned32 result = 0;
380 for (i = 0; i < 32; i += 8, v1 >>= 8)
382 h0 = (unsigned8)(v1 & 0xff);
383 result += (unsigned32)h0;
385 GPR[RD] = EXTEND32 (result);
388 011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH
389 "absq_s.ph r<RD>, r<RT>"
394 unsigned32 v1 = GPR[RT];
395 unsigned32 result = 0;
396 for (i = 0; i < 32; i += 16, v1 >>= 16)
398 h0 = (signed16)(v1 & 0xffff);
399 if (h0 == (signed16)0x8000)
401 DSPCR |= DSPCR_OUFLAG4;
404 else if (h0 & 0x8000)
406 result |= ((unsigned32)((unsigned16)h0) << i);
408 GPR[RD] = EXTEND32 (result);
411 011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W
412 "absq_s.w r<RD>, r<RT>"
415 unsigned32 v1 = GPR[RT];
416 signed32 h0 = (signed32)v1;
417 if (h0 == (signed32)0x80000000)
419 DSPCR |= DSPCR_OUFLAG4;
422 else if (h0 & 0x80000000)
424 GPR[RD] = EXTEND32 (h0);
427 011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH
428 "precrq.qb.ph r<RD>, r<RS>, r<RT>"
431 unsigned32 v1 = GPR[RS];
432 unsigned32 v2 = GPR[RT];
433 unsigned32 tempu = (v1 & 0xff000000) >> 24;
434 unsigned32 tempv = (v1 & 0xff00) >> 8;
435 unsigned32 tempw = (v2 & 0xff000000) >> 24;
436 unsigned32 tempx = (v2 & 0xff00) >> 8;
437 GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
440 011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W
441 "precrq.ph.w r<RD>, r<RS>, r<RT>"
444 unsigned32 v1 = GPR[RS];
445 unsigned32 v2 = GPR[RT];
446 unsigned32 tempu = (v1 & 0xffff0000) >> 16;
447 unsigned32 tempv = (v2 & 0xffff0000) >> 16;
448 GPR[RD] = EXTEND32 ((tempu << 16) | tempv);
451 011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W
452 "precrq_rs.ph.w r<RD>, r<RS>, r<RT>"
455 unsigned32 v1 = GPR[RS];
456 unsigned32 v2 = GPR[RT];
457 signed32 h1 = (signed32)v1;
458 signed32 h2 = (signed32)v2;
459 signed64 temp1 = (signed64)h1 + (signed64)0x8000;
461 signed64 temp3 = (signed64)h2 + (signed64)0x8000;
463 if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000))
465 DSPCR |= DSPCR_OUFLAG6;
469 temp2 = (signed32)((temp1 & 0xffff0000) >> 16);
470 if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000))
472 DSPCR |= DSPCR_OUFLAG6;
476 temp4 = (signed32)((temp3 & 0xffff0000) >> 16);
477 GPR[RD] = EXTEND32 ((temp2 << 16) | temp4);
480 011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH
481 "precrqu_s.qb.ph r<RD>, r<RS>, r<RT>"
484 unsigned32 v1 = GPR[RS];
485 unsigned32 v2 = GPR[RT];
486 unsigned32 tempu, tempv, tempw, tempx;
489 DSPCR |= DSPCR_OUFLAG6;
492 else if (!(v1 & 0x80000000) && ((v1 >> 16) > (unsigned32)0x7f80))
494 DSPCR |= DSPCR_OUFLAG6;
498 tempu = (v1 & 0x7f800000) >> 23;
501 DSPCR |= DSPCR_OUFLAG6;
504 else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (unsigned32)0x7f80))
506 DSPCR |= DSPCR_OUFLAG6;
510 tempv = (v1 & 0x7f80) >> 7;
513 DSPCR |= DSPCR_OUFLAG6;
516 else if (!(v2 & 0x80000000) && ((v2 >> 16) > (unsigned32)0x7f80))
518 DSPCR |= DSPCR_OUFLAG6;
522 tempw = (v2 & 0x7f800000) >> 23;
525 DSPCR |= DSPCR_OUFLAG6;
528 else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (unsigned32)0x7f80))
530 DSPCR |= DSPCR_OUFLAG6;
534 tempx = (v2 & 0x7f80) >> 7;
535 GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
538 011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL
539 "preceq.w.phl r<RD>, r<RT>"
542 unsigned32 v1 = GPR[RT];
543 GPR[RD] = EXTEND32 (v1 & 0xffff0000);
546 011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR
547 "preceq.w.phr r<RD>, r<RT>"
550 unsigned32 v1 = GPR[RT];
551 GPR[RD] = EXTEND32 ((v1 & 0xffff) << 16);
554 011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL
555 "precequ.ph.qbl r<RD>, r<RT>"
558 unsigned32 v1 = GPR[RT];
559 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9);
562 011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR
563 "precequ.ph.qbr r<RD>, r<RT>"
566 unsigned32 v1 = GPR[RT];
567 GPR[RD] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7);
570 011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA
571 "precequ.ph.qbla r<RD>, r<RT>"
574 unsigned32 v1 = GPR[RT];
575 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1);
578 011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA
579 "precequ.ph.qbra r<RD>, r<RT>"
582 unsigned32 v1 = GPR[RT];
583 GPR[RD] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7);
586 011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL
587 "preceu.ph.qbl r<RD>, r<RT>"
590 unsigned32 v1 = GPR[RT];
591 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16);
594 011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR
595 "preceu.ph.qbr r<RD>, r<RT>"
598 unsigned32 v1 = GPR[RT];
599 GPR[RD] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff);
602 011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA
603 "preceu.ph.qbla r<RD>, r<RT>"
606 unsigned32 v1 = GPR[RT];
607 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8);
610 011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA
611 "preceu.ph.qbra r<RD>, r<RT>"
614 unsigned32 v1 = GPR[RT];
615 GPR[RD] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff));
618 011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB
619 "shll.qb r<RD>, r<RT>, <SHIFT3>"
622 do_qb_shift (SD_, RD, RT, SHIFT3, 0);
625 011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB
626 "shllv.qb r<RD>, r<RT>, r<RS>"
629 unsigned32 shift = GPR[RS] & 0x7;
630 do_qb_shift (SD_, RD, RT, shift, 0);
633 011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH
634 "shll.ph r<RD>, r<RT>, <SHIFT4>"
637 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0);
640 011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH
641 "shllv.ph r<RD>, r<RT>, r<RS>"
644 unsigned32 shift = GPR[RS] & 0xf;
645 do_ph_shift (SD_, RD, RT, shift, 0, 0);
648 011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH
649 "shll_s.ph r<RD>, r<RT>, <SHIFT4>"
652 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1);
655 011111,5.RS,5.RT,5.RD,01110,010011:SPECIAL3:32::SHLLV_S.PH
656 "shllv_s.ph r<RD>, r<RT>, r<RS>"
659 unsigned32 shift = GPR[RS] & 0xf;
660 do_ph_shift (SD_, RD, RT, shift, 0, 1);
663 011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W
664 "shll_s.w r<RD>, r<RT>, <SHIFT5>"
667 do_w_shll (SD_, RD, RT, SHIFT5);
670 011111,5.RS,5.RT,5.RD,10110,010011:SPECIAL3:32::SHLLV_S.W
671 "shllv_s.w r<RD>, r<RT>, r<RS>"
674 unsigned32 shift = GPR[RS] & 0x1f;
675 do_w_shll (SD_, RD, RT, shift);
678 011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB
679 "shrl.qb r<RD>, r<RT>, <SHIFT3>"
682 do_qb_shift (SD_, RD, RT, SHIFT3, 1);
685 011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB
686 "shrlv.qb r<RD>, r<RT>, r<RS>"
689 unsigned32 shift = GPR[RS] & 0x7;
690 do_qb_shift (SD_, RD, RT, shift, 1);
693 011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH
694 "shra.ph r<RD>, r<RT>, <SHIFT4>"
697 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0);
700 011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH
701 "shrav.ph r<RD>, r<RT>, r<RS>"
704 unsigned32 shift = GPR[RS] & 0xf;
705 do_ph_shift (SD_, RD, RT, shift, 1, 0);
708 011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH
709 "shra_r.ph r<RD>, r<RT>, <SHIFT4>"
712 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1);
715 011111,5.RS,5.RT,5.RD,01111,010011:SPECIAL3:32::SHRAV_R.PH
716 "shrav_r.ph r<RD>, r<RT>, r<RS>"
719 unsigned32 shift = GPR[RS] & 0xf;
720 do_ph_shift (SD_, RD, RT, shift, 1, 1);
723 011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W
724 "shra_r.w r<RD>, r<RT>, <SHIFT5>"
727 do_w_shra (SD_, RD, RT, SHIFT5);
730 011111,5.RS,5.RT,5.RD,10111,010011:SPECIAL3:32::SHRAV_R.W
731 "shrav_r.w r<RD>, r<RT>, r<RS>"
734 unsigned32 shift = GPR[RS] & 0x1f;
735 do_w_shra (SD_, RD, RT, shift);
738 // loc: 0 = qhl, 1 = qhr
739 :function:::void:do_qb_muleu:int rd, int rs, int rt, int loc
742 unsigned32 result = 0;
743 unsigned32 v1 = GPR[rs];
744 unsigned32 v2 = GPR[rt];
749 for (i = 0; i < 32; i += 16, v1 >>= 8, v2 >>= 16)
751 h1 = (unsigned16)(v1 & 0xff);
752 h2 = (unsigned16)(v2 & 0xffff);
753 prod = (unsigned32)h1 * (unsigned32)h2;
756 DSPCR |= DSPCR_OUFLAG5;
759 result |= ((unsigned32)prod << i);
761 GPR[rd] = EXTEND32 (result);
764 011111,5.RS,5.RT,5.RD,00110,010000:SPECIAL3:32::MULEU_S.PH.QBL
765 "muleu_s.ph.qbl r<RD>, r<RS>, r<RT>"
768 do_qb_muleu (SD_, RD, RS, RT, 0);
771 011111,5.RS,5.RT,5.RD,00111,010000:SPECIAL3:32::MULEU_S.PH.QBR
772 "muleu_s.ph.qbr r<RD>, r<RS>, r<RT>"
775 do_qb_muleu (SD_, RD, RS, RT, 1);
778 011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH
779 "mulq_rs.ph r<RD>, r<RS>, r<RT>"
783 unsigned32 result = 0;
784 unsigned32 v1 = GPR[RS];
785 unsigned32 v2 = GPR[RT];
788 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
790 h1 = (signed16)(v1 & 0xffff);
791 h2 = (signed16)(v2 & 0xffff);
792 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
794 DSPCR |= DSPCR_OUFLAG5;
798 prod = (((signed32)h1 * (signed32)h2) << 1) + (signed32)0x8000;
800 result |= (((unsigned32)prod >> 16) << i);
802 GPR[RD] = EXTEND32 (result);
805 // loc: 0 = phl, 1 = phr
806 :function:::void:do_ph_muleq:int rd, int rs, int rt, int loc
808 unsigned32 v1 = GPR[rs];
809 unsigned32 v2 = GPR[rt];
814 h1 = (signed16)(v1 >> 16);
815 h2 = (signed16)(v2 >> 16);
819 h1 = (signed16)(v1 & 0xffff);
820 h2 = (signed16)(v2 & 0xffff);
822 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
824 DSPCR |= DSPCR_OUFLAG5;
828 prod = ((signed32)h1 * (signed32)h2) << 1;
829 GPR[rd] = EXTEND32 (prod);
832 011111,5.RS,5.RT,5.RD,11100,010000:SPECIAL3:32::MULEQ_S.W.PHL
833 "muleq_s.w.phl r<RD>, r<RS>, r<RT>"
836 do_ph_muleq (SD_, RD, RS, RT, 0);
839 011111,5.RS,5.RT,5.RD,11101,010000:SPECIAL3:32::MULEQ_S.W.PHR
840 "muleq_s.w.phr r<RD>, r<RS>, r<RT>"
843 do_ph_muleq (SD_, RD, RS, RT, 1);
846 // op: 0 = DPAU 1 = DPSU
847 // loc: 0 = qbl, 1 = qbr
848 :function:::void:do_qb_dot_product:int ac, int rs, int rt, int op, int loc
851 unsigned32 v1 = GPR[rs];
852 unsigned32 v2 = GPR[rt];
854 unsigned32 lo = DSPLO(ac);
855 unsigned32 hi = DSPHI(ac);
856 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
862 for (i = 0; i < 16; i += 8, v1 >>= 8, v2 >>= 8)
864 h1 = (unsigned8)(v1 & 0xff);
865 h2 = (unsigned8)(v2 & 0xff);
867 prod += (unsigned64)h1 * (unsigned64)h2;
869 prod -= (unsigned64)h1 * (unsigned64)h2;
871 DSPLO(ac) = EXTEND32 (prod);
872 DSPHI(ac) = EXTEND32 (prod >> 32);
875 011111,5.RS,5.RT,000,2.AC,00011,110000:SPECIAL3:32::DPAU.H.QBL
876 "dpau.h.qbl ac<AC>, r<RS>, r<RT>"
879 do_qb_dot_product (SD_, AC, RS, RT, 0, 0);
882 011111,5.RS,5.RT,000,2.AC,00111,110000:SPECIAL3:32::DPAU.H.QBR
883 "dpau.h.qbr ac<AC>, r<RS>, r<RT>"
886 do_qb_dot_product (SD_, AC, RS, RT, 0, 1);
889 011111,5.RS,5.RT,000,2.AC,01011,110000:SPECIAL3:32::DPSU.H.QBL
890 "dpsu.h.qbl ac<AC>, r<RS>, r<RT>"
893 do_qb_dot_product (SD_, AC, RS, RT, 1, 0);
896 011111,5.RS,5.RT,000,2.AC,01111,110000:SPECIAL3:32::DPSU.H.QBR
897 "dpsu.h.qbr ac<AC>, r<RS>, r<RT>"
900 do_qb_dot_product (SD_, AC, RS, RT, 1, 1);
903 // op: 0 = DPAQ 1 = DPSQ
904 :function:::void:do_ph_dot_product:int ac, int rs, int rt, int op
907 unsigned32 v1 = GPR[rs];
908 unsigned32 v2 = GPR[rt];
911 unsigned32 lo = DSPLO(ac);
912 unsigned32 hi = DSPHI(ac);
913 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
914 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
916 h1 = (signed16)(v1 & 0xffff);
917 h2 = (signed16)(v2 & 0xffff);
918 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
920 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
921 result = (signed32)0x7fffffff;
924 result = ((signed32)h1 * (signed32)h2) << 1;
927 prod += (signed64)result;
929 prod -= (signed64)result;
931 DSPLO(ac) = EXTEND32 (prod);
932 DSPHI(ac) = EXTEND32 (prod >> 32);
935 011111,5.RS,5.RT,000,2.AC,00100,110000:SPECIAL3:32::DPAQ_S.W.PH
936 "dpaq_s.w.ph ac<AC>, r<RS>, r<RT>"
939 do_ph_dot_product (SD_, AC, RS, RT, 0);
942 011111,5.RS,5.RT,000,2.AC,00101,110000:SPECIAL3:32::DPSQ_S.W.PH
943 "dpsq_s.w.ph ac<AC>, r<RS>, r<RT>"
946 do_ph_dot_product (SD_, AC, RS, RT, 1);
949 011111,5.RS,5.RT,000,2.AC,00110,110000:SPECIAL3:32::MULSAQ_S.W.PH
950 "mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>"
954 unsigned32 v1 = GPR[RS];
955 unsigned32 v2 = GPR[RT];
958 unsigned32 lo = DSPLO(AC);
959 unsigned32 hi = DSPHI(AC);
960 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
961 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
963 h1 = (signed16)(v1 & 0xffff);
964 h2 = (signed16)(v2 & 0xffff);
965 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
967 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + AC));
968 result = (signed32) 0x7fffffff;
971 result = ((signed32)h1 * (signed32)h2) << 1;
974 prod -= (signed64) result;
976 prod += (signed64) result;
978 DSPLO(AC) = EXTEND32 (prod);
979 DSPHI(AC) = EXTEND32 (prod >> 32);
982 // op: 0 = DPAQ 1 = DPSQ
983 :function:::void:do_w_dot_product:int ac, int rs, int rt, int op
985 unsigned32 v1 = GPR[rs];
986 unsigned32 v2 = GPR[rt];
989 unsigned32 lo = DSPLO(ac);
990 unsigned32 hi = DSPHI(ac);
998 if (h1 == 0x80000000 && h2 == 0x80000000)
1000 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1001 result = (signed64) 0x7fffffffffffffffLL;
1004 result = ((signed64)h1 * (signed64)h2) << 1;
1005 resultlo = (unsigned32)(result);
1006 resulthi = (unsigned32)(result >> 32);
1009 temp1 = (unsigned64)lo + (unsigned64)resultlo;
1010 carry = (unsigned32)((temp1 >> 32) & 1);
1011 temp2 = (signed64)((signed32)hi) + (signed64)((signed32)resulthi) +
1012 (signed64)((signed32)carry);
1016 temp1 = (unsigned64)lo - (unsigned64)resultlo;
1017 carry = (unsigned32)((temp1 >> 32) & 1);
1018 temp2 = (signed64)((signed32)hi) - (signed64)((signed32)resulthi) -
1019 (signed64)((signed32)carry);
1021 if (((temp2 & 0x100000000LL) >> 1) != (temp2 & 0x80000000LL))
1023 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1024 if (temp2 & 0x100000000LL)
1026 DSPLO(ac) = EXTEND32 (0x00000000);
1027 DSPHI(ac) = EXTEND32 (0x80000000);
1031 DSPLO(ac) = EXTEND32 (0xffffffff);
1032 DSPHI(ac) = EXTEND32 (0x7fffffff);
1037 DSPLO(ac) = EXTEND32 (temp1);
1038 DSPHI(ac) = EXTEND32 (temp2);
1042 011111,5.RS,5.RT,000,2.AC,01100,110000:SPECIAL3:32::DPAQ_SA.L.W
1043 "dpaq_sa.l.w ac<AC>, r<RS>, r<RT>"
1046 do_w_dot_product (SD_, AC, RS, RT, 0);
1049 011111,5.RS,5.RT,000,2.AC,01101,110000:SPECIAL3:32::DPSQ_SA.L.W
1050 "dpsq_sa.l.w ac<AC>, r<RS>, r<RT>"
1053 do_w_dot_product (SD_, AC, RS, RT, 1);
1056 // op: 0 = MAQ_S 1 = MAQ_SA
1057 // loc: 0 = phl, 1 = phr
1058 :function:::void:do_ph_maq:int ac, int rs, int rt, int op, int loc
1061 unsigned32 v1 = GPR[rs];
1062 unsigned32 v2 = GPR[rt];
1065 unsigned32 lo = DSPLO(ac);
1066 unsigned32 hi = DSPHI(ac);
1067 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
1070 h1 = (signed16)(v1 >> 16);
1071 h2 = (signed16)(v2 >> 16);
1075 h1 = (signed16)(v1 & 0xffff);
1076 h2 = (signed16)(v2 & 0xffff);
1078 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
1080 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1081 result = (signed32)0x7fffffff;
1084 result = ((signed32)h1 * (signed32)h2) << 1;
1085 prod += (signed64)result;
1086 if (op == 1) // MAQ_SA
1088 if (prod & 0x8000000000000000LL)
1090 for (i = 62; i >= 31; i--)
1092 if (!(prod & ((signed64)1 << i)))
1094 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1095 prod = 0xffffffff80000000LL;
1102 for (i = 62; i >= 31; i--)
1104 if (prod & ((signed64)1 << i))
1106 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1113 DSPLO(ac) = EXTEND32 (prod);
1114 DSPHI(ac) = EXTEND32 (prod >> 32);
1117 011111,5.RS,5.RT,000,2.AC,10100,110000:SPECIAL3:32::MAQ_S.W.PHL
1118 "maq_s.w.phl ac<AC>, r<RS>, r<RT>"
1121 do_ph_maq (SD_, AC, RS, RT, 0, 0);
1124 011111,5.RS,5.RT,000,2.AC,10110,110000:SPECIAL3:32::MAQ_S.W.PHR
1125 "maq_s.w.phr ac<AC>, r<RS>, r<RT>"
1128 do_ph_maq (SD_, AC, RS, RT, 0, 1);
1131 011111,5.RS,5.RT,000,2.AC,10000,110000:SPECIAL3:32::MAQ_SA.W.PHL
1132 "maq_sa.w.phl ac<AC>, r<RS>, r<RT>"
1135 do_ph_maq (SD_, AC, RS, RT, 1, 0);
1138 011111,5.RS,5.RT,000,2.AC,10010,110000:SPECIAL3:32::MAQ_SA.W.PHR
1139 "maq_sa.w.phr ac<AC>, r<RS>, r<RT>"
1142 do_ph_maq (SD_, AC, RS, RT, 1, 1);
1145 011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV
1146 "bitrev r<RD>, r<RT>"
1150 unsigned32 v1 = GPR[RT];
1152 for (i = 0; i < 16; i++)
1155 h1 |= (1 << (15 - i));
1157 GPR[RD] = EXTEND32 (h1);
1160 011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV
1164 unsigned32 v1 = GPR[RS];
1165 unsigned32 v2 = GPR[RT];
1166 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1167 unsigned32 size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK;
1168 unsigned32 mask1, mask2, mask3, result;
1170 mask1 = (1 << size) - 1;
1173 mask2 = (1 << pos) - 1;
1174 if (pos + size < 32)
1175 mask3 = ~((1 << (pos + size)) - 1);
1178 result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2);
1179 GPR[RT] = EXTEND32 (result);
1182 011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB
1183 "repl.qb r<RD>, <IMM8>"
1186 GPR[RD] = EXTEND32 ((IMM8 << 24) | (IMM8 << 16) | (IMM8 << 8) | IMM8);
1189 011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB
1190 "replv.qb r<RD>, r<RT>"
1193 unsigned32 v1 = GPR[RT];
1195 GPR[RD] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1);
1198 011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH
1199 "repl.ph r<RD>, <IMM10>"
1202 signed32 v1 = IMM10;
1205 GPR[RD] = EXTEND32 ((v1 << 16) | (v1 & 0xffff));
1208 011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH
1209 "replv.ph r<RD>, r<RT>"
1212 unsigned32 v1 = GPR[RT];
1214 GPR[RD] = EXTEND32 ((v1 << 16) | v1);
1217 // op: 0 = EQ, 1 = LT, 2 = LE
1218 :function:::void:do_qb_cmpu:int rs, int rt, int op
1221 unsigned32 v1 = GPR[rs];
1222 unsigned32 v2 = GPR[rt];
1225 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1227 h1 = (unsigned8)(v1 & 0xff);
1228 h2 = (unsigned8)(v2 & 0xff);
1229 mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1232 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1233 else if (op == 1) // LT
1234 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1236 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1240 011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB
1241 "cmpu.eq.qb r<RS>, r<RT>"
1244 do_qb_cmpu (SD_, RS, RT, 0);
1247 011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB
1248 "cmpu.lt.qb r<RS>, r<RT>"
1251 do_qb_cmpu (SD_, RS, RT, 1);
1254 011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB
1255 "cmpu.le.qb r<RS>, r<RT>"
1258 do_qb_cmpu (SD_, RS, RT, 2);
1261 // op: 0 = EQ, 1 = LT, 2 = LE
1262 :function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op
1265 unsigned32 v1 = GPR[rs];
1266 unsigned32 v2 = GPR[rt];
1268 unsigned32 result = 0;
1269 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1271 h1 = (unsigned8)(v1 & 0xff);
1272 h2 = (unsigned8)(v2 & 0xff);
1274 result |= ((h1 == h2) << j);
1275 else if (op == 1) // LT
1276 result |= ((h1 < h2) << j);
1278 result |= ((h1 <= h2) << j);
1280 GPR[rd] = EXTEND32 (result);
1283 011111,5.RS,5.RT,5.RD,00100,010001:SPECIAL3:32::CMPGU.EQ.QB
1284 "cmpgu.eq.qb r<RD>, r<RS>, r<RT>"
1287 do_qb_cmpgu (SD_, RD, RS, RT, 0);
1290 011111,5.RS,5.RT,5.RD,00101,010001:SPECIAL3:32::CMPGU.LT.QB
1291 "cmpgu.lt.qb r<RD>, r<RS>, r<RT>"
1294 do_qb_cmpgu (SD_, RD, RS, RT, 1);
1297 011111,5.RS,5.RT,5.RD,00110,010001:SPECIAL3:32::CMPGU.LE.QB
1298 "cmpgu.le.qb r<RD>, r<RS>, r<RT>"
1301 do_qb_cmpgu (SD_, RD, RS, RT, 2);
1304 // op: 0 = EQ, 1 = LT, 2 = LE
1305 :function:::void:do_ph_cmpu:int rs, int rt, int op
1308 unsigned32 v1 = GPR[rs];
1309 unsigned32 v2 = GPR[rt];
1312 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1314 h1 = (signed16)(v1 & 0xffff);
1315 h2 = (signed16)(v2 & 0xffff);
1316 mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1319 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1320 else if (op == 1) // LT
1321 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1323 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1327 011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH
1328 "cmp.eq.ph r<RS>, r<RT>"
1331 do_ph_cmpu (SD_, RS, RT, 0);
1334 011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH
1335 "cmp.lt.ph r<RS>, r<RT>"
1338 do_ph_cmpu (SD_, RS, RT, 1);
1341 011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH
1342 "cmp.le.ph r<RS>, r<RT>"
1345 do_ph_cmpu (SD_, RS, RT, 2);
1348 011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB
1349 "pick.qb r<RD>, r<RS>, r<RT>"
1353 unsigned32 v1 = GPR[RS];
1354 unsigned32 v2 = GPR[RT];
1356 unsigned32 result = 0;
1357 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1359 h1 = (unsigned8)(v1 & 0xff);
1360 h2 = (unsigned8)(v2 & 0xff);
1361 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
1362 result |= (unsigned32)(h1 << i);
1364 result |= (unsigned32)(h2 << i);
1366 GPR[RD] = EXTEND32 (result);
1369 011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH
1370 "pick.ph r<RD>, r<RS>, r<RT>"
1374 unsigned32 v1 = GPR[RS];
1375 unsigned32 v2 = GPR[RT];
1377 unsigned32 result = 0;
1378 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1380 h1 = (unsigned16)(v1 & 0xffff);
1381 h2 = (unsigned16)(v2 & 0xffff);
1382 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
1383 result |= (unsigned32)(h1 << i);
1385 result |= (unsigned32)(h2 << i);
1387 GPR[RD] = EXTEND32 (result);
1390 011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH
1391 "packrl.ph r<RD>, r<RS>, r<RT>"
1394 unsigned32 v1 = GPR[RS];
1395 unsigned32 v2 = GPR[RT];
1396 GPR[RD] = EXTEND32 ((v1 << 16) + (v2 >> 16));
1399 // op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS
1400 :function:::void:do_w_extr:int rt, int ac, int shift, int op
1403 unsigned32 lo = DSPLO(ac);
1404 unsigned32 hi = DSPHI(ac);
1405 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1406 signed64 result = (signed64)prod;
1408 if (!(prod & 0x8000000000000000LL))
1410 for (i = 62; i >= (shift + 31); i--)
1412 if (prod & ((unsigned64)1 << i))
1414 DSPCR |= DSPCR_OUFLAG7;
1419 if (((prod >> (shift - 1)) & 0xffffffffLL) == 0xffffffffLL)
1421 DSPCR |= DSPCR_OUFLAG7;
1427 for (i = 62; i >= (shift + 31); i--)
1429 if (!(prod & ((unsigned64)1 << i)))
1431 DSPCR |= DSPCR_OUFLAG7;
1437 if (op == 0) // EXTR
1438 result = result >> shift;
1439 else if (op == 1) // EXTR_R
1442 result = ((result >> (shift - 1)) + 1) >> 1;
1444 result = result >> shift;
1449 result = 0x7fffffff;
1450 else if (setcond == 2)
1451 result = 0x80000000;
1455 result = ((result >> (shift - 1)) + 1) >> 1;
1457 result = result >> shift;
1460 GPR[rt] = EXTEND32 (result);
1463 011111,5.SHIFT,5.RT,000,2.AC,00000,111000:SPECIAL3:32::EXTR.W
1464 "extr.w r<RT>, ac<AC>, <SHIFT>"
1467 do_w_extr (SD_, RT, AC, SHIFT, 0);
1470 011111,5.RS,5.RT,000,2.AC,00001,111000:SPECIAL3:32::EXTRV.W
1471 "extrv.w r<RT>, ac<AC>, r<RS>"
1474 unsigned32 shift = GPR[RS] & 0x1f;
1475 do_w_extr (SD_, RT, AC, shift, 0);
1478 011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W
1479 "extr_r.w r<RT>, ac<AC>, <SHIFT>"
1482 do_w_extr (SD_, RT, AC, SHIFT, 1);
1485 011111,5.RS,5.RT,000,2.AC,00101,111000:SPECIAL3:32::EXTRV_R.W
1486 "extrv_r.w r<RT>, ac<AC>, r<RS>"
1489 unsigned32 shift = GPR[RS] & 0x1f;
1490 do_w_extr (SD_, RT, AC, shift, 1);
1493 011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W
1494 "extr_rs.w r<RT>, ac<AC>, <SHIFT>"
1497 do_w_extr (SD_, RT, AC, SHIFT, 2);
1500 011111,5.RS,5.RT,000,2.AC,00111,111000:SPECIAL3:32::EXTRV_RS.W
1501 "extrv_rs.w r<RT>, ac<AC>, r<RS>"
1504 unsigned32 shift = GPR[RS] & 0x1f;
1505 do_w_extr (SD_, RT, AC, shift, 2);
1508 :function:::void:do_h_extr:int rt, int ac, int shift
1511 unsigned32 lo = DSPLO(ac);
1512 unsigned32 hi = DSPHI(ac);
1513 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1514 signed64 result = (signed64)prod;
1515 signed64 value = 0xffffffffffff8000LL;
1517 if (result > 0x7fff)
1520 DSPCR |= DSPCR_OUFLAG7;
1522 else if (result < value)
1525 DSPCR |= DSPCR_OUFLAG7;
1527 GPR[rt] = EXTEND32 (result);
1530 011111,5.SHIFT,5.RT,000,2.AC,01110,111000:SPECIAL3:32::EXTR_S.H
1531 "extr_s.h r<RT>, ac<AC>, <SHIFT>"
1534 do_h_extr (SD_, RT, AC, SHIFT);
1537 011111,5.RS,5.RT,000,2.AC,01111,111000:SPECIAL3:32::EXTRV_S.H
1538 "extrv_s.h r<RT>, ac<AC>, r<RS>"
1541 unsigned32 shift = GPR[RS] & 0x1f;
1542 do_h_extr (SD_, RT, AC, shift);
1545 // op: 0 = EXTP, 1 = EXTPDP
1546 :function:::void:do_extp:int rt, int ac, int size, int op
1548 signed32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1549 unsigned32 lo = DSPLO(ac);
1550 unsigned32 hi = DSPHI(ac);
1551 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1552 unsigned64 result = 0;
1553 if (pos - (size + 1) >= -1)
1555 prod >>= (pos - size);
1556 result = prod & (((unsigned64)1 << (size + 1)) - 1);
1557 DSPCR &= (~DSPCR_EFI_SMASK);
1558 if (op == 1) // EXTPDP
1560 if (pos - (size + 1) >= 0)
1562 DSPCR &= (~DSPCR_POS_SMASK);
1563 DSPCR |= ((pos - (size + 1)) & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1565 else if (pos - (size + 1) == -1)
1567 DSPCR |= DSPCR_POS_SMASK;
1576 GPR[rt] = EXTEND32 (result);
1579 011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP
1580 "extp r<RT>, ac<AC>, <SIZE>"
1583 do_extp (SD_, RT, AC, SIZE, 0);
1586 011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV
1587 "extpv r<RT>, ac<AC>, r<RS>"
1590 unsigned32 size = GPR[RS] & 0x1f;
1591 do_extp (SD_, RT, AC, size, 0);
1594 011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP
1595 "extpdp r<RT>, ac<AC>, <SIZE>"
1598 do_extp (SD_, RT, AC, SIZE, 1);
1601 011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV
1602 "extpdpv r<RT>, ac<AC>, r<RS>"
1605 unsigned32 size = GPR[RS] & 0x1f;
1606 do_extp (SD_, RT, AC, size, 1);
1609 :function:::void:do_shilo:int ac, int shift
1611 unsigned32 lo = DSPLO(ac);
1612 unsigned32 hi = DSPHI(ac);
1613 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1620 DSPLO(ac) = EXTEND32 (prod);
1621 DSPHI(ac) = EXTEND32 (prod >> 32);
1624 011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO
1625 "shilo ac<AC>, <SHIFT6>"
1628 do_shilo (SD_, AC, SHIFT6);
1631 011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV
1632 "shilov ac<AC>, r<RS>"
1635 signed32 shift = GPR[RS] & 0x3f;
1636 do_shilo (SD_, AC, shift);
1639 011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP
1640 "mthlip r<RS>, ac<AC>"
1643 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1644 DSPHI(AC) = DSPLO(AC);
1645 DSPLO(AC) = GPR[RS];
1650 DSPCR &= (~DSPCR_POS_SMASK);
1651 DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1654 000000,000,2.AC,00000,5.RD,00000,010000:SPECIAL:32::MFHIdsp
1655 "mfhi r<RD>":AC == 0
1656 "mfhi r<RD>, ac<AC>"
1666 GPR[RD] = DSPHI(AC);
1669 000000,000,2.AC,00000,5.RD,00000,010010:SPECIAL:32::MFLOdsp
1670 "mflo r<RD>":AC == 0
1671 "mflo r<RD>, ac<AC>"
1681 GPR[RD] = DSPLO(AC);
1684 000000,5.RS,00000,000,2.AC,00000,010001:SPECIAL:32::MTHIdsp
1685 "mthi r<RS>":AC == 0
1686 "mthi r<RS>, ac<AC>"
1694 check_mt_hilo (SD_, HIHISTORY);
1695 DSPHI(AC) = GPR[RS];
1698 000000,5.RS,00000,000,2.AC,00000,010011:SPECIAL:32::MTLOdsp
1699 "mtlo r<RS>":AC == 0
1700 "mtlo r<RS>, ac<AC>"
1708 check_mt_hilo (SD_, LOHISTORY);
1709 DSPLO(AC) = GPR[RS];
1712 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
1713 "wrdsp r<RS>":MASK10 == 1111111111
1714 "wrdsp r<RS>, <MASK10>"
1717 unsigned32 v1 = GPR[RS];
1720 DSPCR &= (~DSPCR_POS_SMASK);
1721 DSPCR |= (v1 & DSPCR_POS_SMASK);
1725 DSPCR &= (~DSPCR_SCOUNT_SMASK);
1726 DSPCR |= (v1 & DSPCR_SCOUNT_SMASK);
1730 DSPCR &= (~DSPCR_CARRY_SMASK);
1731 DSPCR |= (v1 & DSPCR_CARRY_SMASK);
1735 DSPCR &= (~DSPCR_OUFLAG_SMASK);
1736 DSPCR |= (v1 & DSPCR_OUFLAG_SMASK);
1740 DSPCR &= (~DSPCR_CCOND_SMASK);
1741 DSPCR |= (v1 & DSPCR_CCOND_SMASK);
1745 DSPCR &= (~DSPCR_EFI_SMASK);
1746 DSPCR |= (v1 & DSPCR_EFI_SMASK);
1750 011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP
1751 "rddsp r<RD>":MASK10 == 1111111111
1752 "rddsp r<RD>, <MASK10>"
1755 unsigned32 result = 0;
1758 result &= (~DSPCR_POS_SMASK);
1759 result |= (DSPCR & DSPCR_POS_SMASK);
1763 result &= (~DSPCR_SCOUNT_SMASK);
1764 result |= (DSPCR & DSPCR_SCOUNT_SMASK);
1768 result &= (~DSPCR_CARRY_SMASK);
1769 result |= (DSPCR & DSPCR_CARRY_SMASK);
1773 result &= (~DSPCR_OUFLAG_SMASK);
1774 result |= (DSPCR & DSPCR_OUFLAG_SMASK);
1778 result &= (~DSPCR_CCOND_SMASK);
1779 result |= (DSPCR & DSPCR_CCOND_SMASK);
1783 result &= (~DSPCR_EFI_SMASK);
1784 result |= (DSPCR & DSPCR_EFI_SMASK);
1786 GPR[RD] = EXTEND32 (result);
1789 011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX
1790 "lbux r<RD>, r<INDEX>(r<BASE>)"
1793 GPR[RD] = do_load (SD_, AccessLength_BYTE, GPR[BASE], GPR[INDEX]);
1796 011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX
1797 "lhx r<RD>, r<INDEX>(r<BASE>)"
1800 GPR[RD] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], GPR[INDEX]));
1803 011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX
1804 "lwx r<RD>, r<INDEX>(r<BASE>)"
1807 GPR[RD] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
1810 000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32
1814 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1815 address_word offset = EXTEND16 (OFFSET) << 2;
1818 DELAY_SLOT (NIA + offset);