3 // Simulator definition for the MIPS DSP ASE.
4 // Copyright (C) 2005, 2007 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
20 // along with GAS; see the file COPYING. If not, write to the Free
21 // Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
25 // op: 0 = ADD, 1 = SUB, 2 = MUL
26 // sat: 0 = no saturation, 1 = saturation
27 :function:::void:do_ph_op:int rd, int rs, int rt, int op, int sat
32 unsigned32 v1 = GPR[rs];
33 unsigned32 v2 = GPR[rt];
34 unsigned32 result = 0;
35 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
37 h1 = (signed16)(v1 & 0xffff);
38 h2 = (signed16)(v2 & 0xffff);
40 h0 = (signed32)h1 + (signed32)h2;
41 else if (op == 1) // SUB
42 h0 = (signed32)h1 - (signed32)h2;
44 h0 = (signed32)h1 * (signed32)h2;
45 if (h0 > (signed32)0x7fff || h0 < (signed32)0xffff8000)
47 if (op == 0 || op == 1) // ADD, SUB
48 DSPCR |= DSPCR_OUFLAG4;
49 else if (op == 2) // MUL
50 DSPCR |= DSPCR_OUFLAG5;
53 if (h0 > (signed32)0x7fff)
59 result |= ((unsigned32)((unsigned16)h0) << i);
61 GPR[rd] = EXTEND32 (result);
64 // op: 0 = ADD, 1 = SUB
65 :function:::void:do_w_op:int rd, int rs, int rt, int op
69 unsigned32 v1 = GPR[rs];
70 unsigned32 v2 = GPR[rt];
71 unsigned32 result = 0;
75 h0 = (signed64)h1 + (signed64)h2;
77 h0 = (signed64)h1 - (signed64)h2;
78 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
80 DSPCR |= DSPCR_OUFLAG4;
81 if (h0 & 0x100000000LL)
86 GPR[rd] = EXTEND32 (h0);
89 // op: 0 = ADD, 1 = SUB
90 // sat: 0 = no saturation, 1 = saturation
91 :function:::void:do_qb_op:int rd, int rs, int rt, int op, int sat
96 unsigned32 v1 = GPR[rs];
97 unsigned32 v2 = GPR[rt];
98 unsigned32 result = 0;
99 for (i = 0; i < 32; i += 8, v1 >>= 8, v2 >>= 8)
101 h1 = (unsigned8)(v1 & 0xff);
102 h2 = (unsigned8)(v2 & 0xff);
104 h0 = (unsigned32)h1 + (unsigned32)h2;
106 h0 = (unsigned32)h1 - (unsigned32)h2;
109 DSPCR |= DSPCR_OUFLAG4;
118 result |= ((unsigned32)((unsigned8)h0) << i);
120 GPR[rd] = EXTEND32 (result);
123 // op: 0 = left, 1 = right
124 :function:::void:do_qb_shift:int rd, int rt, int shift, int op
128 unsigned32 v1 = GPR[rt];
129 unsigned32 result = 0;
130 for (i = 0; i < 32; i += 8, v1 >>= 8)
132 h0 = (unsigned8)(v1 & 0xff);
135 for (j = 7; j >= 8 - shift; j--)
139 DSPCR |= DSPCR_OUFLAG6;
147 result |= ((unsigned32)h0 << i);
149 GPR[rd] = EXTEND32 (result);
152 // op: 0 = left, 1 = right
153 // sat: 0 = no saturation/rounding, 1 = saturation/rounding
154 :function:::void:do_ph_shift:int rd, int rt, int shift, int op, int sat
158 unsigned32 v1 = GPR[rt];
159 unsigned32 result = 0;
161 for (i = 0; i < 32; i += 16, v1 >>= 16)
163 h0 = (signed16)(v1 & 0xffff);
169 for (j = 14; j >= 15 - shift; j--)
171 if (!(h0 & (1 << j)))
173 DSPCR |= DSPCR_OUFLAG6;
181 for (j = 14; j >= 15 - shift; j--)
185 DSPCR |= DSPCR_OUFLAG6;
196 else if (setcond == 1)
202 if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1))))
203 h0 = (h0 >> shift) + 1;
208 result |= ((unsigned32)((unsigned16)h0) << i);
210 GPR[rd] = EXTEND32 (result);
213 :function:::void:do_w_shll:int rd, int rt, int shift
216 unsigned32 v1 = GPR[rt];
217 unsigned32 result = 0;
221 for (i = 30; i >= 31 - shift; i--)
223 if (!(v1 & (1 << i)))
225 DSPCR |= DSPCR_OUFLAG6;
233 for (i = 30; i >= 31 - shift; i--)
237 DSPCR |= DSPCR_OUFLAG6;
245 else if (setcond == 1)
248 result = v1 << shift;
249 GPR[rd] = EXTEND32 (result);
252 :function:::void:do_w_shra:int rd, int rt, int shift
254 unsigned32 result = GPR[rt];
255 signed32 h0 = (signed32)result;
256 if (shift != 0 && (h0 & (1 << (shift-1))))
257 h0 = (h0 >> shift) + 1;
260 GPR[rd] = EXTEND32 (h0);
263 011111,5.RS,5.RT,5.RD,01010,010000:SPECIAL3:32::ADDQ.PH
264 "addq.ph r<RD>, r<RS>, r<RT>"
267 do_ph_op (SD_, RD, RS, RT, 0, 0);
270 011111,5.RS,5.RT,5.RD,01110,010000:SPECIAL3:32::ADDQ_S.PH
271 "addq_s.ph r<RD>, r<RS>, r<RT>"
274 do_ph_op (SD_, RD, RS, RT, 0, 1);
277 011111,5.RS,5.RT,5.RD,10110,010000:SPECIAL3:32::ADDQ_S.W
278 "addq_s.w r<RD>, r<RS>, r<RT>"
281 do_w_op (SD_, RD, RS, RT, 0);
284 011111,5.RS,5.RT,5.RD,00000,010000:SPECIAL3:32::ADDU.QB
285 "addu.qb r<RD>, r<RS>, r<RT>"
288 do_qb_op (SD_, RD, RS, RT, 0, 0);
291 011111,5.RS,5.RT,5.RD,00100,010000:SPECIAL3:32::ADDU_S.QB
292 "addu_s.qb r<RD>, r<RS>, r<RT>"
295 do_qb_op (SD_, RD, RS, RT, 0, 1);
298 011111,5.RS,5.RT,5.RD,01011,010000:SPECIAL3:32::SUBQ.PH
299 "subq.ph r<RD>, r<RS>, r<RT>"
302 do_ph_op (SD_, RD, RS, RT, 1, 0);
305 011111,5.RS,5.RT,5.RD,01111,010000:SPECIAL3:32::SUBQ_S.PH
306 "subq_s.ph r<RD>, r<RS>, r<RT>"
309 do_ph_op (SD_, RD, RS, RT, 1, 1);
312 011111,5.RS,5.RT,5.RD,10111,010000:SPECIAL3:32::SUBQ_S.W
313 "subq_s.w r<RD>, r<RS>, r<RT>"
316 do_w_op (SD_, RD, RS, RT, 1);
319 011111,5.RS,5.RT,5.RD,00001,010000:SPECIAL3:32::SUBU.QB
320 "subu.qb r<RD>, r<RS>, r<RT>"
323 do_qb_op (SD_, RD, RS, RT, 1, 0);
326 011111,5.RS,5.RT,5.RD,00101,010000:SPECIAL3:32::SUBU_S.QB
327 "subu_s.qb r<RD>, r<RS>, r<RT>"
330 do_qb_op (SD_, RD, RS, RT, 1, 1);
333 011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC
334 "addsc r<RD>, r<RS>, r<RT>"
337 unsigned32 v1 = GPR[RS];
338 unsigned32 v2 = GPR[RT];
340 h0 = (unsigned64)v1 + (unsigned64)v2;
341 if (h0 & 0x100000000LL)
342 DSPCR |= DSPCR_CARRY;
343 GPR[RD] = EXTEND32 (h0);
346 011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC
347 "addwc r<RD>, r<RS>, r<RT>"
350 unsigned32 v1 = GPR[RS];
351 unsigned32 v2 = GPR[RT];
353 signed32 h1 = (signed32) v1;
354 signed32 h2 = (signed32) v2;
355 h0 = (signed64)h1 + (signed64)h2
356 + (signed64)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK);
357 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
358 DSPCR |= DSPCR_OUFLAG4;
359 GPR[RD] = EXTEND32 (h0);
362 011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB
363 "modsub r<RD>, r<RS>, r<RT>"
366 unsigned32 result = 0;
367 unsigned32 v1 = GPR[RS];
368 unsigned32 v2 = GPR[RT];
369 unsigned32 decr = v2 & 0xff;
370 unsigned32 lastindex = (v2 & 0xffff00) >> 8;
375 GPR[RD] = EXTEND32 (result);
378 011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB
379 "raddu.w.qb r<RD>, r<RS>"
384 unsigned32 v1 = GPR[RS];
385 unsigned32 result = 0;
386 for (i = 0; i < 32; i += 8, v1 >>= 8)
388 h0 = (unsigned8)(v1 & 0xff);
389 result += (unsigned32)h0;
391 GPR[RD] = EXTEND32 (result);
394 011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH
395 "absq_s.ph r<RD>, r<RT>"
400 unsigned32 v1 = GPR[RT];
401 unsigned32 result = 0;
402 for (i = 0; i < 32; i += 16, v1 >>= 16)
404 h0 = (signed16)(v1 & 0xffff);
405 if (h0 == (signed16)0x8000)
407 DSPCR |= DSPCR_OUFLAG4;
410 else if (h0 & 0x8000)
412 result |= ((unsigned32)((unsigned16)h0) << i);
414 GPR[RD] = EXTEND32 (result);
417 011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W
418 "absq_s.w r<RD>, r<RT>"
421 unsigned32 v1 = GPR[RT];
422 signed32 h0 = (signed32)v1;
423 if (h0 == (signed32)0x80000000)
425 DSPCR |= DSPCR_OUFLAG4;
428 else if (h0 & 0x80000000)
430 GPR[RD] = EXTEND32 (h0);
433 011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH
434 "precrq.qb.ph r<RD>, r<RS>, r<RT>"
437 unsigned32 v1 = GPR[RS];
438 unsigned32 v2 = GPR[RT];
439 unsigned32 tempu = (v1 & 0xff000000) >> 24;
440 unsigned32 tempv = (v1 & 0xff00) >> 8;
441 unsigned32 tempw = (v2 & 0xff000000) >> 24;
442 unsigned32 tempx = (v2 & 0xff00) >> 8;
443 GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
446 011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W
447 "precrq.ph.w r<RD>, r<RS>, r<RT>"
450 unsigned32 v1 = GPR[RS];
451 unsigned32 v2 = GPR[RT];
452 unsigned32 tempu = (v1 & 0xffff0000) >> 16;
453 unsigned32 tempv = (v2 & 0xffff0000) >> 16;
454 GPR[RD] = EXTEND32 ((tempu << 16) | tempv);
457 011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W
458 "precrq_rs.ph.w r<RD>, r<RS>, r<RT>"
461 unsigned32 v1 = GPR[RS];
462 unsigned32 v2 = GPR[RT];
463 signed32 h1 = (signed32)v1;
464 signed32 h2 = (signed32)v2;
465 signed64 temp1 = (signed64)h1 + (signed64)0x8000;
467 signed64 temp3 = (signed64)h2 + (signed64)0x8000;
469 if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000))
471 DSPCR |= DSPCR_OUFLAG6;
475 temp2 = (signed32)((temp1 & 0xffff0000) >> 16);
476 if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000))
478 DSPCR |= DSPCR_OUFLAG6;
482 temp4 = (signed32)((temp3 & 0xffff0000) >> 16);
483 GPR[RD] = EXTEND32 ((temp2 << 16) | temp4);
486 011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH
487 "precrqu_s.qb.ph r<RD>, r<RS>, r<RT>"
490 unsigned32 v1 = GPR[RS];
491 unsigned32 v2 = GPR[RT];
492 unsigned32 tempu, tempv, tempw, tempx;
495 DSPCR |= DSPCR_OUFLAG6;
498 else if (!(v1 & 0x80000000) && ((v1 >> 16) > (unsigned32)0x7f80))
500 DSPCR |= DSPCR_OUFLAG6;
504 tempu = (v1 & 0x7f800000) >> 23;
507 DSPCR |= DSPCR_OUFLAG6;
510 else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (unsigned32)0x7f80))
512 DSPCR |= DSPCR_OUFLAG6;
516 tempv = (v1 & 0x7f80) >> 7;
519 DSPCR |= DSPCR_OUFLAG6;
522 else if (!(v2 & 0x80000000) && ((v2 >> 16) > (unsigned32)0x7f80))
524 DSPCR |= DSPCR_OUFLAG6;
528 tempw = (v2 & 0x7f800000) >> 23;
531 DSPCR |= DSPCR_OUFLAG6;
534 else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (unsigned32)0x7f80))
536 DSPCR |= DSPCR_OUFLAG6;
540 tempx = (v2 & 0x7f80) >> 7;
541 GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
544 011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL
545 "preceq.w.phl r<RD>, r<RT>"
548 unsigned32 v1 = GPR[RT];
549 GPR[RD] = EXTEND32 (v1 & 0xffff0000);
552 011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR
553 "preceq.w.phr r<RD>, r<RT>"
556 unsigned32 v1 = GPR[RT];
557 GPR[RD] = EXTEND32 ((v1 & 0xffff) << 16);
560 011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL
561 "precequ.ph.qbl r<RD>, r<RT>"
564 unsigned32 v1 = GPR[RT];
565 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9);
568 011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR
569 "precequ.ph.qbr r<RD>, r<RT>"
572 unsigned32 v1 = GPR[RT];
573 GPR[RD] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7);
576 011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA
577 "precequ.ph.qbla r<RD>, r<RT>"
580 unsigned32 v1 = GPR[RT];
581 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1);
584 011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA
585 "precequ.ph.qbra r<RD>, r<RT>"
588 unsigned32 v1 = GPR[RT];
589 GPR[RD] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7);
592 011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL
593 "preceu.ph.qbl r<RD>, r<RT>"
596 unsigned32 v1 = GPR[RT];
597 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16);
600 011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR
601 "preceu.ph.qbr r<RD>, r<RT>"
604 unsigned32 v1 = GPR[RT];
605 GPR[RD] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff);
608 011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA
609 "preceu.ph.qbla r<RD>, r<RT>"
612 unsigned32 v1 = GPR[RT];
613 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8);
616 011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA
617 "preceu.ph.qbra r<RD>, r<RT>"
620 unsigned32 v1 = GPR[RT];
621 GPR[RD] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff));
624 011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB
625 "shll.qb r<RD>, r<RT>, <SHIFT3>"
628 do_qb_shift (SD_, RD, RT, SHIFT3, 0);
631 011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB
632 "shllv.qb r<RD>, r<RT>, r<RS>"
635 unsigned32 shift = GPR[RS] & 0x7;
636 do_qb_shift (SD_, RD, RT, shift, 0);
639 011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH
640 "shll.ph r<RD>, r<RT>, <SHIFT4>"
643 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0);
646 011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH
647 "shllv.ph r<RD>, r<RT>, r<RS>"
650 unsigned32 shift = GPR[RS] & 0xf;
651 do_ph_shift (SD_, RD, RT, shift, 0, 0);
654 011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH
655 "shll_s.ph r<RD>, r<RT>, <SHIFT4>"
658 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1);
661 011111,5.RS,5.RT,5.RD,01110,010011:SPECIAL3:32::SHLLV_S.PH
662 "shllv_s.ph r<RD>, r<RT>, r<RS>"
665 unsigned32 shift = GPR[RS] & 0xf;
666 do_ph_shift (SD_, RD, RT, shift, 0, 1);
669 011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W
670 "shll_s.w r<RD>, r<RT>, <SHIFT5>"
673 do_w_shll (SD_, RD, RT, SHIFT5);
676 011111,5.RS,5.RT,5.RD,10110,010011:SPECIAL3:32::SHLLV_S.W
677 "shllv_s.w r<RD>, r<RT>, r<RS>"
680 unsigned32 shift = GPR[RS] & 0x1f;
681 do_w_shll (SD_, RD, RT, shift);
684 011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB
685 "shrl.qb r<RD>, r<RT>, <SHIFT3>"
688 do_qb_shift (SD_, RD, RT, SHIFT3, 1);
691 011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB
692 "shrlv.qb r<RD>, r<RT>, r<RS>"
695 unsigned32 shift = GPR[RS] & 0x7;
696 do_qb_shift (SD_, RD, RT, shift, 1);
699 011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH
700 "shra.ph r<RD>, r<RT>, <SHIFT4>"
703 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0);
706 011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH
707 "shrav.ph r<RD>, r<RT>, r<RS>"
710 unsigned32 shift = GPR[RS] & 0xf;
711 do_ph_shift (SD_, RD, RT, shift, 1, 0);
714 011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH
715 "shra_r.ph r<RD>, r<RT>, <SHIFT4>"
718 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1);
721 011111,5.RS,5.RT,5.RD,01111,010011:SPECIAL3:32::SHRAV_R.PH
722 "shrav_r.ph r<RD>, r<RT>, r<RS>"
725 unsigned32 shift = GPR[RS] & 0xf;
726 do_ph_shift (SD_, RD, RT, shift, 1, 1);
729 011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W
730 "shra_r.w r<RD>, r<RT>, <SHIFT5>"
733 do_w_shra (SD_, RD, RT, SHIFT5);
736 011111,5.RS,5.RT,5.RD,10111,010011:SPECIAL3:32::SHRAV_R.W
737 "shrav_r.w r<RD>, r<RT>, r<RS>"
740 unsigned32 shift = GPR[RS] & 0x1f;
741 do_w_shra (SD_, RD, RT, shift);
744 // loc: 0 = qhl, 1 = qhr
745 :function:::void:do_qb_muleu:int rd, int rs, int rt, int loc
748 unsigned32 result = 0;
749 unsigned32 v1 = GPR[rs];
750 unsigned32 v2 = GPR[rt];
755 for (i = 0; i < 32; i += 16, v1 >>= 8, v2 >>= 16)
757 h1 = (unsigned16)(v1 & 0xff);
758 h2 = (unsigned16)(v2 & 0xffff);
759 prod = (unsigned32)h1 * (unsigned32)h2;
762 DSPCR |= DSPCR_OUFLAG5;
765 result |= ((unsigned32)prod << i);
767 GPR[rd] = EXTEND32 (result);
770 011111,5.RS,5.RT,5.RD,00110,010000:SPECIAL3:32::MULEU_S.PH.QBL
771 "muleu_s.ph.qbl r<RD>, r<RS>, r<RT>"
774 do_qb_muleu (SD_, RD, RS, RT, 0);
777 011111,5.RS,5.RT,5.RD,00111,010000:SPECIAL3:32::MULEU_S.PH.QBR
778 "muleu_s.ph.qbr r<RD>, r<RS>, r<RT>"
781 do_qb_muleu (SD_, RD, RS, RT, 1);
784 // round: 0 = no rounding, 1 = rounding
785 :function:::void:do_ph_mulq:int rd, int rs, int rt, int round
788 unsigned32 result = 0;
789 unsigned32 v1 = GPR[rs];
790 unsigned32 v2 = GPR[rt];
793 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
795 h1 = (signed16)(v1 & 0xffff);
796 h2 = (signed16)(v2 & 0xffff);
797 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
799 DSPCR |= DSPCR_OUFLAG5;
804 prod = ((signed32)h1 * (signed32)h2) << 1;
806 prod += (signed32)0x8000;
808 result |= (((unsigned32)prod >> 16) << i);
810 GPR[rd] = EXTEND32 (result);
813 011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH
814 "mulq_rs.ph r<RD>, r<RS>, r<RT>"
817 do_ph_mulq (SD_, RD, RS, RT, 1);
820 // loc: 0 = phl, 1 = phr
821 :function:::void:do_ph_muleq:int rd, int rs, int rt, int loc
823 unsigned32 v1 = GPR[rs];
824 unsigned32 v2 = GPR[rt];
829 h1 = (signed16)(v1 >> 16);
830 h2 = (signed16)(v2 >> 16);
834 h1 = (signed16)(v1 & 0xffff);
835 h2 = (signed16)(v2 & 0xffff);
837 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
839 DSPCR |= DSPCR_OUFLAG5;
843 prod = ((signed32)h1 * (signed32)h2) << 1;
844 GPR[rd] = EXTEND32 (prod);
847 011111,5.RS,5.RT,5.RD,11100,010000:SPECIAL3:32::MULEQ_S.W.PHL
848 "muleq_s.w.phl r<RD>, r<RS>, r<RT>"
851 do_ph_muleq (SD_, RD, RS, RT, 0);
854 011111,5.RS,5.RT,5.RD,11101,010000:SPECIAL3:32::MULEQ_S.W.PHR
855 "muleq_s.w.phr r<RD>, r<RS>, r<RT>"
858 do_ph_muleq (SD_, RD, RS, RT, 1);
861 // op: 0 = DPAU 1 = DPSU
862 // loc: 0 = qbl, 1 = qbr
863 :function:::void:do_qb_dot_product:int ac, int rs, int rt, int op, int loc
866 unsigned32 v1 = GPR[rs];
867 unsigned32 v2 = GPR[rt];
869 unsigned32 lo = DSPLO(ac);
870 unsigned32 hi = DSPHI(ac);
871 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
877 for (i = 0; i < 16; i += 8, v1 >>= 8, v2 >>= 8)
879 h1 = (unsigned8)(v1 & 0xff);
880 h2 = (unsigned8)(v2 & 0xff);
882 prod += (unsigned64)h1 * (unsigned64)h2;
884 prod -= (unsigned64)h1 * (unsigned64)h2;
886 DSPLO(ac) = EXTEND32 (prod);
887 DSPHI(ac) = EXTEND32 (prod >> 32);
890 011111,5.RS,5.RT,000,2.AC,00011,110000:SPECIAL3:32::DPAU.H.QBL
891 "dpau.h.qbl ac<AC>, r<RS>, r<RT>"
894 do_qb_dot_product (SD_, AC, RS, RT, 0, 0);
897 011111,5.RS,5.RT,000,2.AC,00111,110000:SPECIAL3:32::DPAU.H.QBR
898 "dpau.h.qbr ac<AC>, r<RS>, r<RT>"
901 do_qb_dot_product (SD_, AC, RS, RT, 0, 1);
904 011111,5.RS,5.RT,000,2.AC,01011,110000:SPECIAL3:32::DPSU.H.QBL
905 "dpsu.h.qbl ac<AC>, r<RS>, r<RT>"
908 do_qb_dot_product (SD_, AC, RS, RT, 1, 0);
911 011111,5.RS,5.RT,000,2.AC,01111,110000:SPECIAL3:32::DPSU.H.QBR
912 "dpsu.h.qbr ac<AC>, r<RS>, r<RT>"
915 do_qb_dot_product (SD_, AC, RS, RT, 1, 1);
918 // op: 0 = DPAQ 1 = DPSQ
919 :function:::void:do_ph_dot_product:int ac, int rs, int rt, int op
922 unsigned32 v1 = GPR[rs];
923 unsigned32 v2 = GPR[rt];
926 unsigned32 lo = DSPLO(ac);
927 unsigned32 hi = DSPHI(ac);
928 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
929 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
931 h1 = (signed16)(v1 & 0xffff);
932 h2 = (signed16)(v2 & 0xffff);
933 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
935 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
936 result = (signed32)0x7fffffff;
939 result = ((signed32)h1 * (signed32)h2) << 1;
942 prod += (signed64)result;
944 prod -= (signed64)result;
946 DSPLO(ac) = EXTEND32 (prod);
947 DSPHI(ac) = EXTEND32 (prod >> 32);
950 011111,5.RS,5.RT,000,2.AC,00100,110000:SPECIAL3:32::DPAQ_S.W.PH
951 "dpaq_s.w.ph ac<AC>, r<RS>, r<RT>"
954 do_ph_dot_product (SD_, AC, RS, RT, 0);
957 011111,5.RS,5.RT,000,2.AC,00101,110000:SPECIAL3:32::DPSQ_S.W.PH
958 "dpsq_s.w.ph ac<AC>, r<RS>, r<RT>"
961 do_ph_dot_product (SD_, AC, RS, RT, 1);
964 011111,5.RS,5.RT,000,2.AC,00110,110000:SPECIAL3:32::MULSAQ_S.W.PH
965 "mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>"
969 unsigned32 v1 = GPR[RS];
970 unsigned32 v2 = GPR[RT];
973 unsigned32 lo = DSPLO(AC);
974 unsigned32 hi = DSPHI(AC);
975 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
976 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
978 h1 = (signed16)(v1 & 0xffff);
979 h2 = (signed16)(v2 & 0xffff);
980 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
982 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + AC));
983 result = (signed32) 0x7fffffff;
986 result = ((signed32)h1 * (signed32)h2) << 1;
989 prod -= (signed64) result;
991 prod += (signed64) result;
993 DSPLO(AC) = EXTEND32 (prod);
994 DSPHI(AC) = EXTEND32 (prod >> 32);
997 // op: 0 = DPAQ 1 = DPSQ
998 :function:::void:do_w_dot_product:int ac, int rs, int rt, int op
1000 unsigned32 v1 = GPR[rs];
1001 unsigned32 v2 = GPR[rt];
1004 unsigned32 lo = DSPLO(ac);
1005 unsigned32 hi = DSPHI(ac);
1006 unsigned32 resultlo;
1007 unsigned32 resulthi;
1013 if (h1 == 0x80000000 && h2 == 0x80000000)
1015 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1016 result = (signed64) 0x7fffffffffffffffLL;
1019 result = ((signed64)h1 * (signed64)h2) << 1;
1020 resultlo = (unsigned32)(result);
1021 resulthi = (unsigned32)(result >> 32);
1024 temp1 = (unsigned64)lo + (unsigned64)resultlo;
1025 carry = (unsigned32)((temp1 >> 32) & 1);
1026 temp2 = (signed64)((signed32)hi) + (signed64)((signed32)resulthi) +
1027 (signed64)((signed32)carry);
1031 temp1 = (unsigned64)lo - (unsigned64)resultlo;
1032 carry = (unsigned32)((temp1 >> 32) & 1);
1033 temp2 = (signed64)((signed32)hi) - (signed64)((signed32)resulthi) -
1034 (signed64)((signed32)carry);
1036 if (((temp2 & 0x100000000LL) >> 1) != (temp2 & 0x80000000LL))
1038 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1039 if (temp2 & 0x100000000LL)
1041 DSPLO(ac) = EXTEND32 (0x00000000);
1042 DSPHI(ac) = EXTEND32 (0x80000000);
1046 DSPLO(ac) = EXTEND32 (0xffffffff);
1047 DSPHI(ac) = EXTEND32 (0x7fffffff);
1052 DSPLO(ac) = EXTEND32 (temp1);
1053 DSPHI(ac) = EXTEND32 (temp2);
1057 011111,5.RS,5.RT,000,2.AC,01100,110000:SPECIAL3:32::DPAQ_SA.L.W
1058 "dpaq_sa.l.w ac<AC>, r<RS>, r<RT>"
1061 do_w_dot_product (SD_, AC, RS, RT, 0);
1064 011111,5.RS,5.RT,000,2.AC,01101,110000:SPECIAL3:32::DPSQ_SA.L.W
1065 "dpsq_sa.l.w ac<AC>, r<RS>, r<RT>"
1068 do_w_dot_product (SD_, AC, RS, RT, 1);
1071 // op: 0 = MAQ_S 1 = MAQ_SA
1072 // loc: 0 = phl, 1 = phr
1073 :function:::void:do_ph_maq:int ac, int rs, int rt, int op, int loc
1076 unsigned32 v1 = GPR[rs];
1077 unsigned32 v2 = GPR[rt];
1080 unsigned32 lo = DSPLO(ac);
1081 unsigned32 hi = DSPHI(ac);
1082 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
1085 h1 = (signed16)(v1 >> 16);
1086 h2 = (signed16)(v2 >> 16);
1090 h1 = (signed16)(v1 & 0xffff);
1091 h2 = (signed16)(v2 & 0xffff);
1093 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
1095 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1096 result = (signed32)0x7fffffff;
1099 result = ((signed32)h1 * (signed32)h2) << 1;
1100 prod += (signed64)result;
1101 if (op == 1) // MAQ_SA
1103 if (prod & 0x8000000000000000LL)
1105 for (i = 62; i >= 31; i--)
1107 if (!(prod & ((signed64)1 << i)))
1109 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1110 prod = 0xffffffff80000000LL;
1117 for (i = 62; i >= 31; i--)
1119 if (prod & ((signed64)1 << i))
1121 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1128 DSPLO(ac) = EXTEND32 (prod);
1129 DSPHI(ac) = EXTEND32 (prod >> 32);
1132 011111,5.RS,5.RT,000,2.AC,10100,110000:SPECIAL3:32::MAQ_S.W.PHL
1133 "maq_s.w.phl ac<AC>, r<RS>, r<RT>"
1136 do_ph_maq (SD_, AC, RS, RT, 0, 0);
1139 011111,5.RS,5.RT,000,2.AC,10110,110000:SPECIAL3:32::MAQ_S.W.PHR
1140 "maq_s.w.phr ac<AC>, r<RS>, r<RT>"
1143 do_ph_maq (SD_, AC, RS, RT, 0, 1);
1146 011111,5.RS,5.RT,000,2.AC,10000,110000:SPECIAL3:32::MAQ_SA.W.PHL
1147 "maq_sa.w.phl ac<AC>, r<RS>, r<RT>"
1150 do_ph_maq (SD_, AC, RS, RT, 1, 0);
1153 011111,5.RS,5.RT,000,2.AC,10010,110000:SPECIAL3:32::MAQ_SA.W.PHR
1154 "maq_sa.w.phr ac<AC>, r<RS>, r<RT>"
1157 do_ph_maq (SD_, AC, RS, RT, 1, 1);
1160 011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV
1161 "bitrev r<RD>, r<RT>"
1165 unsigned32 v1 = GPR[RT];
1167 for (i = 0; i < 16; i++)
1170 h1 |= (1 << (15 - i));
1172 GPR[RD] = EXTEND32 (h1);
1175 011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV
1179 unsigned32 v1 = GPR[RS];
1180 unsigned32 v2 = GPR[RT];
1181 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1182 unsigned32 size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK;
1183 unsigned32 mask1, mask2, mask3, result;
1185 mask1 = (1 << size) - 1;
1188 mask2 = (1 << pos) - 1;
1189 if (pos + size < 32)
1190 mask3 = ~((1 << (pos + size)) - 1);
1193 result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2);
1194 GPR[RT] = EXTEND32 (result);
1197 011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB
1198 "repl.qb r<RD>, <IMM8>"
1201 GPR[RD] = EXTEND32 ((IMM8 << 24) | (IMM8 << 16) | (IMM8 << 8) | IMM8);
1204 011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB
1205 "replv.qb r<RD>, r<RT>"
1208 unsigned32 v1 = GPR[RT];
1210 GPR[RD] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1);
1213 011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH
1214 "repl.ph r<RD>, <IMM10>"
1217 signed32 v1 = IMM10;
1220 GPR[RD] = EXTEND32 ((v1 << 16) | (v1 & 0xffff));
1223 011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH
1224 "replv.ph r<RD>, r<RT>"
1227 unsigned32 v1 = GPR[RT];
1229 GPR[RD] = EXTEND32 ((v1 << 16) | v1);
1232 // op: 0 = EQ, 1 = LT, 2 = LE
1233 :function:::void:do_qb_cmpu:int rs, int rt, int op
1236 unsigned32 v1 = GPR[rs];
1237 unsigned32 v2 = GPR[rt];
1240 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1242 h1 = (unsigned8)(v1 & 0xff);
1243 h2 = (unsigned8)(v2 & 0xff);
1244 mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1247 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1248 else if (op == 1) // LT
1249 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1251 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1255 011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB
1256 "cmpu.eq.qb r<RS>, r<RT>"
1259 do_qb_cmpu (SD_, RS, RT, 0);
1262 011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB
1263 "cmpu.lt.qb r<RS>, r<RT>"
1266 do_qb_cmpu (SD_, RS, RT, 1);
1269 011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB
1270 "cmpu.le.qb r<RS>, r<RT>"
1273 do_qb_cmpu (SD_, RS, RT, 2);
1276 // op: 0 = EQ, 1 = LT, 2 = LE
1277 :function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op
1280 unsigned32 v1 = GPR[rs];
1281 unsigned32 v2 = GPR[rt];
1283 unsigned32 result = 0;
1284 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1286 h1 = (unsigned8)(v1 & 0xff);
1287 h2 = (unsigned8)(v2 & 0xff);
1289 result |= ((h1 == h2) << j);
1290 else if (op == 1) // LT
1291 result |= ((h1 < h2) << j);
1293 result |= ((h1 <= h2) << j);
1295 GPR[rd] = EXTEND32 (result);
1298 011111,5.RS,5.RT,5.RD,00100,010001:SPECIAL3:32::CMPGU.EQ.QB
1299 "cmpgu.eq.qb r<RD>, r<RS>, r<RT>"
1302 do_qb_cmpgu (SD_, RD, RS, RT, 0);
1305 011111,5.RS,5.RT,5.RD,00101,010001:SPECIAL3:32::CMPGU.LT.QB
1306 "cmpgu.lt.qb r<RD>, r<RS>, r<RT>"
1309 do_qb_cmpgu (SD_, RD, RS, RT, 1);
1312 011111,5.RS,5.RT,5.RD,00110,010001:SPECIAL3:32::CMPGU.LE.QB
1313 "cmpgu.le.qb r<RD>, r<RS>, r<RT>"
1316 do_qb_cmpgu (SD_, RD, RS, RT, 2);
1319 // op: 0 = EQ, 1 = LT, 2 = LE
1320 :function:::void:do_ph_cmpu:int rs, int rt, int op
1323 unsigned32 v1 = GPR[rs];
1324 unsigned32 v2 = GPR[rt];
1327 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1329 h1 = (signed16)(v1 & 0xffff);
1330 h2 = (signed16)(v2 & 0xffff);
1331 mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1334 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1335 else if (op == 1) // LT
1336 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1338 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1342 011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH
1343 "cmp.eq.ph r<RS>, r<RT>"
1346 do_ph_cmpu (SD_, RS, RT, 0);
1349 011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH
1350 "cmp.lt.ph r<RS>, r<RT>"
1353 do_ph_cmpu (SD_, RS, RT, 1);
1356 011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH
1357 "cmp.le.ph r<RS>, r<RT>"
1360 do_ph_cmpu (SD_, RS, RT, 2);
1363 011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB
1364 "pick.qb r<RD>, r<RS>, r<RT>"
1368 unsigned32 v1 = GPR[RS];
1369 unsigned32 v2 = GPR[RT];
1371 unsigned32 result = 0;
1372 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1374 h1 = (unsigned8)(v1 & 0xff);
1375 h2 = (unsigned8)(v2 & 0xff);
1376 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
1377 result |= (unsigned32)(h1 << i);
1379 result |= (unsigned32)(h2 << i);
1381 GPR[RD] = EXTEND32 (result);
1384 011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH
1385 "pick.ph r<RD>, r<RS>, r<RT>"
1389 unsigned32 v1 = GPR[RS];
1390 unsigned32 v2 = GPR[RT];
1392 unsigned32 result = 0;
1393 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1395 h1 = (unsigned16)(v1 & 0xffff);
1396 h2 = (unsigned16)(v2 & 0xffff);
1397 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
1398 result |= (unsigned32)(h1 << i);
1400 result |= (unsigned32)(h2 << i);
1402 GPR[RD] = EXTEND32 (result);
1405 011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH
1406 "packrl.ph r<RD>, r<RS>, r<RT>"
1409 unsigned32 v1 = GPR[RS];
1410 unsigned32 v2 = GPR[RT];
1411 GPR[RD] = EXTEND32 ((v1 << 16) + (v2 >> 16));
1414 // op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS
1415 :function:::void:do_w_extr:int rt, int ac, int shift, int op
1418 unsigned32 lo = DSPLO(ac);
1419 unsigned32 hi = DSPHI(ac);
1420 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1421 signed64 result = (signed64)prod;
1423 if (!(prod & 0x8000000000000000LL))
1425 for (i = 62; i >= (shift + 31); i--)
1427 if (prod & ((unsigned64)1 << i))
1429 DSPCR |= DSPCR_OUFLAG7;
1434 if (((prod >> (shift - 1)) & 0xffffffffLL) == 0xffffffffLL)
1436 DSPCR |= DSPCR_OUFLAG7;
1442 for (i = 62; i >= (shift + 31); i--)
1444 if (!(prod & ((unsigned64)1 << i)))
1446 DSPCR |= DSPCR_OUFLAG7;
1452 if (op == 0) // EXTR
1453 result = result >> shift;
1454 else if (op == 1) // EXTR_R
1457 result = ((result >> (shift - 1)) + 1) >> 1;
1459 result = result >> shift;
1464 result = 0x7fffffff;
1465 else if (setcond == 2)
1466 result = 0x80000000;
1470 result = ((result >> (shift - 1)) + 1) >> 1;
1472 result = result >> shift;
1475 GPR[rt] = EXTEND32 (result);
1478 011111,5.SHIFT,5.RT,000,2.AC,00000,111000:SPECIAL3:32::EXTR.W
1479 "extr.w r<RT>, ac<AC>, <SHIFT>"
1482 do_w_extr (SD_, RT, AC, SHIFT, 0);
1485 011111,5.RS,5.RT,000,2.AC,00001,111000:SPECIAL3:32::EXTRV.W
1486 "extrv.w r<RT>, ac<AC>, r<RS>"
1489 unsigned32 shift = GPR[RS] & 0x1f;
1490 do_w_extr (SD_, RT, AC, shift, 0);
1493 011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W
1494 "extr_r.w r<RT>, ac<AC>, <SHIFT>"
1497 do_w_extr (SD_, RT, AC, SHIFT, 1);
1500 011111,5.RS,5.RT,000,2.AC,00101,111000:SPECIAL3:32::EXTRV_R.W
1501 "extrv_r.w r<RT>, ac<AC>, r<RS>"
1504 unsigned32 shift = GPR[RS] & 0x1f;
1505 do_w_extr (SD_, RT, AC, shift, 1);
1508 011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W
1509 "extr_rs.w r<RT>, ac<AC>, <SHIFT>"
1512 do_w_extr (SD_, RT, AC, SHIFT, 2);
1515 011111,5.RS,5.RT,000,2.AC,00111,111000:SPECIAL3:32::EXTRV_RS.W
1516 "extrv_rs.w r<RT>, ac<AC>, r<RS>"
1519 unsigned32 shift = GPR[RS] & 0x1f;
1520 do_w_extr (SD_, RT, AC, shift, 2);
1523 :function:::void:do_h_extr:int rt, int ac, int shift
1526 unsigned32 lo = DSPLO(ac);
1527 unsigned32 hi = DSPHI(ac);
1528 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1529 signed64 result = (signed64)prod;
1530 signed64 value = 0xffffffffffff8000LL;
1532 if (result > 0x7fff)
1535 DSPCR |= DSPCR_OUFLAG7;
1537 else if (result < value)
1540 DSPCR |= DSPCR_OUFLAG7;
1542 GPR[rt] = EXTEND32 (result);
1545 011111,5.SHIFT,5.RT,000,2.AC,01110,111000:SPECIAL3:32::EXTR_S.H
1546 "extr_s.h r<RT>, ac<AC>, <SHIFT>"
1549 do_h_extr (SD_, RT, AC, SHIFT);
1552 011111,5.RS,5.RT,000,2.AC,01111,111000:SPECIAL3:32::EXTRV_S.H
1553 "extrv_s.h r<RT>, ac<AC>, r<RS>"
1556 unsigned32 shift = GPR[RS] & 0x1f;
1557 do_h_extr (SD_, RT, AC, shift);
1560 // op: 0 = EXTP, 1 = EXTPDP
1561 :function:::void:do_extp:int rt, int ac, int size, int op
1563 signed32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1564 unsigned32 lo = DSPLO(ac);
1565 unsigned32 hi = DSPHI(ac);
1566 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1567 unsigned64 result = 0;
1568 if (pos - (size + 1) >= -1)
1570 prod >>= (pos - size);
1571 result = prod & (((unsigned64)1 << (size + 1)) - 1);
1572 DSPCR &= (~DSPCR_EFI_SMASK);
1573 if (op == 1) // EXTPDP
1575 if (pos - (size + 1) >= 0)
1577 DSPCR &= (~DSPCR_POS_SMASK);
1578 DSPCR |= ((pos - (size + 1)) & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1580 else if (pos - (size + 1) == -1)
1582 DSPCR |= DSPCR_POS_SMASK;
1591 GPR[rt] = EXTEND32 (result);
1594 011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP
1595 "extp r<RT>, ac<AC>, <SIZE>"
1598 do_extp (SD_, RT, AC, SIZE, 0);
1601 011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV
1602 "extpv r<RT>, ac<AC>, r<RS>"
1605 unsigned32 size = GPR[RS] & 0x1f;
1606 do_extp (SD_, RT, AC, size, 0);
1609 011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP
1610 "extpdp r<RT>, ac<AC>, <SIZE>"
1613 do_extp (SD_, RT, AC, SIZE, 1);
1616 011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV
1617 "extpdpv r<RT>, ac<AC>, r<RS>"
1620 unsigned32 size = GPR[RS] & 0x1f;
1621 do_extp (SD_, RT, AC, size, 1);
1624 :function:::void:do_shilo:int ac, int shift
1626 unsigned32 lo = DSPLO(ac);
1627 unsigned32 hi = DSPHI(ac);
1628 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1635 DSPLO(ac) = EXTEND32 (prod);
1636 DSPHI(ac) = EXTEND32 (prod >> 32);
1639 011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO
1640 "shilo ac<AC>, <SHIFT6>"
1643 do_shilo (SD_, AC, SHIFT6);
1646 011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV
1647 "shilov ac<AC>, r<RS>"
1650 signed32 shift = GPR[RS] & 0x3f;
1651 do_shilo (SD_, AC, shift);
1654 011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP
1655 "mthlip r<RS>, ac<AC>"
1658 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1659 DSPHI(AC) = DSPLO(AC);
1660 DSPLO(AC) = GPR[RS];
1665 DSPCR &= (~DSPCR_POS_SMASK);
1666 DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1669 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
1670 "wrdsp r<RS>":MASK10 == 1111111111
1671 "wrdsp r<RS>, <MASK10>"
1674 unsigned32 v1 = GPR[RS];
1677 DSPCR &= (~DSPCR_POS_SMASK);
1678 DSPCR |= (v1 & DSPCR_POS_SMASK);
1682 DSPCR &= (~DSPCR_SCOUNT_SMASK);
1683 DSPCR |= (v1 & DSPCR_SCOUNT_SMASK);
1687 DSPCR &= (~DSPCR_CARRY_SMASK);
1688 DSPCR |= (v1 & DSPCR_CARRY_SMASK);
1692 DSPCR &= (~DSPCR_OUFLAG_SMASK);
1693 DSPCR |= (v1 & DSPCR_OUFLAG_SMASK);
1697 DSPCR &= (~DSPCR_CCOND_SMASK);
1698 DSPCR |= (v1 & DSPCR_CCOND_SMASK);
1702 DSPCR &= (~DSPCR_EFI_SMASK);
1703 DSPCR |= (v1 & DSPCR_EFI_SMASK);
1707 011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP
1708 "rddsp r<RD>":MASK10 == 1111111111
1709 "rddsp r<RD>, <MASK10>"
1712 unsigned32 result = 0;
1715 result &= (~DSPCR_POS_SMASK);
1716 result |= (DSPCR & DSPCR_POS_SMASK);
1720 result &= (~DSPCR_SCOUNT_SMASK);
1721 result |= (DSPCR & DSPCR_SCOUNT_SMASK);
1725 result &= (~DSPCR_CARRY_SMASK);
1726 result |= (DSPCR & DSPCR_CARRY_SMASK);
1730 result &= (~DSPCR_OUFLAG_SMASK);
1731 result |= (DSPCR & DSPCR_OUFLAG_SMASK);
1735 result &= (~DSPCR_CCOND_SMASK);
1736 result |= (DSPCR & DSPCR_CCOND_SMASK);
1740 result &= (~DSPCR_EFI_SMASK);
1741 result |= (DSPCR & DSPCR_EFI_SMASK);
1743 GPR[RD] = EXTEND32 (result);
1746 011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX
1747 "lbux r<RD>, r<INDEX>(r<BASE>)"
1750 GPR[RD] = do_load (SD_, AccessLength_BYTE, GPR[BASE], GPR[INDEX]);
1753 011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX
1754 "lhx r<RD>, r<INDEX>(r<BASE>)"
1757 GPR[RD] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], GPR[INDEX]));
1760 011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX
1761 "lwx r<RD>, r<INDEX>(r<BASE>)"
1764 GPR[RD] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX]));
1767 000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32
1771 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1772 address_word offset = EXTEND16 (OFFSET) << 2;
1775 DELAY_SLOT (NIA + offset);