3 // Simulator definition for the MIPS DSP ASE.
4 // Copyright (C) 2005-2014 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 3 of the License, or
12 // (at your option) any later version.
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
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 // op: 0 = ADD, 1 = SUB, 2 = MUL
24 // sat: 0 = no saturation, 1 = saturation
25 :function:::void:do_ph_op:int rd, int rs, int rt, int op, int sat
30 unsigned32 v1 = GPR[rs];
31 unsigned32 v2 = GPR[rt];
32 unsigned32 result = 0;
33 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
35 h1 = (signed16)(v1 & 0xffff);
36 h2 = (signed16)(v2 & 0xffff);
38 h0 = (signed32)h1 + (signed32)h2;
39 else if (op == 1) // SUB
40 h0 = (signed32)h1 - (signed32)h2;
42 h0 = (signed32)h1 * (signed32)h2;
43 if (h0 > (signed32)0x7fff || h0 < (signed32)0xffff8000)
45 if (op == 0 || op == 1) // ADD, SUB
46 DSPCR |= DSPCR_OUFLAG4;
47 else if (op == 2) // MUL
48 DSPCR |= DSPCR_OUFLAG5;
51 if (h0 > (signed32)0x7fff)
57 result |= ((unsigned32)((unsigned16)h0) << i);
59 GPR[rd] = EXTEND32 (result);
62 // op: 0 = ADD, 1 = SUB
63 :function:::void:do_w_op:int rd, int rs, int rt, int op
67 unsigned32 v1 = GPR[rs];
68 unsigned32 v2 = GPR[rt];
69 unsigned32 result = 0;
73 h0 = (signed64)h1 + (signed64)h2;
75 h0 = (signed64)h1 - (signed64)h2;
76 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
78 DSPCR |= DSPCR_OUFLAG4;
79 if (h0 & 0x100000000LL)
84 GPR[rd] = EXTEND32 (h0);
87 // op: 0 = ADD, 1 = SUB
88 // sat: 0 = no saturation, 1 = saturation
89 :function:::void:do_qb_op:int rd, int rs, int rt, int op, int sat
94 unsigned32 v1 = GPR[rs];
95 unsigned32 v2 = GPR[rt];
96 unsigned32 result = 0;
97 for (i = 0; i < 32; i += 8, v1 >>= 8, v2 >>= 8)
99 h1 = (unsigned8)(v1 & 0xff);
100 h2 = (unsigned8)(v2 & 0xff);
102 h0 = (unsigned32)h1 + (unsigned32)h2;
104 h0 = (unsigned32)h1 - (unsigned32)h2;
107 DSPCR |= DSPCR_OUFLAG4;
116 result |= ((unsigned32)((unsigned8)h0) << i);
118 GPR[rd] = EXTEND32 (result);
121 // op: 0 = left, 1 = right
122 :function:::void:do_qb_shift:int rd, int rt, int shift, int op
126 unsigned32 v1 = GPR[rt];
127 unsigned32 result = 0;
128 for (i = 0; i < 32; i += 8, v1 >>= 8)
130 h0 = (unsigned8)(v1 & 0xff);
133 for (j = 7; j >= 8 - shift; j--)
137 DSPCR |= DSPCR_OUFLAG6;
145 result |= ((unsigned32)h0 << i);
147 GPR[rd] = EXTEND32 (result);
150 // op: 0 = left, 1 = right
151 // sat: 0 = no saturation/rounding, 1 = saturation/rounding
152 :function:::void:do_ph_shift:int rd, int rt, int shift, int op, int sat
156 unsigned32 v1 = GPR[rt];
157 unsigned32 result = 0;
159 for (i = 0; i < 32; i += 16, v1 >>= 16)
161 h0 = (signed16)(v1 & 0xffff);
167 for (j = 14; j >= 15 - shift; j--)
169 if (!(h0 & (1 << j)))
171 DSPCR |= DSPCR_OUFLAG6;
179 for (j = 14; j >= 15 - shift; j--)
183 DSPCR |= DSPCR_OUFLAG6;
194 else if (setcond == 1)
200 if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1))))
201 h0 = (h0 >> shift) + 1;
206 result |= ((unsigned32)((unsigned16)h0) << i);
208 GPR[rd] = EXTEND32 (result);
211 :function:::void:do_w_shll:int rd, int rt, int shift
214 unsigned32 v1 = GPR[rt];
215 unsigned32 result = 0;
219 for (i = 30; i >= 31 - shift; i--)
221 if (!(v1 & (1 << i)))
223 DSPCR |= DSPCR_OUFLAG6;
231 for (i = 30; i >= 31 - shift; i--)
235 DSPCR |= DSPCR_OUFLAG6;
243 else if (setcond == 1)
246 result = v1 << shift;
247 GPR[rd] = EXTEND32 (result);
250 :function:::void:do_w_shra:int rd, int rt, int shift
252 unsigned32 result = GPR[rt];
253 signed32 h0 = (signed32)result;
254 if (shift != 0 && (h0 & (1 << (shift-1))))
255 h0 = (h0 >> shift) + 1;
258 GPR[rd] = EXTEND32 (h0);
261 011111,5.RS,5.RT,5.RD,01010,010000:SPECIAL3:32::ADDQ.PH
262 "addq.ph r<RD>, r<RS>, r<RT>"
265 do_ph_op (SD_, RD, RS, RT, 0, 0);
268 011111,5.RS,5.RT,5.RD,01110,010000:SPECIAL3:32::ADDQ_S.PH
269 "addq_s.ph r<RD>, r<RS>, r<RT>"
272 do_ph_op (SD_, RD, RS, RT, 0, 1);
275 011111,5.RS,5.RT,5.RD,10110,010000:SPECIAL3:32::ADDQ_S.W
276 "addq_s.w r<RD>, r<RS>, r<RT>"
279 do_w_op (SD_, RD, RS, RT, 0);
282 011111,5.RS,5.RT,5.RD,00000,010000:SPECIAL3:32::ADDU.QB
283 "addu.qb r<RD>, r<RS>, r<RT>"
286 do_qb_op (SD_, RD, RS, RT, 0, 0);
289 011111,5.RS,5.RT,5.RD,00100,010000:SPECIAL3:32::ADDU_S.QB
290 "addu_s.qb r<RD>, r<RS>, r<RT>"
293 do_qb_op (SD_, RD, RS, RT, 0, 1);
296 011111,5.RS,5.RT,5.RD,01011,010000:SPECIAL3:32::SUBQ.PH
297 "subq.ph r<RD>, r<RS>, r<RT>"
300 do_ph_op (SD_, RD, RS, RT, 1, 0);
303 011111,5.RS,5.RT,5.RD,01111,010000:SPECIAL3:32::SUBQ_S.PH
304 "subq_s.ph r<RD>, r<RS>, r<RT>"
307 do_ph_op (SD_, RD, RS, RT, 1, 1);
310 011111,5.RS,5.RT,5.RD,10111,010000:SPECIAL3:32::SUBQ_S.W
311 "subq_s.w r<RD>, r<RS>, r<RT>"
314 do_w_op (SD_, RD, RS, RT, 1);
317 011111,5.RS,5.RT,5.RD,00001,010000:SPECIAL3:32::SUBU.QB
318 "subu.qb r<RD>, r<RS>, r<RT>"
321 do_qb_op (SD_, RD, RS, RT, 1, 0);
324 011111,5.RS,5.RT,5.RD,00101,010000:SPECIAL3:32::SUBU_S.QB
325 "subu_s.qb r<RD>, r<RS>, r<RT>"
328 do_qb_op (SD_, RD, RS, RT, 1, 1);
331 011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC
332 "addsc r<RD>, r<RS>, r<RT>"
335 unsigned32 v1 = GPR[RS];
336 unsigned32 v2 = GPR[RT];
338 h0 = (unsigned64)v1 + (unsigned64)v2;
339 if (h0 & 0x100000000LL)
340 DSPCR |= DSPCR_CARRY;
341 GPR[RD] = EXTEND32 (h0);
344 011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC
345 "addwc r<RD>, r<RS>, r<RT>"
348 unsigned32 v1 = GPR[RS];
349 unsigned32 v2 = GPR[RT];
351 signed32 h1 = (signed32) v1;
352 signed32 h2 = (signed32) v2;
353 h0 = (signed64)h1 + (signed64)h2
354 + (signed64)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK);
355 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
356 DSPCR |= DSPCR_OUFLAG4;
357 GPR[RD] = EXTEND32 (h0);
360 011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB
361 "modsub r<RD>, r<RS>, r<RT>"
364 unsigned32 result = 0;
365 unsigned32 v1 = GPR[RS];
366 unsigned32 v2 = GPR[RT];
367 unsigned32 decr = v2 & 0xff;
368 unsigned32 lastindex = (v2 & 0xffff00) >> 8;
373 GPR[RD] = EXTEND32 (result);
376 011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB
377 "raddu.w.qb r<RD>, r<RS>"
382 unsigned32 v1 = GPR[RS];
383 unsigned32 result = 0;
384 for (i = 0; i < 32; i += 8, v1 >>= 8)
386 h0 = (unsigned8)(v1 & 0xff);
387 result += (unsigned32)h0;
389 GPR[RD] = EXTEND32 (result);
392 011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH
393 "absq_s.ph r<RD>, r<RT>"
398 unsigned32 v1 = GPR[RT];
399 unsigned32 result = 0;
400 for (i = 0; i < 32; i += 16, v1 >>= 16)
402 h0 = (signed16)(v1 & 0xffff);
403 if (h0 == (signed16)0x8000)
405 DSPCR |= DSPCR_OUFLAG4;
408 else if (h0 & 0x8000)
410 result |= ((unsigned32)((unsigned16)h0) << i);
412 GPR[RD] = EXTEND32 (result);
415 011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W
416 "absq_s.w r<RD>, r<RT>"
419 unsigned32 v1 = GPR[RT];
420 signed32 h0 = (signed32)v1;
421 if (h0 == (signed32)0x80000000)
423 DSPCR |= DSPCR_OUFLAG4;
426 else if (h0 & 0x80000000)
428 GPR[RD] = EXTEND32 (h0);
431 011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH
432 "precrq.qb.ph r<RD>, r<RS>, r<RT>"
435 unsigned32 v1 = GPR[RS];
436 unsigned32 v2 = GPR[RT];
437 unsigned32 tempu = (v1 & 0xff000000) >> 24;
438 unsigned32 tempv = (v1 & 0xff00) >> 8;
439 unsigned32 tempw = (v2 & 0xff000000) >> 24;
440 unsigned32 tempx = (v2 & 0xff00) >> 8;
441 GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
444 011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W
445 "precrq.ph.w r<RD>, r<RS>, r<RT>"
448 unsigned32 v1 = GPR[RS];
449 unsigned32 v2 = GPR[RT];
450 unsigned32 tempu = (v1 & 0xffff0000) >> 16;
451 unsigned32 tempv = (v2 & 0xffff0000) >> 16;
452 GPR[RD] = EXTEND32 ((tempu << 16) | tempv);
455 011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W
456 "precrq_rs.ph.w r<RD>, r<RS>, r<RT>"
459 unsigned32 v1 = GPR[RS];
460 unsigned32 v2 = GPR[RT];
461 signed32 h1 = (signed32)v1;
462 signed32 h2 = (signed32)v2;
463 signed64 temp1 = (signed64)h1 + (signed64)0x8000;
465 signed64 temp3 = (signed64)h2 + (signed64)0x8000;
467 if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000))
469 DSPCR |= DSPCR_OUFLAG6;
473 temp2 = (signed32)((temp1 & 0xffff0000) >> 16);
474 if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000))
476 DSPCR |= DSPCR_OUFLAG6;
480 temp4 = (signed32)((temp3 & 0xffff0000) >> 16);
481 GPR[RD] = EXTEND32 ((temp2 << 16) | temp4);
484 011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH
485 "precrqu_s.qb.ph r<RD>, r<RS>, r<RT>"
488 unsigned32 v1 = GPR[RS];
489 unsigned32 v2 = GPR[RT];
490 unsigned32 tempu, tempv, tempw, tempx;
493 DSPCR |= DSPCR_OUFLAG6;
496 else if (!(v1 & 0x80000000) && ((v1 >> 16) > (unsigned32)0x7f80))
498 DSPCR |= DSPCR_OUFLAG6;
502 tempu = (v1 & 0x7f800000) >> 23;
505 DSPCR |= DSPCR_OUFLAG6;
508 else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (unsigned32)0x7f80))
510 DSPCR |= DSPCR_OUFLAG6;
514 tempv = (v1 & 0x7f80) >> 7;
517 DSPCR |= DSPCR_OUFLAG6;
520 else if (!(v2 & 0x80000000) && ((v2 >> 16) > (unsigned32)0x7f80))
522 DSPCR |= DSPCR_OUFLAG6;
526 tempw = (v2 & 0x7f800000) >> 23;
529 DSPCR |= DSPCR_OUFLAG6;
532 else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (unsigned32)0x7f80))
534 DSPCR |= DSPCR_OUFLAG6;
538 tempx = (v2 & 0x7f80) >> 7;
539 GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
542 011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL
543 "preceq.w.phl r<RD>, r<RT>"
546 unsigned32 v1 = GPR[RT];
547 GPR[RD] = EXTEND32 (v1 & 0xffff0000);
550 011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR
551 "preceq.w.phr r<RD>, r<RT>"
554 unsigned32 v1 = GPR[RT];
555 GPR[RD] = EXTEND32 ((v1 & 0xffff) << 16);
558 011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL
559 "precequ.ph.qbl r<RD>, r<RT>"
562 unsigned32 v1 = GPR[RT];
563 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9);
566 011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR
567 "precequ.ph.qbr r<RD>, r<RT>"
570 unsigned32 v1 = GPR[RT];
571 GPR[RD] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7);
574 011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA
575 "precequ.ph.qbla r<RD>, r<RT>"
578 unsigned32 v1 = GPR[RT];
579 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1);
582 011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA
583 "precequ.ph.qbra r<RD>, r<RT>"
586 unsigned32 v1 = GPR[RT];
587 GPR[RD] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7);
590 011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL
591 "preceu.ph.qbl r<RD>, r<RT>"
594 unsigned32 v1 = GPR[RT];
595 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16);
598 011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR
599 "preceu.ph.qbr r<RD>, r<RT>"
602 unsigned32 v1 = GPR[RT];
603 GPR[RD] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff);
606 011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA
607 "preceu.ph.qbla r<RD>, r<RT>"
610 unsigned32 v1 = GPR[RT];
611 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8);
614 011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA
615 "preceu.ph.qbra r<RD>, r<RT>"
618 unsigned32 v1 = GPR[RT];
619 GPR[RD] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff));
622 011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB
623 "shll.qb r<RD>, r<RT>, <SHIFT3>"
626 do_qb_shift (SD_, RD, RT, SHIFT3, 0);
629 011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB
630 "shllv.qb r<RD>, r<RT>, r<RS>"
633 unsigned32 shift = GPR[RS] & 0x7;
634 do_qb_shift (SD_, RD, RT, shift, 0);
637 011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH
638 "shll.ph r<RD>, r<RT>, <SHIFT4>"
641 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0);
644 011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH
645 "shllv.ph r<RD>, r<RT>, r<RS>"
648 unsigned32 shift = GPR[RS] & 0xf;
649 do_ph_shift (SD_, RD, RT, shift, 0, 0);
652 011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH
653 "shll_s.ph r<RD>, r<RT>, <SHIFT4>"
656 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1);
659 011111,5.RS,5.RT,5.RD,01110,010011:SPECIAL3:32::SHLLV_S.PH
660 "shllv_s.ph r<RD>, r<RT>, r<RS>"
663 unsigned32 shift = GPR[RS] & 0xf;
664 do_ph_shift (SD_, RD, RT, shift, 0, 1);
667 011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W
668 "shll_s.w r<RD>, r<RT>, <SHIFT5>"
671 do_w_shll (SD_, RD, RT, SHIFT5);
674 011111,5.RS,5.RT,5.RD,10110,010011:SPECIAL3:32::SHLLV_S.W
675 "shllv_s.w r<RD>, r<RT>, r<RS>"
678 unsigned32 shift = GPR[RS] & 0x1f;
679 do_w_shll (SD_, RD, RT, shift);
682 011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB
683 "shrl.qb r<RD>, r<RT>, <SHIFT3>"
686 do_qb_shift (SD_, RD, RT, SHIFT3, 1);
689 011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB
690 "shrlv.qb r<RD>, r<RT>, r<RS>"
693 unsigned32 shift = GPR[RS] & 0x7;
694 do_qb_shift (SD_, RD, RT, shift, 1);
697 011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH
698 "shra.ph r<RD>, r<RT>, <SHIFT4>"
701 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0);
704 011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH
705 "shrav.ph r<RD>, r<RT>, r<RS>"
708 unsigned32 shift = GPR[RS] & 0xf;
709 do_ph_shift (SD_, RD, RT, shift, 1, 0);
712 011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH
713 "shra_r.ph r<RD>, r<RT>, <SHIFT4>"
716 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1);
719 011111,5.RS,5.RT,5.RD,01111,010011:SPECIAL3:32::SHRAV_R.PH
720 "shrav_r.ph r<RD>, r<RT>, r<RS>"
723 unsigned32 shift = GPR[RS] & 0xf;
724 do_ph_shift (SD_, RD, RT, shift, 1, 1);
727 011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W
728 "shra_r.w r<RD>, r<RT>, <SHIFT5>"
731 do_w_shra (SD_, RD, RT, SHIFT5);
734 011111,5.RS,5.RT,5.RD,10111,010011:SPECIAL3:32::SHRAV_R.W
735 "shrav_r.w r<RD>, r<RT>, r<RS>"
738 unsigned32 shift = GPR[RS] & 0x1f;
739 do_w_shra (SD_, RD, RT, shift);
742 // loc: 0 = qhl, 1 = qhr
743 :function:::void:do_qb_muleu:int rd, int rs, int rt, int loc
746 unsigned32 result = 0;
747 unsigned32 v1 = GPR[rs];
748 unsigned32 v2 = GPR[rt];
753 for (i = 0; i < 32; i += 16, v1 >>= 8, v2 >>= 16)
755 h1 = (unsigned16)(v1 & 0xff);
756 h2 = (unsigned16)(v2 & 0xffff);
757 prod = (unsigned32)h1 * (unsigned32)h2;
760 DSPCR |= DSPCR_OUFLAG5;
763 result |= ((unsigned32)prod << i);
765 GPR[rd] = EXTEND32 (result);
768 011111,5.RS,5.RT,5.RD,00110,010000:SPECIAL3:32::MULEU_S.PH.QBL
769 "muleu_s.ph.qbl r<RD>, r<RS>, r<RT>"
772 do_qb_muleu (SD_, RD, RS, RT, 0);
775 011111,5.RS,5.RT,5.RD,00111,010000:SPECIAL3:32::MULEU_S.PH.QBR
776 "muleu_s.ph.qbr r<RD>, r<RS>, r<RT>"
779 do_qb_muleu (SD_, RD, RS, RT, 1);
782 // round: 0 = no rounding, 1 = rounding
783 :function:::void:do_ph_mulq:int rd, int rs, int rt, int round
786 unsigned32 result = 0;
787 unsigned32 v1 = GPR[rs];
788 unsigned32 v2 = GPR[rt];
791 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
793 h1 = (signed16)(v1 & 0xffff);
794 h2 = (signed16)(v2 & 0xffff);
795 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
797 DSPCR |= DSPCR_OUFLAG5;
802 prod = ((signed32)h1 * (signed32)h2) << 1;
804 prod += (signed32)0x8000;
806 result |= (((unsigned32)prod >> 16) << i);
808 GPR[rd] = EXTEND32 (result);
811 011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH
812 "mulq_rs.ph r<RD>, r<RS>, r<RT>"
815 do_ph_mulq (SD_, RD, RS, RT, 1);
818 // loc: 0 = phl, 1 = phr
819 :function:::void:do_ph_muleq:int rd, int rs, int rt, int loc
821 unsigned32 v1 = GPR[rs];
822 unsigned32 v2 = GPR[rt];
827 h1 = (signed16)(v1 >> 16);
828 h2 = (signed16)(v2 >> 16);
832 h1 = (signed16)(v1 & 0xffff);
833 h2 = (signed16)(v2 & 0xffff);
835 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
837 DSPCR |= DSPCR_OUFLAG5;
841 prod = ((signed32)h1 * (signed32)h2) << 1;
842 GPR[rd] = EXTEND32 (prod);
845 011111,5.RS,5.RT,5.RD,11100,010000:SPECIAL3:32::MULEQ_S.W.PHL
846 "muleq_s.w.phl r<RD>, r<RS>, r<RT>"
849 do_ph_muleq (SD_, RD, RS, RT, 0);
852 011111,5.RS,5.RT,5.RD,11101,010000:SPECIAL3:32::MULEQ_S.W.PHR
853 "muleq_s.w.phr r<RD>, r<RS>, r<RT>"
856 do_ph_muleq (SD_, RD, RS, RT, 1);
859 // op: 0 = DPAU 1 = DPSU
860 // loc: 0 = qbl, 1 = qbr
861 :function:::void:do_qb_dot_product:int ac, int rs, int rt, int op, int loc
864 unsigned32 v1 = GPR[rs];
865 unsigned32 v2 = GPR[rt];
867 unsigned32 lo = DSPLO(ac);
868 unsigned32 hi = DSPHI(ac);
869 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
875 for (i = 0; i < 16; i += 8, v1 >>= 8, v2 >>= 8)
877 h1 = (unsigned8)(v1 & 0xff);
878 h2 = (unsigned8)(v2 & 0xff);
880 prod += (unsigned64)h1 * (unsigned64)h2;
882 prod -= (unsigned64)h1 * (unsigned64)h2;
884 DSPLO(ac) = EXTEND32 (prod);
885 DSPHI(ac) = EXTEND32 (prod >> 32);
888 011111,5.RS,5.RT,000,2.AC,00011,110000:SPECIAL3:32::DPAU.H.QBL
889 "dpau.h.qbl ac<AC>, r<RS>, r<RT>"
892 do_qb_dot_product (SD_, AC, RS, RT, 0, 0);
895 011111,5.RS,5.RT,000,2.AC,00111,110000:SPECIAL3:32::DPAU.H.QBR
896 "dpau.h.qbr ac<AC>, r<RS>, r<RT>"
899 do_qb_dot_product (SD_, AC, RS, RT, 0, 1);
902 011111,5.RS,5.RT,000,2.AC,01011,110000:SPECIAL3:32::DPSU.H.QBL
903 "dpsu.h.qbl ac<AC>, r<RS>, r<RT>"
906 do_qb_dot_product (SD_, AC, RS, RT, 1, 0);
909 011111,5.RS,5.RT,000,2.AC,01111,110000:SPECIAL3:32::DPSU.H.QBR
910 "dpsu.h.qbr ac<AC>, r<RS>, r<RT>"
913 do_qb_dot_product (SD_, AC, RS, RT, 1, 1);
916 // op: 0 = DPAQ 1 = DPSQ
917 :function:::void:do_ph_dot_product:int ac, int rs, int rt, int op
920 unsigned32 v1 = GPR[rs];
921 unsigned32 v2 = GPR[rt];
924 unsigned32 lo = DSPLO(ac);
925 unsigned32 hi = DSPHI(ac);
926 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
927 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
929 h1 = (signed16)(v1 & 0xffff);
930 h2 = (signed16)(v2 & 0xffff);
931 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
933 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
934 result = (signed32)0x7fffffff;
937 result = ((signed32)h1 * (signed32)h2) << 1;
940 prod += (signed64)result;
942 prod -= (signed64)result;
944 DSPLO(ac) = EXTEND32 (prod);
945 DSPHI(ac) = EXTEND32 (prod >> 32);
948 011111,5.RS,5.RT,000,2.AC,00100,110000:SPECIAL3:32::DPAQ_S.W.PH
949 "dpaq_s.w.ph ac<AC>, r<RS>, r<RT>"
952 do_ph_dot_product (SD_, AC, RS, RT, 0);
955 011111,5.RS,5.RT,000,2.AC,00101,110000:SPECIAL3:32::DPSQ_S.W.PH
956 "dpsq_s.w.ph ac<AC>, r<RS>, r<RT>"
959 do_ph_dot_product (SD_, AC, RS, RT, 1);
962 011111,5.RS,5.RT,000,2.AC,00110,110000:SPECIAL3:32::MULSAQ_S.W.PH
963 "mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>"
967 unsigned32 v1 = GPR[RS];
968 unsigned32 v2 = GPR[RT];
971 unsigned32 lo = DSPLO(AC);
972 unsigned32 hi = DSPHI(AC);
973 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
974 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
976 h1 = (signed16)(v1 & 0xffff);
977 h2 = (signed16)(v2 & 0xffff);
978 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
980 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + AC));
981 result = (signed32) 0x7fffffff;
984 result = ((signed32)h1 * (signed32)h2) << 1;
987 prod -= (signed64) result;
989 prod += (signed64) result;
991 DSPLO(AC) = EXTEND32 (prod);
992 DSPHI(AC) = EXTEND32 (prod >> 32);
995 // op: 0 = DPAQ 1 = DPSQ
996 :function:::void:do_w_dot_product:int ac, int rs, int rt, int op
998 unsigned32 v1 = GPR[rs];
999 unsigned32 v2 = GPR[rt];
1002 unsigned32 lo = DSPLO(ac);
1003 unsigned32 hi = DSPHI(ac);
1004 unsigned32 resultlo;
1005 unsigned32 resulthi;
1011 if (h1 == 0x80000000 && h2 == 0x80000000)
1013 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1014 result = (signed64) 0x7fffffffffffffffLL;
1017 result = ((signed64)h1 * (signed64)h2) << 1;
1018 resultlo = (unsigned32)(result);
1019 resulthi = (unsigned32)(result >> 32);
1022 temp1 = (unsigned64)lo + (unsigned64)resultlo;
1023 carry = (unsigned32)((temp1 >> 32) & 1);
1024 temp2 = (signed64)((signed32)hi) + (signed64)((signed32)resulthi) +
1025 (signed64)((signed32)carry);
1029 temp1 = (unsigned64)lo - (unsigned64)resultlo;
1030 carry = (unsigned32)((temp1 >> 32) & 1);
1031 temp2 = (signed64)((signed32)hi) - (signed64)((signed32)resulthi) -
1032 (signed64)((signed32)carry);
1034 if (((temp2 & 0x100000000LL) >> 1) != (temp2 & 0x80000000LL))
1036 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1037 if (temp2 & 0x100000000LL)
1039 DSPLO(ac) = EXTEND32 (0x00000000);
1040 DSPHI(ac) = EXTEND32 (0x80000000);
1044 DSPLO(ac) = EXTEND32 (0xffffffff);
1045 DSPHI(ac) = EXTEND32 (0x7fffffff);
1050 DSPLO(ac) = EXTEND32 (temp1);
1051 DSPHI(ac) = EXTEND32 (temp2);
1055 011111,5.RS,5.RT,000,2.AC,01100,110000:SPECIAL3:32::DPAQ_SA.L.W
1056 "dpaq_sa.l.w ac<AC>, r<RS>, r<RT>"
1059 do_w_dot_product (SD_, AC, RS, RT, 0);
1062 011111,5.RS,5.RT,000,2.AC,01101,110000:SPECIAL3:32::DPSQ_SA.L.W
1063 "dpsq_sa.l.w ac<AC>, r<RS>, r<RT>"
1066 do_w_dot_product (SD_, AC, RS, RT, 1);
1069 // op: 0 = MAQ_S 1 = MAQ_SA
1070 // loc: 0 = phl, 1 = phr
1071 :function:::void:do_ph_maq:int ac, int rs, int rt, int op, int loc
1074 unsigned32 v1 = GPR[rs];
1075 unsigned32 v2 = GPR[rt];
1078 unsigned32 lo = DSPLO(ac);
1079 unsigned32 hi = DSPHI(ac);
1080 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
1083 h1 = (signed16)(v1 >> 16);
1084 h2 = (signed16)(v2 >> 16);
1088 h1 = (signed16)(v1 & 0xffff);
1089 h2 = (signed16)(v2 & 0xffff);
1091 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
1093 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1094 result = (signed32)0x7fffffff;
1097 result = ((signed32)h1 * (signed32)h2) << 1;
1098 prod += (signed64)result;
1099 if (op == 1) // MAQ_SA
1101 if (prod & 0x8000000000000000LL)
1103 for (i = 62; i >= 31; i--)
1105 if (!(prod & ((signed64)1 << i)))
1107 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1108 prod = 0xffffffff80000000LL;
1115 for (i = 62; i >= 31; i--)
1117 if (prod & ((signed64)1 << i))
1119 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1126 DSPLO(ac) = EXTEND32 (prod);
1127 DSPHI(ac) = EXTEND32 (prod >> 32);
1130 011111,5.RS,5.RT,000,2.AC,10100,110000:SPECIAL3:32::MAQ_S.W.PHL
1131 "maq_s.w.phl ac<AC>, r<RS>, r<RT>"
1134 do_ph_maq (SD_, AC, RS, RT, 0, 0);
1137 011111,5.RS,5.RT,000,2.AC,10110,110000:SPECIAL3:32::MAQ_S.W.PHR
1138 "maq_s.w.phr ac<AC>, r<RS>, r<RT>"
1141 do_ph_maq (SD_, AC, RS, RT, 0, 1);
1144 011111,5.RS,5.RT,000,2.AC,10000,110000:SPECIAL3:32::MAQ_SA.W.PHL
1145 "maq_sa.w.phl ac<AC>, r<RS>, r<RT>"
1148 do_ph_maq (SD_, AC, RS, RT, 1, 0);
1151 011111,5.RS,5.RT,000,2.AC,10010,110000:SPECIAL3:32::MAQ_SA.W.PHR
1152 "maq_sa.w.phr ac<AC>, r<RS>, r<RT>"
1155 do_ph_maq (SD_, AC, RS, RT, 1, 1);
1158 011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV
1159 "bitrev r<RD>, r<RT>"
1163 unsigned32 v1 = GPR[RT];
1165 for (i = 0; i < 16; i++)
1168 h1 |= (1 << (15 - i));
1170 GPR[RD] = EXTEND32 (h1);
1173 011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV
1177 unsigned32 v1 = GPR[RS];
1178 unsigned32 v2 = GPR[RT];
1179 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1180 unsigned32 size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK;
1181 unsigned32 mask1, mask2, mask3, result;
1183 mask1 = (1 << size) - 1;
1186 mask2 = (1 << pos) - 1;
1187 if (pos + size < 32)
1188 mask3 = ~((1 << (pos + size)) - 1);
1191 result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2);
1192 GPR[RT] = EXTEND32 (result);
1195 011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB
1196 "repl.qb r<RD>, <IMM8>"
1199 GPR[RD] = EXTEND32 ((IMM8 << 24) | (IMM8 << 16) | (IMM8 << 8) | IMM8);
1202 011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB
1203 "replv.qb r<RD>, r<RT>"
1206 unsigned32 v1 = GPR[RT];
1208 GPR[RD] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1);
1211 011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH
1212 "repl.ph r<RD>, <IMM10>"
1215 signed32 v1 = IMM10;
1218 GPR[RD] = EXTEND32 ((v1 << 16) | (v1 & 0xffff));
1221 011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH
1222 "replv.ph r<RD>, r<RT>"
1225 unsigned32 v1 = GPR[RT];
1227 GPR[RD] = EXTEND32 ((v1 << 16) | v1);
1230 // op: 0 = EQ, 1 = LT, 2 = LE
1231 :function:::void:do_qb_cmpu:int rs, int rt, int op
1234 unsigned32 v1 = GPR[rs];
1235 unsigned32 v2 = GPR[rt];
1238 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1240 h1 = (unsigned8)(v1 & 0xff);
1241 h2 = (unsigned8)(v2 & 0xff);
1242 mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1245 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1246 else if (op == 1) // LT
1247 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1249 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1253 011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB
1254 "cmpu.eq.qb r<RS>, r<RT>"
1257 do_qb_cmpu (SD_, RS, RT, 0);
1260 011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB
1261 "cmpu.lt.qb r<RS>, r<RT>"
1264 do_qb_cmpu (SD_, RS, RT, 1);
1267 011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB
1268 "cmpu.le.qb r<RS>, r<RT>"
1271 do_qb_cmpu (SD_, RS, RT, 2);
1274 // op: 0 = EQ, 1 = LT, 2 = LE
1275 :function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op
1278 unsigned32 v1 = GPR[rs];
1279 unsigned32 v2 = GPR[rt];
1281 unsigned32 result = 0;
1282 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1284 h1 = (unsigned8)(v1 & 0xff);
1285 h2 = (unsigned8)(v2 & 0xff);
1287 result |= ((h1 == h2) << j);
1288 else if (op == 1) // LT
1289 result |= ((h1 < h2) << j);
1291 result |= ((h1 <= h2) << j);
1293 GPR[rd] = EXTEND32 (result);
1296 011111,5.RS,5.RT,5.RD,00100,010001:SPECIAL3:32::CMPGU.EQ.QB
1297 "cmpgu.eq.qb r<RD>, r<RS>, r<RT>"
1300 do_qb_cmpgu (SD_, RD, RS, RT, 0);
1303 011111,5.RS,5.RT,5.RD,00101,010001:SPECIAL3:32::CMPGU.LT.QB
1304 "cmpgu.lt.qb r<RD>, r<RS>, r<RT>"
1307 do_qb_cmpgu (SD_, RD, RS, RT, 1);
1310 011111,5.RS,5.RT,5.RD,00110,010001:SPECIAL3:32::CMPGU.LE.QB
1311 "cmpgu.le.qb r<RD>, r<RS>, r<RT>"
1314 do_qb_cmpgu (SD_, RD, RS, RT, 2);
1317 // op: 0 = EQ, 1 = LT, 2 = LE
1318 :function:::void:do_ph_cmpu:int rs, int rt, int op
1321 unsigned32 v1 = GPR[rs];
1322 unsigned32 v2 = GPR[rt];
1325 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1327 h1 = (signed16)(v1 & 0xffff);
1328 h2 = (signed16)(v2 & 0xffff);
1329 mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1332 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1333 else if (op == 1) // LT
1334 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1336 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1340 011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH
1341 "cmp.eq.ph r<RS>, r<RT>"
1344 do_ph_cmpu (SD_, RS, RT, 0);
1347 011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH
1348 "cmp.lt.ph r<RS>, r<RT>"
1351 do_ph_cmpu (SD_, RS, RT, 1);
1354 011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH
1355 "cmp.le.ph r<RS>, r<RT>"
1358 do_ph_cmpu (SD_, RS, RT, 2);
1361 011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB
1362 "pick.qb r<RD>, r<RS>, r<RT>"
1366 unsigned32 v1 = GPR[RS];
1367 unsigned32 v2 = GPR[RT];
1369 unsigned32 result = 0;
1370 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1372 h1 = (unsigned8)(v1 & 0xff);
1373 h2 = (unsigned8)(v2 & 0xff);
1374 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
1375 result |= (unsigned32)(h1 << i);
1377 result |= (unsigned32)(h2 << i);
1379 GPR[RD] = EXTEND32 (result);
1382 011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH
1383 "pick.ph r<RD>, r<RS>, r<RT>"
1387 unsigned32 v1 = GPR[RS];
1388 unsigned32 v2 = GPR[RT];
1390 unsigned32 result = 0;
1391 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1393 h1 = (unsigned16)(v1 & 0xffff);
1394 h2 = (unsigned16)(v2 & 0xffff);
1395 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
1396 result |= (unsigned32)(h1 << i);
1398 result |= (unsigned32)(h2 << i);
1400 GPR[RD] = EXTEND32 (result);
1403 011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH
1404 "packrl.ph r<RD>, r<RS>, r<RT>"
1407 unsigned32 v1 = GPR[RS];
1408 unsigned32 v2 = GPR[RT];
1409 GPR[RD] = EXTEND32 ((v1 << 16) + (v2 >> 16));
1412 // op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS
1413 :function:::void:do_w_extr:int rt, int ac, int shift, int op
1416 unsigned32 lo = DSPLO(ac);
1417 unsigned32 hi = DSPHI(ac);
1418 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1419 signed64 result = (signed64)prod;
1421 if (!(prod & 0x8000000000000000LL))
1423 for (i = 62; i >= (shift + 31); i--)
1425 if (prod & ((unsigned64)1 << i))
1427 DSPCR |= DSPCR_OUFLAG7;
1432 if (((prod >> (shift - 1)) & 0xffffffffLL) == 0xffffffffLL)
1434 DSPCR |= DSPCR_OUFLAG7;
1440 for (i = 62; i >= (shift + 31); i--)
1442 if (!(prod & ((unsigned64)1 << i)))
1444 DSPCR |= DSPCR_OUFLAG7;
1450 if (op == 0) // EXTR
1451 result = result >> shift;
1452 else if (op == 1) // EXTR_R
1455 result = ((result >> (shift - 1)) + 1) >> 1;
1457 result = result >> shift;
1462 result = 0x7fffffff;
1463 else if (setcond == 2)
1464 result = 0x80000000;
1468 result = ((result >> (shift - 1)) + 1) >> 1;
1470 result = result >> shift;
1473 GPR[rt] = EXTEND32 (result);
1476 011111,5.SHIFT,5.RT,000,2.AC,00000,111000:SPECIAL3:32::EXTR.W
1477 "extr.w r<RT>, ac<AC>, <SHIFT>"
1480 do_w_extr (SD_, RT, AC, SHIFT, 0);
1483 011111,5.RS,5.RT,000,2.AC,00001,111000:SPECIAL3:32::EXTRV.W
1484 "extrv.w r<RT>, ac<AC>, r<RS>"
1487 unsigned32 shift = GPR[RS] & 0x1f;
1488 do_w_extr (SD_, RT, AC, shift, 0);
1491 011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W
1492 "extr_r.w r<RT>, ac<AC>, <SHIFT>"
1495 do_w_extr (SD_, RT, AC, SHIFT, 1);
1498 011111,5.RS,5.RT,000,2.AC,00101,111000:SPECIAL3:32::EXTRV_R.W
1499 "extrv_r.w r<RT>, ac<AC>, r<RS>"
1502 unsigned32 shift = GPR[RS] & 0x1f;
1503 do_w_extr (SD_, RT, AC, shift, 1);
1506 011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W
1507 "extr_rs.w r<RT>, ac<AC>, <SHIFT>"
1510 do_w_extr (SD_, RT, AC, SHIFT, 2);
1513 011111,5.RS,5.RT,000,2.AC,00111,111000:SPECIAL3:32::EXTRV_RS.W
1514 "extrv_rs.w r<RT>, ac<AC>, r<RS>"
1517 unsigned32 shift = GPR[RS] & 0x1f;
1518 do_w_extr (SD_, RT, AC, shift, 2);
1521 :function:::void:do_h_extr:int rt, int ac, int shift
1524 unsigned32 lo = DSPLO(ac);
1525 unsigned32 hi = DSPHI(ac);
1526 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1527 signed64 result = (signed64)prod;
1528 signed64 value = 0xffffffffffff8000LL;
1530 if (result > 0x7fff)
1533 DSPCR |= DSPCR_OUFLAG7;
1535 else if (result < value)
1538 DSPCR |= DSPCR_OUFLAG7;
1540 GPR[rt] = EXTEND32 (result);
1543 011111,5.SHIFT,5.RT,000,2.AC,01110,111000:SPECIAL3:32::EXTR_S.H
1544 "extr_s.h r<RT>, ac<AC>, <SHIFT>"
1547 do_h_extr (SD_, RT, AC, SHIFT);
1550 011111,5.RS,5.RT,000,2.AC,01111,111000:SPECIAL3:32::EXTRV_S.H
1551 "extrv_s.h r<RT>, ac<AC>, r<RS>"
1554 unsigned32 shift = GPR[RS] & 0x1f;
1555 do_h_extr (SD_, RT, AC, shift);
1558 // op: 0 = EXTP, 1 = EXTPDP
1559 :function:::void:do_extp:int rt, int ac, int size, int op
1561 signed32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1562 unsigned32 lo = DSPLO(ac);
1563 unsigned32 hi = DSPHI(ac);
1564 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1565 unsigned64 result = 0;
1566 if (pos - (size + 1) >= -1)
1568 prod >>= (pos - size);
1569 result = prod & (((unsigned64)1 << (size + 1)) - 1);
1570 DSPCR &= (~DSPCR_EFI_SMASK);
1571 if (op == 1) // EXTPDP
1573 if (pos - (size + 1) >= 0)
1575 DSPCR &= (~DSPCR_POS_SMASK);
1576 DSPCR |= ((pos - (size + 1)) & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1578 else if (pos - (size + 1) == -1)
1580 DSPCR |= DSPCR_POS_SMASK;
1589 GPR[rt] = EXTEND32 (result);
1592 011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP
1593 "extp r<RT>, ac<AC>, <SIZE>"
1596 do_extp (SD_, RT, AC, SIZE, 0);
1599 011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV
1600 "extpv r<RT>, ac<AC>, r<RS>"
1603 unsigned32 size = GPR[RS] & 0x1f;
1604 do_extp (SD_, RT, AC, size, 0);
1607 011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP
1608 "extpdp r<RT>, ac<AC>, <SIZE>"
1611 do_extp (SD_, RT, AC, SIZE, 1);
1614 011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV
1615 "extpdpv r<RT>, ac<AC>, r<RS>"
1618 unsigned32 size = GPR[RS] & 0x1f;
1619 do_extp (SD_, RT, AC, size, 1);
1622 :function:::void:do_shilo:int ac, int shift
1624 unsigned32 lo = DSPLO(ac);
1625 unsigned32 hi = DSPHI(ac);
1626 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1633 DSPLO(ac) = EXTEND32 (prod);
1634 DSPHI(ac) = EXTEND32 (prod >> 32);
1637 011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO
1638 "shilo ac<AC>, <SHIFT6>"
1641 do_shilo (SD_, AC, SHIFT6);
1644 011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV
1645 "shilov ac<AC>, r<RS>"
1648 signed32 shift = GPR[RS] & 0x3f;
1649 do_shilo (SD_, AC, shift);
1652 011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP
1653 "mthlip r<RS>, ac<AC>"
1656 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1657 DSPHI(AC) = DSPLO(AC);
1658 DSPLO(AC) = GPR[RS];
1663 DSPCR &= (~DSPCR_POS_SMASK);
1664 DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1667 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
1668 "wrdsp r<RS>":MASK10 == 1111111111
1669 "wrdsp r<RS>, <MASK10>"
1672 unsigned32 v1 = GPR[RS];
1675 DSPCR &= (~DSPCR_POS_SMASK);
1676 DSPCR |= (v1 & DSPCR_POS_SMASK);
1680 DSPCR &= (~DSPCR_SCOUNT_SMASK);
1681 DSPCR |= (v1 & DSPCR_SCOUNT_SMASK);
1685 DSPCR &= (~DSPCR_CARRY_SMASK);
1686 DSPCR |= (v1 & DSPCR_CARRY_SMASK);
1690 DSPCR &= (~DSPCR_OUFLAG_SMASK);
1691 DSPCR |= (v1 & DSPCR_OUFLAG_SMASK);
1695 DSPCR &= (~DSPCR_CCOND_SMASK);
1696 DSPCR |= (v1 & DSPCR_CCOND_SMASK);
1700 DSPCR &= (~DSPCR_EFI_SMASK);
1701 DSPCR |= (v1 & DSPCR_EFI_SMASK);
1705 011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP
1706 "rddsp r<RD>":MASK10 == 1111111111
1707 "rddsp r<RD>, <MASK10>"
1710 unsigned32 result = 0;
1713 result &= (~DSPCR_POS_SMASK);
1714 result |= (DSPCR & DSPCR_POS_SMASK);
1718 result &= (~DSPCR_SCOUNT_SMASK);
1719 result |= (DSPCR & DSPCR_SCOUNT_SMASK);
1723 result &= (~DSPCR_CARRY_SMASK);
1724 result |= (DSPCR & DSPCR_CARRY_SMASK);
1728 result &= (~DSPCR_OUFLAG_SMASK);
1729 result |= (DSPCR & DSPCR_OUFLAG_SMASK);
1733 result &= (~DSPCR_CCOND_SMASK);
1734 result |= (DSPCR & DSPCR_CCOND_SMASK);
1738 result &= (~DSPCR_EFI_SMASK);
1739 result |= (DSPCR & DSPCR_EFI_SMASK);
1741 GPR[RD] = EXTEND32 (result);
1744 011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX
1745 "lbux r<RD>, r<INDEX>(r<BASE>)"
1748 GPR[RD] = do_load (SD_, AccessLength_BYTE, GPR[BASE], GPR[INDEX]);
1751 011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX
1752 "lhx r<RD>, r<INDEX>(r<BASE>)"
1755 GPR[RD] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], GPR[INDEX]));
1758 011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX
1759 "lwx r<RD>, r<INDEX>(r<BASE>)"
1762 GPR[RD] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
1765 000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32
1769 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1770 address_word offset = EXTEND16 (OFFSET) << 2;
1773 DELAY_SLOT (NIA + offset);