gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / sim / mips / dsp.igen
1 // -*- C -*-
2
3 // Simulator definition for the MIPS DSP ASE.
4 // Copyright (C) 2005-2020 Free Software Foundation, Inc.
5 // Contributed by MIPS Technologies, Inc. Written by Chao-ying Fu.
6 //
7 // This file is part of the MIPS sim
8 //
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.
13 //
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.
18 //
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/>.
21
22
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
26 {
27 int i;
28 signed32 h0 = 0;
29 signed16 h1, h2;
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)
34 {
35 h1 = (signed16)(v1 & 0xffff);
36 h2 = (signed16)(v2 & 0xffff);
37 if (op == 0) // ADD
38 h0 = (signed32)h1 + (signed32)h2;
39 else if (op == 1) // SUB
40 h0 = (signed32)h1 - (signed32)h2;
41 else // MUL
42 h0 = (signed32)h1 * (signed32)h2;
43 if (h0 > (signed32)0x7fff || h0 < (signed32)0xffff8000)
44 {
45 if (op == 0 || op == 1) // ADD, SUB
46 DSPCR |= DSPCR_OUFLAG4;
47 else if (op == 2) // MUL
48 DSPCR |= DSPCR_OUFLAG5;
49 if (sat == 1)
50 {
51 if (h0 > (signed32)0x7fff)
52 h0 = 0x7fff;
53 else
54 h0 = 0x8000;
55 }
56 }
57 result |= ((unsigned32)((unsigned16)h0) << i);
58 }
59 GPR[rd] = EXTEND32 (result);
60 }
61
62 // op: 0 = ADD, 1 = SUB
63 :function:::void:do_w_op:int rd, int rs, int rt, int op
64 {
65 signed64 h0;
66 signed32 h1, h2;
67 unsigned32 v1 = GPR[rs];
68 unsigned32 v2 = GPR[rt];
69 unsigned32 result = 0;
70 h1 = (signed32)v1;
71 h2 = (signed32)v2;
72 if (op == 0) // ADD
73 h0 = (signed64)h1 + (signed64)h2;
74 else // SUB
75 h0 = (signed64)h1 - (signed64)h2;
76 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
77 {
78 DSPCR |= DSPCR_OUFLAG4;
79 if (h0 & 0x100000000LL)
80 h0 = 0x80000000;
81 else
82 h0 = 0x7fffffff;
83 }
84 GPR[rd] = EXTEND32 (h0);
85 }
86
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
90 {
91 int i;
92 unsigned32 h0;
93 unsigned8 h1, h2;
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)
98 {
99 h1 = (unsigned8)(v1 & 0xff);
100 h2 = (unsigned8)(v2 & 0xff);
101 if (op == 0) // ADD
102 h0 = (unsigned32)h1 + (unsigned32)h2;
103 else // SUB
104 h0 = (unsigned32)h1 - (unsigned32)h2;
105 if (h0 & 0x100)
106 {
107 DSPCR |= DSPCR_OUFLAG4;
108 if (sat == 1)
109 {
110 if (op == 0) // ADD
111 h0 = 0xff;
112 else // SUB
113 h0 = 0;
114 }
115 }
116 result |= ((unsigned32)((unsigned8)h0) << i);
117 }
118 GPR[rd] = EXTEND32 (result);
119 }
120
121 // op: 0 = left, 1 = right
122 :function:::void:do_qb_shift:int rd, int rt, int shift, int op
123 {
124 int i, j;
125 unsigned8 h0;
126 unsigned32 v1 = GPR[rt];
127 unsigned32 result = 0;
128 for (i = 0; i < 32; i += 8, v1 >>= 8)
129 {
130 h0 = (unsigned8)(v1 & 0xff);
131 if (op == 0) // left
132 {
133 for (j = 7; j >= 8 - shift; j--)
134 {
135 if (h0 & (1<<j))
136 {
137 DSPCR |= DSPCR_OUFLAG6;
138 break;
139 }
140 }
141 h0 = h0 << shift;
142 }
143 else // right
144 h0 = h0 >> shift;
145 result |= ((unsigned32)h0 << i);
146 }
147 GPR[rd] = EXTEND32 (result);
148 }
149
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
153 {
154 int i, j;
155 signed16 h0;
156 unsigned32 v1 = GPR[rt];
157 unsigned32 result = 0;
158 int setcond;
159 for (i = 0; i < 32; i += 16, v1 >>= 16)
160 {
161 h0 = (signed16)(v1 & 0xffff);
162 if (op == 0) // left
163 {
164 setcond = 0;
165 if (h0 & (1<<15))
166 {
167 for (j = 14; j >= 15 - shift; j--)
168 {
169 if (!(h0 & (1 << j)))
170 {
171 DSPCR |= DSPCR_OUFLAG6;
172 setcond = 1;
173 break;
174 }
175 }
176 }
177 else
178 {
179 for (j = 14; j >= 15 - shift; j--)
180 {
181 if (h0 & (1 << j))
182 {
183 DSPCR |= DSPCR_OUFLAG6;
184 setcond = 2;
185 break;
186 }
187 }
188 }
189 h0 = h0 << shift;
190 if (sat == 1)
191 {
192 if (setcond == 2)
193 h0 = 0x7fff;
194 else if (setcond == 1)
195 h0 = 0x8000;
196 }
197 }
198 else // right
199 {
200 if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1))))
201 h0 = (h0 >> shift) + 1;
202 else
203 h0 = h0 >> shift;
204 }
205
206 result |= ((unsigned32)((unsigned16)h0) << i);
207 }
208 GPR[rd] = EXTEND32 (result);
209 }
210
211 :function:::void:do_w_shll:int rd, int rt, int shift
212 {
213 int i;
214 unsigned32 v1 = GPR[rt];
215 unsigned32 result = 0;
216 int setcond = 0;
217 if (v1 & (1 << 31))
218 {
219 for (i = 30; i >= 31 - shift; i--)
220 {
221 if (!(v1 & (1 << i)))
222 {
223 DSPCR |= DSPCR_OUFLAG6;
224 setcond = 1;
225 break;
226 }
227 }
228 }
229 else
230 {
231 for (i = 30; i >= 31 - shift; i--)
232 {
233 if (v1 & (1 << i))
234 {
235 DSPCR |= DSPCR_OUFLAG6;
236 setcond = 2;
237 break;
238 }
239 }
240 }
241 if (setcond == 2)
242 result = 0x7fffffff;
243 else if (setcond == 1)
244 result = 0x80000000;
245 else
246 result = v1 << shift;
247 GPR[rd] = EXTEND32 (result);
248 }
249
250 :function:::void:do_ph_s_absq:int rd, int rt
251 {
252 int i;
253 signed16 h0;
254 unsigned32 v1 = GPR[rt];
255 unsigned32 result = 0;
256 for (i = 0; i < 32; i += 16, v1 >>= 16)
257 {
258 h0 = (signed16)(v1 & 0xffff);
259 if (h0 == (signed16)0x8000)
260 {
261 DSPCR |= DSPCR_OUFLAG4;
262 h0 = 0x7fff;
263 }
264 else if (h0 & 0x8000)
265 h0 = -h0;
266 result |= ((unsigned32)((unsigned16)h0) << i);
267 }
268 GPR[rd] = EXTEND32 (result);
269 }
270
271 :function:::void:do_w_s_absq:int rd, int rt
272 {
273 unsigned32 v1 = GPR[rt];
274 signed32 h0 = (signed32)v1;
275 if (h0 == (signed32)0x80000000)
276 {
277 DSPCR |= DSPCR_OUFLAG4;
278 h0 = 0x7fffffff;
279 }
280 else if (h0 & 0x80000000)
281 h0 = -h0;
282 GPR[rd] = EXTEND32 (h0);
283 }
284
285 :function:::void:do_qb_s_absq:int rd, int rt
286 {
287 int i;
288 signed8 q0;
289 unsigned32 v1 = GPR[rt];
290 unsigned32 result = 0;
291 for (i = 0; i < 32; i += 8, v1 >>= 8)
292 {
293 q0 = (signed8)(v1 & 0xff);
294 if (q0 == (signed8)0x80)
295 {
296 DSPCR |= DSPCR_OUFLAG4;
297 q0 = 0x7f;
298 }
299 else if (q0 & 0x80)
300 q0 = -q0;
301 result |= ((unsigned32)((unsigned8)q0) << i);
302 }
303 GPR[rd] = EXTEND32 (result);
304 }
305
306 :function:::void:do_addsc:int rd, int rs, int rt
307 {
308 unsigned32 v1 = GPR[rs];
309 unsigned32 v2 = GPR[rt];
310 unsigned64 h0;
311 h0 = (unsigned64)v1 + (unsigned64)v2;
312 if (h0 & 0x100000000LL)
313 DSPCR |= DSPCR_CARRY;
314 GPR[rd] = EXTEND32 (h0);
315 }
316
317 :function:::void:do_addwc:int rd, int rs, int rt
318 {
319 unsigned32 v1 = GPR[rs];
320 unsigned32 v2 = GPR[rt];
321 unsigned64 h0;
322 signed32 h1 = (signed32) v1;
323 signed32 h2 = (signed32) v2;
324 h0 = (signed64)h1 + (signed64)h2
325 + (signed64)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK);
326 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
327 DSPCR |= DSPCR_OUFLAG4;
328 GPR[rd] = EXTEND32 (h0);
329 }
330
331 :function:::void:do_bitrev:int rd, int rt
332 {
333 int i;
334 unsigned32 v1 = GPR[rt];
335 unsigned32 h1 = 0;
336 for (i = 0; i < 16; i++)
337 {
338 if (v1 & (1 << i))
339 h1 |= (1 << (15 - i));
340 }
341 GPR[rd] = EXTEND32 (h1);
342 }
343
344 // op: 0 = EXTPV, 1 = EXTPDPV
345 :function:::void:do_extpv:int rt, int ac, int rs, int op
346 {
347 unsigned32 size = GPR[rs] & 0x1f;
348 do_extp (SD_, rt, ac, size, op);
349 }
350
351 // op: 0 = EXTRV, 1 = EXTRV_R, 2 = EXTRV_RS
352 :function:::void:do_extrv:int rt, int ac, int rs, int op
353 {
354 unsigned32 shift = GPR[rs] & 0x1f;
355 do_w_extr (SD_, rt, ac, shift, op);
356 }
357
358 :function:::void:do_extrv_s_h:int rt, int ac, int rs
359 {
360 unsigned32 shift = GPR[rs] & 0x1f;
361 do_h_extr (SD_, rt, ac, shift);
362 }
363
364 :function:::void:do_insv:int rt, int rs
365 {
366 unsigned32 v1 = GPR[rs];
367 unsigned32 v2 = GPR[rt];
368 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
369 unsigned32 size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK;
370 unsigned32 mask1, mask2, mask3, result;
371 if (size < 32)
372 mask1 = (1 << size) - 1;
373 else
374 mask1 = 0xffffffff;
375 mask2 = (1 << pos) - 1;
376 if (pos + size < 32)
377 mask3 = ~((1 << (pos + size)) - 1);
378 else
379 mask3 = 0;
380 result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2);
381 GPR[rt] = EXTEND32 (result);
382 }
383
384 // op: 0 = NORMAL, 1 = EXTEND16, 2 = EXTEND32
385 :function:::void:do_lxx:int rd, int base, int index, int op
386 {
387 if (op == 0)
388 GPR[rd] = do_load (SD_, AccessLength_BYTE, GPR[base], GPR[index]);
389 else if (op == 1)
390 GPR[rd] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base], GPR[index]));
391 else if (op == 2)
392 GPR[rd] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base], GPR[index]));
393 }
394
395 :function:::void:do_modsub:int rd, int rs, int rt
396 {
397 unsigned32 result = 0;
398 unsigned32 v1 = GPR[rs];
399 unsigned32 v2 = GPR[rt];
400 unsigned32 decr = v2 & 0xff;
401 unsigned32 lastindex = (v2 & 0xffff00) >> 8;
402 if (v1 == 0)
403 result = lastindex;
404 else
405 result = v1 - decr;
406 GPR[rd] = EXTEND32 (result);
407 }
408
409 :function:::void:do_mthlip:int rs, int ac
410 {
411 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
412 DSPHI(ac) = DSPLO(ac);
413 DSPLO(ac) = GPR[rs];
414 if (pos >= 32)
415 Unpredictable ();
416 else
417 pos += 32;
418 DSPCR &= (~DSPCR_POS_SMASK);
419 DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
420 }
421
422 :function:::void:do_mulsaq_s_w_ph:int ac, int rs, int rt
423 {
424 int i;
425 unsigned32 v1 = GPR[rs];
426 unsigned32 v2 = GPR[rt];
427 signed16 h1, h2;
428 signed32 result;
429 unsigned32 lo = DSPLO(ac);
430 unsigned32 hi = DSPHI(ac);
431 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
432 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
433 {
434 h1 = (signed16)(v1 & 0xffff);
435 h2 = (signed16)(v2 & 0xffff);
436 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
437 {
438 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
439 result = (signed32) 0x7fffffff;
440 }
441 else
442 result = ((signed32)h1 * (signed32)h2) << 1;
443
444 if (i == 0)
445 prod -= (signed64) result;
446 else
447 prod += (signed64) result;
448 }
449 DSPLO(ac) = EXTEND32 (prod);
450 DSPHI(ac) = EXTEND32 (prod >> 32);
451 }
452
453 :function:::void:do_ph_packrl:int rd, int rs, int rt
454 {
455
456 unsigned32 v1 = GPR[rs];
457 unsigned32 v2 = GPR[rt];
458 GPR[rd] = EXTEND32 ((v1 << 16) + (v2 >> 16));
459 }
460
461 :function:::void:do_qb_pick:int rd, int rs, int rt
462 {
463 int i, j;
464 unsigned32 v1 = GPR[rs];
465 unsigned32 v2 = GPR[rt];
466 unsigned8 h1, h2;
467 unsigned32 result = 0;
468 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
469 {
470 h1 = (unsigned8)(v1 & 0xff);
471 h2 = (unsigned8)(v2 & 0xff);
472 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
473 result |= (unsigned32)(h1 << i);
474 else
475 result |= (unsigned32)(h2 << i);
476 }
477 GPR[rd] = EXTEND32 (result);
478 }
479
480 :function:::void:do_ph_pick:int rd, int rs, int rt
481 {
482 int i, j;
483 unsigned32 v1 = GPR[rs];
484 unsigned32 v2 = GPR[rt];
485 unsigned16 h1, h2;
486 unsigned32 result = 0;
487 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
488 {
489 h1 = (unsigned16)(v1 & 0xffff);
490 h2 = (unsigned16)(v2 & 0xffff);
491 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j)))
492 result |= (unsigned32)(h1 << i);
493 else
494 result |= (unsigned32)(h2 << i);
495 }
496 GPR[rd] = EXTEND32 (result);
497 }
498
499 // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA
500 :function:::void:do_qb_ph_precequ:int rd, int rt, int op
501 {
502 unsigned32 v1 = GPR[rt];
503 if (op == 0)
504 GPR[rd] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7);
505 else if (op == 1)
506 GPR[rd] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7);
507 else if (op == 2)
508 GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9);
509 else if (op == 3)
510 GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1);
511 }
512
513 // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA
514 :function:::void:do_qb_ph_preceu:int rd, int rt, int op
515 {
516 unsigned32 v1 = GPR[rt];
517 if (op == 0)
518 GPR[rd] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff);
519 else if (op == 1)
520 GPR[rd] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff));
521 else if (op == 2)
522 GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16);
523 else if (op == 3)
524 GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8);
525 }
526
527 // op: 0 = .PHL, 1 = PHR
528 :function:::void:do_w_preceq:int rd, int rt, int op
529 {
530 unsigned32 v1 = GPR[rt];
531 if (op == 0)
532 GPR[rd] = EXTEND32 (v1 & 0xffff0000);
533 else if (op == 1)
534 GPR[rd] = EXTEND32 ((v1 & 0xffff) << 16);
535 }
536
537 :function:::void:do_w_ph_precrq:int rd, int rs, int rt
538 {
539 unsigned32 v1 = GPR[rs];
540 unsigned32 v2 = GPR[rt];
541 unsigned32 tempu = (v1 & 0xffff0000) >> 16;
542 unsigned32 tempv = (v2 & 0xffff0000) >> 16;
543 GPR[rd] = EXTEND32 ((tempu << 16) | tempv);
544 }
545
546 // sat: 0 = PRECRQ.QB.PH, 1 = PRECRQU_S.QB.PH
547 :function:::void:do_ph_qb_precrq:int rd, int rs, int rt, int sat
548 {
549 unsigned32 v1 = GPR[rs];
550 unsigned32 v2 = GPR[rt];
551 unsigned32 tempu = 0, tempv = 0, tempw = 0, tempx = 0;
552 if (sat == 0)
553 {
554 tempu = (v1 & 0xff000000) >> 24;
555 tempv = (v1 & 0xff00) >> 8;
556 tempw = (v2 & 0xff000000) >> 24;
557 tempx = (v2 & 0xff00) >> 8;
558 }
559 else if (sat == 1)
560 {
561 if (v1 & 0x80000000)
562 {
563 DSPCR |= DSPCR_OUFLAG6;
564 tempu = 0;
565 }
566 else if (!(v1 & 0x80000000) && ((v1 >> 16) > (unsigned32)0x7f80))
567 {
568 DSPCR |= DSPCR_OUFLAG6;
569 tempu = 0xff;
570 }
571 else
572 tempu = (v1 & 0x7f800000) >> 23;
573 if (v1 & 0x8000)
574 {
575 DSPCR |= DSPCR_OUFLAG6;
576 tempv = 0;
577 }
578 else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (unsigned32)0x7f80))
579 {
580 DSPCR |= DSPCR_OUFLAG6;
581 tempv = 0xff;
582 }
583 else
584 tempv = (v1 & 0x7f80) >> 7;
585 if (v2 & 0x80000000)
586 {
587 DSPCR |= DSPCR_OUFLAG6;
588 tempw = 0;
589 }
590 else if (!(v2 & 0x80000000) && ((v2 >> 16) > (unsigned32)0x7f80))
591 {
592 DSPCR |= DSPCR_OUFLAG6;
593 tempw = 0xff;
594 }
595 else
596 tempw = (v2 & 0x7f800000) >> 23;
597 if (v2 & 0x8000)
598 {
599 DSPCR |= DSPCR_OUFLAG6;
600 tempx = 0;
601 }
602 else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (unsigned32)0x7f80))
603 {
604 DSPCR |= DSPCR_OUFLAG6;
605 tempx = 0xff;
606 }
607 else
608 tempx = (v2 & 0x7f80) >> 7;
609 }
610 GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
611 }
612
613 :function:::void:do_w_ph_rs_precrq:int rd, int rs, int rt
614 {
615 unsigned32 v1 = GPR[rs];
616 unsigned32 v2 = GPR[rt];
617 signed32 h1 = (signed32)v1;
618 signed32 h2 = (signed32)v2;
619 signed64 temp1 = (signed64)h1 + (signed64)0x8000;
620 signed32 temp2;
621 signed64 temp3 = (signed64)h2 + (signed64)0x8000;
622 signed32 temp4;
623 if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000))
624 {
625 DSPCR |= DSPCR_OUFLAG6;
626 temp2 = 0x7fff;
627 }
628 else
629 temp2 = (signed32)((temp1 & 0xffff0000) >> 16);
630 if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000))
631 {
632 DSPCR |= DSPCR_OUFLAG6;
633 temp4 = 0x7fff;
634 }
635 else
636 temp4 = (signed32)((temp3 & 0xffff0000) >> 16);
637 GPR[rd] = EXTEND32 ((temp2 << 16) | temp4);
638 }
639
640 :function:::void:do_qb_w_raddu:int rd, int rs
641 {
642 int i;
643 unsigned8 h0;
644 unsigned32 v1 = GPR[rs];
645 unsigned32 result = 0;
646 for (i = 0; i < 32; i += 8, v1 >>= 8)
647 {
648 h0 = (unsigned8)(v1 & 0xff);
649 result += (unsigned32)h0;
650 }
651 GPR[rd] = EXTEND32 (result);
652 }
653
654 :function:::void:do_rddsp:int rd, int mask
655 {
656 unsigned32 result = 0;
657 if (mask & 0x1)
658 {
659 result &= (~DSPCR_POS_SMASK);
660 result |= (DSPCR & DSPCR_POS_SMASK);
661 }
662 if (mask & 0x2)
663 {
664 result &= (~DSPCR_SCOUNT_SMASK);
665 result |= (DSPCR & DSPCR_SCOUNT_SMASK);
666 }
667 if (mask & 0x4)
668 {
669 result &= (~DSPCR_CARRY_SMASK);
670 result |= (DSPCR & DSPCR_CARRY_SMASK);
671 }
672 if (mask & 0x8)
673 {
674 result &= (~DSPCR_OUFLAG_SMASK);
675 result |= (DSPCR & DSPCR_OUFLAG_SMASK);
676 }
677 if (mask & 0x10)
678 {
679 result &= (~DSPCR_CCOND_SMASK);
680 result |= (DSPCR & DSPCR_CCOND_SMASK);
681 }
682 if (mask & 0x20)
683 {
684 result &= (~DSPCR_EFI_SMASK);
685 result |= (DSPCR & DSPCR_EFI_SMASK);
686 }
687 GPR[rd] = EXTEND32 (result);
688 }
689
690 // op: 0 = REPL.QB, 1 = REPLV.QB, 2 = REPL.PH, 3 = REPLV.PH
691 :function:::void:do_repl:int rd, int p2, int op
692 {
693 if (op == 0)
694 GPR[rd] = EXTEND32 ((p2 << 24) | (p2 << 16) | (p2 << 8) | p2);
695 else if (op == 1)
696 {
697 unsigned32 v1 = GPR[p2] & 0xff;
698 GPR[rd] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1);
699 }
700 else if (op == 2)
701 {
702 signed32 v1 = p2;
703 if (v1 & 0x200)
704 v1 |= 0xfffffc00;
705 GPR[rd] = EXTEND32 ((v1 << 16) | (v1 & 0xffff));
706 }
707 else if (op == 3)
708 {
709 unsigned32 v1 = GPR[p2];
710 v1 = v1 & 0xffff;
711 GPR[rd] = EXTEND32 ((v1 << 16) | v1);
712 }
713 }
714
715 :function:::void:do_shilov:int ac, int rs
716 {
717 signed32 shift = GPR[rs] & 0x3f;
718 do_shilo (SD_, ac, shift);
719 }
720
721 // op: 0 = SHLLV, 1 = SHRAV
722 // sat: 0 = normal, 1 = saturate/rounding
723 :function:::void:do_ph_shl:int rd, int rt, int rs, int op, int sat
724 {
725 unsigned32 shift = GPR[rs] & 0xf;
726 do_ph_shift (SD_, rd, rt, shift, op, sat);
727 }
728
729 // op: 0 = SHLLV, 1 = SHRLV
730 :function:::void:do_qb_shl:int rd, int rt, int rs, int op
731 {
732 unsigned32 shift = GPR[rs] & 0x7;
733 do_qb_shift (SD_, rd, rt, shift, op);
734 }
735
736 :function:::void:do_w_s_shllv:int rd, int rt, int rs
737 {
738 unsigned32 shift = GPR[rs] & 0x1f;
739 do_w_shll (SD_, rd, rt, shift);
740 }
741
742 :function:::void:do_ph_shrlv:int rd, int rt, int rs
743 {
744 unsigned32 shift = GPR[rs] & 0xf;
745 do_ph_shrl (SD_, rd, rt, shift);
746 }
747
748 :function:::void:do_w_r_shrav:int rd, int rt, int rs
749 {
750 unsigned32 shift = GPR[rs] & 0x1f;
751 do_w_shra (SD_, rd, rt, shift);
752 }
753
754 :function:::void:do_wrdsp:int rs, int mask
755 {
756 unsigned32 v1 = GPR[rs];
757 if (mask & 0x1)
758 {
759 DSPCR &= (~DSPCR_POS_SMASK);
760 DSPCR |= (v1 & DSPCR_POS_SMASK);
761 }
762 if (mask & 0x2)
763 {
764 DSPCR &= (~DSPCR_SCOUNT_SMASK);
765 DSPCR |= (v1 & DSPCR_SCOUNT_SMASK);
766 }
767 if (mask & 0x4)
768 {
769 DSPCR &= (~DSPCR_CARRY_SMASK);
770 DSPCR |= (v1 & DSPCR_CARRY_SMASK);
771 }
772 if (mask & 0x8)
773 {
774 DSPCR &= (~DSPCR_OUFLAG_SMASK);
775 DSPCR |= (v1 & DSPCR_OUFLAG_SMASK);
776 }
777 if (mask & 0x10)
778 {
779 DSPCR &= (~DSPCR_CCOND_SMASK);
780 DSPCR |= (v1 & DSPCR_CCOND_SMASK);
781 }
782 if (mask & 0x20)
783 {
784 DSPCR &= (~DSPCR_EFI_SMASK);
785 DSPCR |= (v1 & DSPCR_EFI_SMASK);
786 }
787 }
788
789 // round: 0 = no rounding, 1 = rounding
790 :function:::void:do_qb_shrav:int rd, int rt, int rs, int round
791 {
792 unsigned32 shift = GPR[rs] & 0x7;
793 do_qb_shra (SD_, rd, rt, shift, round);
794 }
795
796 :function:::void:do_append:int rt, int rs, int sa
797 {
798 unsigned32 v0 = GPR[rs];
799 unsigned32 v1 = GPR[rt];
800 unsigned32 result;
801 unsigned32 mask = (1 << sa) - 1;
802 result = (v1 << sa) | (v0 & mask);
803 GPR[rt] = EXTEND32 (result);
804 }
805
806 :function:::void:do_balign:int rt, int rs, int bp
807 {
808 unsigned32 v0 = GPR[rs];
809 unsigned32 v1 = GPR[rt];
810 unsigned32 result;
811 if (bp == 0)
812 result = v1;
813 else
814 result = (v1 << 8 * bp) | (v0 >> 8 * (4 - bp));
815 GPR[rt] = EXTEND32 (result);
816 }
817
818 :function:::void:do_ph_w_mulsa:int ac, int rs, int rt
819 {
820 int i;
821 unsigned32 v1 = GPR[rs];
822 unsigned32 v2 = GPR[rt];
823 signed16 h1, h2;
824 signed32 result;
825 unsigned32 lo = DSPLO(ac);
826 unsigned32 hi = DSPHI(ac);
827 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
828 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
829 {
830 h1 = (signed16)(v1 & 0xffff);
831 h2 = (signed16)(v2 & 0xffff);
832 result = (signed32)h1 * (signed32)h2;
833
834 if (i == 0)
835 prod -= (signed64) result;
836 else
837 prod += (signed64) result;
838 }
839 DSPLO(ac) = EXTEND32 (prod);
840 DSPHI(ac) = EXTEND32 (prod >> 32);
841 }
842
843 :function:::void:do_ph_qb_precr:int rd, int rs, int rt
844 {
845 unsigned32 v1 = GPR[rs];
846 unsigned32 v2 = GPR[rt];
847 unsigned32 tempu = (v1 & 0xff0000) >> 16;
848 unsigned32 tempv = (v1 & 0xff);
849 unsigned32 tempw = (v2 & 0xff0000) >> 16;
850 unsigned32 tempx = (v2 & 0xff);
851 GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx);
852 }
853
854 :function:::void:do_prepend:int rt, int rs, int sa
855 {
856 unsigned32 v0 = GPR[rs];
857 unsigned32 v1 = GPR[rt];
858 unsigned32 result;
859 if (sa == 0)
860 result = v1;
861 else
862 result = (v0 << (32 - sa)) | (v1 >> sa);
863 GPR[rt] = EXTEND32 (result);
864 }
865
866 :function:::void:do_w_shra:int rd, int rt, int shift
867 {
868 unsigned32 result = GPR[rt];
869 signed32 h0 = (signed32)result;
870 if (shift != 0 && (h0 & (1 << (shift-1))))
871 h0 = (h0 >> shift) + 1;
872 else
873 h0 = h0 >> shift;
874 GPR[rd] = EXTEND32 (h0);
875 }
876
877 011111,5.RS,5.RT,5.RD,01010,010000:SPECIAL3:32::ADDQ.PH
878 "addq.ph r<RD>, r<RS>, r<RT>"
879 *dsp:
880 {
881 do_ph_op (SD_, RD, RS, RT, 0, 0);
882 }
883
884 011111,5.RS,5.RT,5.RD,01110,010000:SPECIAL3:32::ADDQ_S.PH
885 "addq_s.ph r<RD>, r<RS>, r<RT>"
886 *dsp:
887 {
888 do_ph_op (SD_, RD, RS, RT, 0, 1);
889 }
890
891 011111,5.RS,5.RT,5.RD,10110,010000:SPECIAL3:32::ADDQ_S.W
892 "addq_s.w r<RD>, r<RS>, r<RT>"
893 *dsp:
894 {
895 do_w_op (SD_, RD, RS, RT, 0);
896 }
897
898 011111,5.RS,5.RT,5.RD,00000,010000:SPECIAL3:32::ADDU.QB
899 "addu.qb r<RD>, r<RS>, r<RT>"
900 *dsp:
901 {
902 do_qb_op (SD_, RD, RS, RT, 0, 0);
903 }
904
905 011111,5.RS,5.RT,5.RD,00100,010000:SPECIAL3:32::ADDU_S.QB
906 "addu_s.qb r<RD>, r<RS>, r<RT>"
907 *dsp:
908 {
909 do_qb_op (SD_, RD, RS, RT, 0, 1);
910 }
911
912 011111,5.RS,5.RT,5.RD,01011,010000:SPECIAL3:32::SUBQ.PH
913 "subq.ph r<RD>, r<RS>, r<RT>"
914 *dsp:
915 {
916 do_ph_op (SD_, RD, RS, RT, 1, 0);
917 }
918
919 011111,5.RS,5.RT,5.RD,01111,010000:SPECIAL3:32::SUBQ_S.PH
920 "subq_s.ph r<RD>, r<RS>, r<RT>"
921 *dsp:
922 {
923 do_ph_op (SD_, RD, RS, RT, 1, 1);
924 }
925
926 011111,5.RS,5.RT,5.RD,10111,010000:SPECIAL3:32::SUBQ_S.W
927 "subq_s.w r<RD>, r<RS>, r<RT>"
928 *dsp:
929 {
930 do_w_op (SD_, RD, RS, RT, 1);
931 }
932
933 011111,5.RS,5.RT,5.RD,00001,010000:SPECIAL3:32::SUBU.QB
934 "subu.qb r<RD>, r<RS>, r<RT>"
935 *dsp:
936 {
937 do_qb_op (SD_, RD, RS, RT, 1, 0);
938 }
939
940 011111,5.RS,5.RT,5.RD,00101,010000:SPECIAL3:32::SUBU_S.QB
941 "subu_s.qb r<RD>, r<RS>, r<RT>"
942 *dsp:
943 {
944 do_qb_op (SD_, RD, RS, RT, 1, 1);
945 }
946
947 011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC
948 "addsc r<RD>, r<RS>, r<RT>"
949 *dsp:
950 {
951 do_addsc (SD_, RD, RS, RT);
952 }
953
954 011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC
955 "addwc r<RD>, r<RS>, r<RT>"
956 *dsp:
957 {
958 do_addwc (SD_, RD, RS, RT);
959 }
960
961 011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB
962 "modsub r<RD>, r<RS>, r<RT>"
963 *dsp:
964 {
965 do_modsub (SD_, RD, RS, RT);
966 }
967
968 011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB
969 "raddu.w.qb r<RD>, r<RS>"
970 *dsp:
971 {
972 do_qb_w_raddu (SD_, RD, RS);
973 }
974
975 011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH
976 "absq_s.ph r<RD>, r<RT>"
977 *dsp:
978 {
979 do_ph_s_absq (SD_, RD, RT);
980 }
981
982 011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W
983 "absq_s.w r<RD>, r<RT>"
984 *dsp:
985 {
986 do_w_s_absq (SD_, RD, RT);
987 }
988
989 011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH
990 "precrq.qb.ph r<RD>, r<RS>, r<RT>"
991 *dsp:
992 {
993 do_ph_qb_precrq (SD_, RD, RS, RT, 0);
994 }
995
996 011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W
997 "precrq.ph.w r<RD>, r<RS>, r<RT>"
998 *dsp:
999 {
1000 do_w_ph_precrq (SD_, RD, RS, RT);
1001 }
1002
1003 011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W
1004 "precrq_rs.ph.w r<RD>, r<RS>, r<RT>"
1005 *dsp:
1006 {
1007 do_w_ph_rs_precrq (SD_, RD, RS, RT);
1008 }
1009
1010 011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH
1011 "precrqu_s.qb.ph r<RD>, r<RS>, r<RT>"
1012 *dsp:
1013 {
1014 do_ph_qb_precrq (SD_, RD, RS, RT, 1);
1015 }
1016
1017 011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL
1018 "preceq.w.phl r<RD>, r<RT>"
1019 *dsp:
1020 {
1021 do_w_preceq (SD_, RD, RT, 0);
1022 }
1023
1024 011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR
1025 "preceq.w.phr r<RD>, r<RT>"
1026 *dsp:
1027 {
1028 do_w_preceq (SD_, RD, RT, 1);
1029 }
1030
1031 011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL
1032 "precequ.ph.qbl r<RD>, r<RT>"
1033 *dsp:
1034 {
1035 do_qb_ph_precequ (SD_, RD, RT, 2);
1036 }
1037
1038 011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR
1039 "precequ.ph.qbr r<RD>, r<RT>"
1040 *dsp:
1041 {
1042 do_qb_ph_precequ (SD_, RD, RT, 0);
1043 }
1044
1045 011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA
1046 "precequ.ph.qbla r<RD>, r<RT>"
1047 *dsp:
1048 {
1049 do_qb_ph_precequ (SD_, RD, RT, 3);
1050 }
1051
1052 011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA
1053 "precequ.ph.qbra r<RD>, r<RT>"
1054 *dsp:
1055 {
1056 do_qb_ph_precequ (SD_, RD, RT, 1);
1057 }
1058
1059 011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL
1060 "preceu.ph.qbl r<RD>, r<RT>"
1061 *dsp:
1062 {
1063 do_qb_ph_preceu (SD_, RD, RT, 2);
1064 }
1065
1066 011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR
1067 "preceu.ph.qbr r<RD>, r<RT>"
1068 *dsp:
1069 {
1070 do_qb_ph_preceu (SD_, RD, RT, 0);
1071 }
1072
1073 011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA
1074 "preceu.ph.qbla r<RD>, r<RT>"
1075 *dsp:
1076 {
1077 do_qb_ph_preceu (SD_, RD, RT, 3);
1078 }
1079
1080 011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA
1081 "preceu.ph.qbra r<RD>, r<RT>"
1082 *dsp:
1083 {
1084 do_qb_ph_preceu (SD_, RD, RT, 1);
1085 }
1086
1087 011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB
1088 "shll.qb r<RD>, r<RT>, <SHIFT3>"
1089 *dsp:
1090 {
1091 do_qb_shift (SD_, RD, RT, SHIFT3, 0);
1092 }
1093
1094 011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB
1095 "shllv.qb r<RD>, r<RT>, r<RS>"
1096 *dsp:
1097 {
1098 do_qb_shl (SD_, RD, RT, RS, 0);
1099 }
1100
1101 011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH
1102 "shll.ph r<RD>, r<RT>, <SHIFT4>"
1103 *dsp:
1104 {
1105 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0);
1106 }
1107
1108 011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH
1109 "shllv.ph r<RD>, r<RT>, r<RS>"
1110 *dsp:
1111 {
1112 do_ph_shl (SD_, RD, RT, RS, 0, 0);
1113 }
1114
1115 011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH
1116 "shll_s.ph r<RD>, r<RT>, <SHIFT4>"
1117 *dsp:
1118 {
1119 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1);
1120 }
1121
1122 011111,5.RS,5.RT,5.RD,01110,010011:SPECIAL3:32::SHLLV_S.PH
1123 "shllv_s.ph r<RD>, r<RT>, r<RS>"
1124 *dsp:
1125 {
1126 do_ph_shl (SD_, RD, RT, RS, 0, 1);
1127 }
1128
1129 011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W
1130 "shll_s.w r<RD>, r<RT>, <SHIFT5>"
1131 *dsp:
1132 {
1133 do_w_shll (SD_, RD, RT, SHIFT5);
1134 }
1135
1136 011111,5.RS,5.RT,5.RD,10110,010011:SPECIAL3:32::SHLLV_S.W
1137 "shllv_s.w r<RD>, r<RT>, r<RS>"
1138 *dsp:
1139 {
1140 do_w_s_shllv (SD_, RD, RT, RS);
1141 }
1142
1143 011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB
1144 "shrl.qb r<RD>, r<RT>, <SHIFT3>"
1145 *dsp:
1146 {
1147 do_qb_shift (SD_, RD, RT, SHIFT3, 1);
1148 }
1149
1150 011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB
1151 "shrlv.qb r<RD>, r<RT>, r<RS>"
1152 *dsp:
1153 {
1154 do_qb_shl (SD_, RD, RT, RS, 1);
1155 }
1156
1157 011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH
1158 "shra.ph r<RD>, r<RT>, <SHIFT4>"
1159 *dsp:
1160 {
1161 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0);
1162 }
1163
1164 011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH
1165 "shrav.ph r<RD>, r<RT>, r<RS>"
1166 *dsp:
1167 {
1168 do_ph_shl (SD_, RD, RT, RS, 1, 0);
1169 }
1170
1171 011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH
1172 "shra_r.ph r<RD>, r<RT>, <SHIFT4>"
1173 *dsp:
1174 {
1175 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1);
1176 }
1177
1178 011111,5.RS,5.RT,5.RD,01111,010011:SPECIAL3:32::SHRAV_R.PH
1179 "shrav_r.ph r<RD>, r<RT>, r<RS>"
1180 *dsp:
1181 {
1182 do_ph_shl (SD_, RD, RT, RS, 1, 1);
1183 }
1184
1185 011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W
1186 "shra_r.w r<RD>, r<RT>, <SHIFT5>"
1187 *dsp:
1188 {
1189 do_w_shra (SD_, RD, RT, SHIFT5);
1190 }
1191
1192 011111,5.RS,5.RT,5.RD,10111,010011:SPECIAL3:32::SHRAV_R.W
1193 "shrav_r.w r<RD>, r<RT>, r<RS>"
1194 *dsp:
1195 {
1196 do_w_r_shrav (SD_, RD, RT, RS);
1197 }
1198
1199 // loc: 0 = qhl, 1 = qhr
1200 :function:::void:do_qb_muleu:int rd, int rs, int rt, int loc
1201 {
1202 int i;
1203 unsigned32 result = 0;
1204 unsigned32 v1 = GPR[rs];
1205 unsigned32 v2 = GPR[rt];
1206 unsigned16 h1, h2;
1207 unsigned32 prod;
1208 if (loc == 0)
1209 v1 >>= 16;
1210 for (i = 0; i < 32; i += 16, v1 >>= 8, v2 >>= 16)
1211 {
1212 h1 = (unsigned16)(v1 & 0xff);
1213 h2 = (unsigned16)(v2 & 0xffff);
1214 prod = (unsigned32)h1 * (unsigned32)h2;
1215 if (prod > 0xffff)
1216 {
1217 DSPCR |= DSPCR_OUFLAG5;
1218 prod = 0xffff;
1219 }
1220 result |= ((unsigned32)prod << i);
1221 }
1222 GPR[rd] = EXTEND32 (result);
1223 }
1224
1225 011111,5.RS,5.RT,5.RD,00110,010000:SPECIAL3:32::MULEU_S.PH.QBL
1226 "muleu_s.ph.qbl r<RD>, r<RS>, r<RT>"
1227 *dsp:
1228 {
1229 do_qb_muleu (SD_, RD, RS, RT, 0);
1230 }
1231
1232 011111,5.RS,5.RT,5.RD,00111,010000:SPECIAL3:32::MULEU_S.PH.QBR
1233 "muleu_s.ph.qbr r<RD>, r<RS>, r<RT>"
1234 *dsp:
1235 {
1236 do_qb_muleu (SD_, RD, RS, RT, 1);
1237 }
1238
1239 // round: 0 = no rounding, 1 = rounding
1240 :function:::void:do_ph_mulq:int rd, int rs, int rt, int round
1241 {
1242 int i;
1243 unsigned32 result = 0;
1244 unsigned32 v1 = GPR[rs];
1245 unsigned32 v2 = GPR[rt];
1246 signed16 h1, h2;
1247 signed32 prod;
1248 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
1249 {
1250 h1 = (signed16)(v1 & 0xffff);
1251 h2 = (signed16)(v2 & 0xffff);
1252 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
1253 {
1254 DSPCR |= DSPCR_OUFLAG5;
1255 prod = 0x7fffffff;
1256 }
1257 else
1258 {
1259 prod = ((signed32)h1 * (signed32)h2) << 1;
1260 if (round == 1)
1261 prod += (signed32)0x8000;
1262 }
1263 result |= (((unsigned32)prod >> 16) << i);
1264 }
1265 GPR[rd] = EXTEND32 (result);
1266 }
1267
1268 011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH
1269 "mulq_rs.ph r<RD>, r<RS>, r<RT>"
1270 *dsp:
1271 {
1272 do_ph_mulq (SD_, RD, RS, RT, 1);
1273 }
1274
1275 // loc: 0 = phl, 1 = phr
1276 :function:::void:do_ph_muleq:int rd, int rs, int rt, int loc
1277 {
1278 unsigned32 v1 = GPR[rs];
1279 unsigned32 v2 = GPR[rt];
1280 signed16 h1, h2;
1281 signed32 prod;
1282 if (loc == 0)
1283 {
1284 h1 = (signed16)(v1 >> 16);
1285 h2 = (signed16)(v2 >> 16);
1286 }
1287 else
1288 {
1289 h1 = (signed16)(v1 & 0xffff);
1290 h2 = (signed16)(v2 & 0xffff);
1291 }
1292 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
1293 {
1294 DSPCR |= DSPCR_OUFLAG5;
1295 prod = 0x7fffffff;
1296 }
1297 else
1298 prod = ((signed32)h1 * (signed32)h2) << 1;
1299 GPR[rd] = EXTEND32 (prod);
1300 }
1301
1302 011111,5.RS,5.RT,5.RD,11100,010000:SPECIAL3:32::MULEQ_S.W.PHL
1303 "muleq_s.w.phl r<RD>, r<RS>, r<RT>"
1304 *dsp:
1305 {
1306 do_ph_muleq (SD_, RD, RS, RT, 0);
1307 }
1308
1309 011111,5.RS,5.RT,5.RD,11101,010000:SPECIAL3:32::MULEQ_S.W.PHR
1310 "muleq_s.w.phr r<RD>, r<RS>, r<RT>"
1311 *dsp:
1312 {
1313 do_ph_muleq (SD_, RD, RS, RT, 1);
1314 }
1315
1316 // op: 0 = DPAU 1 = DPSU
1317 // loc: 0 = qbl, 1 = qbr
1318 :function:::void:do_qb_dot_product:int ac, int rs, int rt, int op, int loc
1319 {
1320 int i;
1321 unsigned32 v1 = GPR[rs];
1322 unsigned32 v2 = GPR[rt];
1323 unsigned8 h1, h2;
1324 unsigned32 lo = DSPLO(ac);
1325 unsigned32 hi = DSPHI(ac);
1326 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1327 if (loc == 0)
1328 {
1329 v1 >>= 16;
1330 v2 >>= 16;
1331 }
1332 for (i = 0; i < 16; i += 8, v1 >>= 8, v2 >>= 8)
1333 {
1334 h1 = (unsigned8)(v1 & 0xff);
1335 h2 = (unsigned8)(v2 & 0xff);
1336 if (op == 0) // DPAU
1337 prod += (unsigned64)h1 * (unsigned64)h2;
1338 else // DPSU
1339 prod -= (unsigned64)h1 * (unsigned64)h2;
1340 }
1341 DSPLO(ac) = EXTEND32 (prod);
1342 DSPHI(ac) = EXTEND32 (prod >> 32);
1343 }
1344
1345 011111,5.RS,5.RT,000,2.AC,00011,110000:SPECIAL3:32::DPAU.H.QBL
1346 "dpau.h.qbl ac<AC>, r<RS>, r<RT>"
1347 *dsp:
1348 {
1349 do_qb_dot_product (SD_, AC, RS, RT, 0, 0);
1350 }
1351
1352 011111,5.RS,5.RT,000,2.AC,00111,110000:SPECIAL3:32::DPAU.H.QBR
1353 "dpau.h.qbr ac<AC>, r<RS>, r<RT>"
1354 *dsp:
1355 {
1356 do_qb_dot_product (SD_, AC, RS, RT, 0, 1);
1357 }
1358
1359 011111,5.RS,5.RT,000,2.AC,01011,110000:SPECIAL3:32::DPSU.H.QBL
1360 "dpsu.h.qbl ac<AC>, r<RS>, r<RT>"
1361 *dsp:
1362 {
1363 do_qb_dot_product (SD_, AC, RS, RT, 1, 0);
1364 }
1365
1366 011111,5.RS,5.RT,000,2.AC,01111,110000:SPECIAL3:32::DPSU.H.QBR
1367 "dpsu.h.qbr ac<AC>, r<RS>, r<RT>"
1368 *dsp:
1369 {
1370 do_qb_dot_product (SD_, AC, RS, RT, 1, 1);
1371 }
1372
1373 // op: 0 = DPAQ 1 = DPSQ
1374 :function:::void:do_ph_dot_product:int ac, int rs, int rt, int op
1375 {
1376 int i;
1377 unsigned32 v1 = GPR[rs];
1378 unsigned32 v2 = GPR[rt];
1379 signed16 h1, h2;
1380 signed32 result;
1381 unsigned32 lo = DSPLO(ac);
1382 unsigned32 hi = DSPHI(ac);
1383 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
1384 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16)
1385 {
1386 h1 = (signed16)(v1 & 0xffff);
1387 h2 = (signed16)(v2 & 0xffff);
1388 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
1389 {
1390 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1391 result = (signed32)0x7fffffff;
1392 }
1393 else
1394 result = ((signed32)h1 * (signed32)h2) << 1;
1395
1396 if (op == 0) // DPAQ
1397 prod += (signed64)result;
1398 else // DPSQ
1399 prod -= (signed64)result;
1400 }
1401 DSPLO(ac) = EXTEND32 (prod);
1402 DSPHI(ac) = EXTEND32 (prod >> 32);
1403 }
1404
1405 011111,5.RS,5.RT,000,2.AC,00100,110000:SPECIAL3:32::DPAQ_S.W.PH
1406 "dpaq_s.w.ph ac<AC>, r<RS>, r<RT>"
1407 *dsp:
1408 {
1409 do_ph_dot_product (SD_, AC, RS, RT, 0);
1410 }
1411
1412 011111,5.RS,5.RT,000,2.AC,00101,110000:SPECIAL3:32::DPSQ_S.W.PH
1413 "dpsq_s.w.ph ac<AC>, r<RS>, r<RT>"
1414 *dsp:
1415 {
1416 do_ph_dot_product (SD_, AC, RS, RT, 1);
1417 }
1418
1419 011111,5.RS,5.RT,000,2.AC,00110,110000:SPECIAL3:32::MULSAQ_S.W.PH
1420 "mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>"
1421 *dsp:
1422 {
1423 do_mulsaq_s_w_ph (SD_, AC, RS, RT);
1424 }
1425
1426 // op: 0 = DPAQ 1 = DPSQ
1427 :function:::void:do_w_dot_product:int ac, int rs, int rt, int op
1428 {
1429 unsigned32 v1 = GPR[rs];
1430 unsigned32 v2 = GPR[rt];
1431 signed32 h1, h2;
1432 signed64 result;
1433 unsigned32 lo = DSPLO(ac);
1434 unsigned32 hi = DSPHI(ac);
1435 unsigned32 resultlo;
1436 unsigned32 resulthi;
1437 unsigned32 carry;
1438 unsigned64 temp1;
1439 signed64 temp2;
1440 h1 = (signed32) v1;
1441 h2 = (signed32) v2;
1442 if (h1 == 0x80000000 && h2 == 0x80000000)
1443 {
1444 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1445 result = (signed64) 0x7fffffffffffffffLL;
1446 }
1447 else
1448 result = ((signed64)h1 * (signed64)h2) << 1;
1449 resultlo = (unsigned32)(result);
1450 resulthi = (unsigned32)(result >> 32);
1451 if (op ==0) // DPAQ
1452 {
1453 temp1 = (unsigned64)lo + (unsigned64)resultlo;
1454 carry = (unsigned32)((temp1 >> 32) & 1);
1455 temp2 = (signed64)((signed32)hi) + (signed64)((signed32)resulthi) +
1456 (signed64)((signed32)carry);
1457 }
1458 else // DPSQ
1459 {
1460 temp1 = (unsigned64)lo - (unsigned64)resultlo;
1461 carry = (unsigned32)((temp1 >> 32) & 1);
1462 temp2 = (signed64)((signed32)hi) - (signed64)((signed32)resulthi) -
1463 (signed64)((signed32)carry);
1464 }
1465 if (((temp2 & 0x100000000LL) >> 1) != (temp2 & 0x80000000LL))
1466 {
1467 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1468 if (temp2 & 0x100000000LL)
1469 {
1470 DSPLO(ac) = EXTEND32 (0x00000000);
1471 DSPHI(ac) = EXTEND32 (0x80000000);
1472 }
1473 else
1474 {
1475 DSPLO(ac) = EXTEND32 (0xffffffff);
1476 DSPHI(ac) = EXTEND32 (0x7fffffff);
1477 }
1478 }
1479 else
1480 {
1481 DSPLO(ac) = EXTEND32 (temp1);
1482 DSPHI(ac) = EXTEND32 (temp2);
1483 }
1484 }
1485
1486 011111,5.RS,5.RT,000,2.AC,01100,110000:SPECIAL3:32::DPAQ_SA.L.W
1487 "dpaq_sa.l.w ac<AC>, r<RS>, r<RT>"
1488 *dsp:
1489 {
1490 do_w_dot_product (SD_, AC, RS, RT, 0);
1491 }
1492
1493 011111,5.RS,5.RT,000,2.AC,01101,110000:SPECIAL3:32::DPSQ_SA.L.W
1494 "dpsq_sa.l.w ac<AC>, r<RS>, r<RT>"
1495 *dsp:
1496 {
1497 do_w_dot_product (SD_, AC, RS, RT, 1);
1498 }
1499
1500 // op: 0 = MAQ_S 1 = MAQ_SA
1501 // loc: 0 = phl, 1 = phr
1502 :function:::void:do_ph_maq:int ac, int rs, int rt, int op, int loc
1503 {
1504 int i;
1505 unsigned32 v1 = GPR[rs];
1506 unsigned32 v2 = GPR[rt];
1507 signed16 h1, h2;
1508 signed32 result;
1509 unsigned32 lo = DSPLO(ac);
1510 unsigned32 hi = DSPHI(ac);
1511 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo);
1512 if (loc == 0)
1513 {
1514 h1 = (signed16)(v1 >> 16);
1515 h2 = (signed16)(v2 >> 16);
1516 }
1517 else
1518 {
1519 h1 = (signed16)(v1 & 0xffff);
1520 h2 = (signed16)(v2 & 0xffff);
1521 }
1522 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000)
1523 {
1524 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1525 result = (signed32)0x7fffffff;
1526 }
1527 else
1528 result = ((signed32)h1 * (signed32)h2) << 1;
1529 prod += (signed64)result;
1530 if (op == 1) // MAQ_SA
1531 {
1532 if (prod & 0x8000000000000000LL)
1533 {
1534 for (i = 62; i >= 31; i--)
1535 {
1536 if (!(prod & ((signed64)1 << i)))
1537 {
1538 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1539 prod = 0xffffffff80000000LL;
1540 break;
1541 }
1542 }
1543 }
1544 else
1545 {
1546 for (i = 62; i >= 31; i--)
1547 {
1548 if (prod & ((signed64)1 << i))
1549 {
1550 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac));
1551 prod = 0x7fffffff;
1552 break;
1553 }
1554 }
1555 }
1556 }
1557 DSPLO(ac) = EXTEND32 (prod);
1558 DSPHI(ac) = EXTEND32 (prod >> 32);
1559 }
1560
1561 011111,5.RS,5.RT,000,2.AC,10100,110000:SPECIAL3:32::MAQ_S.W.PHL
1562 "maq_s.w.phl ac<AC>, r<RS>, r<RT>"
1563 *dsp:
1564 {
1565 do_ph_maq (SD_, AC, RS, RT, 0, 0);
1566 }
1567
1568 011111,5.RS,5.RT,000,2.AC,10110,110000:SPECIAL3:32::MAQ_S.W.PHR
1569 "maq_s.w.phr ac<AC>, r<RS>, r<RT>"
1570 *dsp:
1571 {
1572 do_ph_maq (SD_, AC, RS, RT, 0, 1);
1573 }
1574
1575 011111,5.RS,5.RT,000,2.AC,10000,110000:SPECIAL3:32::MAQ_SA.W.PHL
1576 "maq_sa.w.phl ac<AC>, r<RS>, r<RT>"
1577 *dsp:
1578 {
1579 do_ph_maq (SD_, AC, RS, RT, 1, 0);
1580 }
1581
1582 011111,5.RS,5.RT,000,2.AC,10010,110000:SPECIAL3:32::MAQ_SA.W.PHR
1583 "maq_sa.w.phr ac<AC>, r<RS>, r<RT>"
1584 *dsp:
1585 {
1586 do_ph_maq (SD_, AC, RS, RT, 1, 1);
1587 }
1588
1589 011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV
1590 "bitrev r<RD>, r<RT>"
1591 *dsp:
1592 {
1593 do_bitrev (SD_, RD, RT);
1594 }
1595
1596 011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV
1597 "insv r<RT>, r<RS>"
1598 *dsp:
1599 {
1600 do_insv (SD_, RT, RS);
1601 }
1602
1603 011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB
1604 "repl.qb r<RD>, <IMM8>"
1605 *dsp:
1606 {
1607 do_repl (SD_, RD, IMM8, 0);
1608 }
1609
1610 011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB
1611 "replv.qb r<RD>, r<RT>"
1612 *dsp:
1613 {
1614 do_repl (SD_, RD, RT, 1);
1615 }
1616
1617 011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH
1618 "repl.ph r<RD>, <IMM10>"
1619 *dsp:
1620 {
1621 do_repl (SD_, RD, IMM10, 2);
1622 }
1623
1624 011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH
1625 "replv.ph r<RD>, r<RT>"
1626 *dsp:
1627 {
1628 do_repl (SD_, RD, RT, 3);
1629 }
1630
1631 // op: 0 = EQ, 1 = LT, 2 = LE
1632 :function:::void:do_qb_cmpu:int rs, int rt, int op
1633 {
1634 int i, j;
1635 unsigned32 v1 = GPR[rs];
1636 unsigned32 v2 = GPR[rt];
1637 unsigned8 h1, h2;
1638 unsigned32 mask;
1639 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1640 {
1641 h1 = (unsigned8)(v1 & 0xff);
1642 h2 = (unsigned8)(v2 & 0xff);
1643 mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1644 DSPCR &= mask;
1645 if (op == 0) // EQ
1646 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1647 else if (op == 1) // LT
1648 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1649 else // LE
1650 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1651 }
1652 }
1653
1654 011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB
1655 "cmpu.eq.qb r<RS>, r<RT>"
1656 *dsp:
1657 {
1658 do_qb_cmpu (SD_, RS, RT, 0);
1659 }
1660
1661 011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB
1662 "cmpu.lt.qb r<RS>, r<RT>"
1663 *dsp:
1664 {
1665 do_qb_cmpu (SD_, RS, RT, 1);
1666 }
1667
1668 011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB
1669 "cmpu.le.qb r<RS>, r<RT>"
1670 *dsp:
1671 {
1672 do_qb_cmpu (SD_, RS, RT, 2);
1673 }
1674
1675 // op: 0 = EQ, 1 = LT, 2 = LE
1676 :function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op
1677 {
1678 int i, j;
1679 unsigned32 v1 = GPR[rs];
1680 unsigned32 v2 = GPR[rt];
1681 unsigned8 h1, h2;
1682 unsigned32 result = 0;
1683 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8)
1684 {
1685 h1 = (unsigned8)(v1 & 0xff);
1686 h2 = (unsigned8)(v2 & 0xff);
1687 if (op == 0) // EQ
1688 result |= ((h1 == h2) << j);
1689 else if (op == 1) // LT
1690 result |= ((h1 < h2) << j);
1691 else // LE
1692 result |= ((h1 <= h2) << j);
1693 }
1694 GPR[rd] = EXTEND32 (result);
1695 }
1696
1697 011111,5.RS,5.RT,5.RD,00100,010001:SPECIAL3:32::CMPGU.EQ.QB
1698 "cmpgu.eq.qb r<RD>, r<RS>, r<RT>"
1699 *dsp:
1700 {
1701 do_qb_cmpgu (SD_, RD, RS, RT, 0);
1702 }
1703
1704 011111,5.RS,5.RT,5.RD,00101,010001:SPECIAL3:32::CMPGU.LT.QB
1705 "cmpgu.lt.qb r<RD>, r<RS>, r<RT>"
1706 *dsp:
1707 {
1708 do_qb_cmpgu (SD_, RD, RS, RT, 1);
1709 }
1710
1711 011111,5.RS,5.RT,5.RD,00110,010001:SPECIAL3:32::CMPGU.LE.QB
1712 "cmpgu.le.qb r<RD>, r<RS>, r<RT>"
1713 *dsp:
1714 {
1715 do_qb_cmpgu (SD_, RD, RS, RT, 2);
1716 }
1717
1718 // op: 0 = EQ, 1 = LT, 2 = LE
1719 :function:::void:do_ph_cmpu:int rs, int rt, int op
1720 {
1721 int i, j;
1722 unsigned32 v1 = GPR[rs];
1723 unsigned32 v2 = GPR[rt];
1724 signed16 h1, h2;
1725 unsigned32 mask;
1726 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16)
1727 {
1728 h1 = (signed16)(v1 & 0xffff);
1729 h2 = (signed16)(v2 & 0xffff);
1730 mask = ~(1 << (DSPCR_CCOND_SHIFT + j));
1731 DSPCR &= mask;
1732 if (op == 0) // EQ
1733 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j));
1734 else if (op == 1) // LT
1735 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j));
1736 else // LE
1737 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j));
1738 }
1739 }
1740
1741 011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH
1742 "cmp.eq.ph r<RS>, r<RT>"
1743 *dsp:
1744 {
1745 do_ph_cmpu (SD_, RS, RT, 0);
1746 }
1747
1748 011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH
1749 "cmp.lt.ph r<RS>, r<RT>"
1750 *dsp:
1751 {
1752 do_ph_cmpu (SD_, RS, RT, 1);
1753 }
1754
1755 011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH
1756 "cmp.le.ph r<RS>, r<RT>"
1757 *dsp:
1758 {
1759 do_ph_cmpu (SD_, RS, RT, 2);
1760 }
1761
1762 011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB
1763 "pick.qb r<RD>, r<RS>, r<RT>"
1764 *dsp:
1765 {
1766 do_qb_pick (SD_, RD, RS, RT);
1767 }
1768
1769 011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH
1770 "pick.ph r<RD>, r<RS>, r<RT>"
1771 *dsp:
1772 {
1773 do_ph_pick (SD_, RD, RS, RT);
1774 }
1775
1776 011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH
1777 "packrl.ph r<RD>, r<RS>, r<RT>"
1778 *dsp:
1779 {
1780 do_ph_packrl (SD_, RD, RS, RT);
1781 }
1782
1783 // op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS
1784 :function:::void:do_w_extr:int rt, int ac, int shift, int op
1785 {
1786 int i;
1787 unsigned32 lo = DSPLO(ac);
1788 unsigned32 hi = DSPHI(ac);
1789 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1790 signed64 result = (signed64)prod;
1791 int setcond = 0;
1792 if (!(prod & 0x8000000000000000LL))
1793 {
1794 for (i = 62; i >= (shift + 31); i--)
1795 {
1796 if (prod & ((unsigned64)1 << i))
1797 {
1798 DSPCR |= DSPCR_OUFLAG7;
1799 setcond = 1;
1800 break;
1801 }
1802 }
1803 if (((prod >> (shift - 1)) & 0xffffffffLL) == 0xffffffffLL)
1804 {
1805 DSPCR |= DSPCR_OUFLAG7;
1806 setcond = 1;
1807 }
1808 }
1809 else
1810 {
1811 for (i = 62; i >= (shift + 31); i--)
1812 {
1813 if (!(prod & ((unsigned64)1 << i)))
1814 {
1815 DSPCR |= DSPCR_OUFLAG7;
1816 setcond = 2;
1817 break;
1818 }
1819 }
1820 }
1821 if (op == 0) // EXTR
1822 result = result >> shift;
1823 else if (op == 1) // EXTR_R
1824 {
1825 if (shift != 0)
1826 result = ((result >> (shift - 1)) + 1) >> 1;
1827 else
1828 result = result >> shift;
1829 }
1830 else // EXTR_RS
1831 {
1832 if (setcond == 1)
1833 result = 0x7fffffff;
1834 else if (setcond == 2)
1835 result = 0x80000000;
1836 else
1837 {
1838 if (shift != 0)
1839 result = ((result >> (shift - 1)) + 1) >> 1;
1840 else
1841 result = result >> shift;
1842 }
1843 }
1844 GPR[rt] = EXTEND32 (result);
1845 }
1846
1847 011111,5.SHIFT,5.RT,000,2.AC,00000,111000:SPECIAL3:32::EXTR.W
1848 "extr.w r<RT>, ac<AC>, <SHIFT>"
1849 *dsp:
1850 {
1851 do_w_extr (SD_, RT, AC, SHIFT, 0);
1852 }
1853
1854 011111,5.RS,5.RT,000,2.AC,00001,111000:SPECIAL3:32::EXTRV.W
1855 "extrv.w r<RT>, ac<AC>, r<RS>"
1856 *dsp:
1857 {
1858 do_extrv (SD_, RT, AC, RS, 0);
1859 }
1860
1861 011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W
1862 "extr_r.w r<RT>, ac<AC>, <SHIFT>"
1863 *dsp:
1864 {
1865 do_w_extr (SD_, RT, AC, SHIFT, 1);
1866 }
1867
1868 011111,5.RS,5.RT,000,2.AC,00101,111000:SPECIAL3:32::EXTRV_R.W
1869 "extrv_r.w r<RT>, ac<AC>, r<RS>"
1870 *dsp:
1871 {
1872 do_extrv (SD_, RT, AC, RS, 1);
1873 }
1874
1875 011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W
1876 "extr_rs.w r<RT>, ac<AC>, <SHIFT>"
1877 *dsp:
1878 {
1879 do_w_extr (SD_, RT, AC, SHIFT, 2);
1880 }
1881
1882 011111,5.RS,5.RT,000,2.AC,00111,111000:SPECIAL3:32::EXTRV_RS.W
1883 "extrv_rs.w r<RT>, ac<AC>, r<RS>"
1884 *dsp:
1885 {
1886 do_extrv (SD_, RT, AC, RS, 2);
1887 }
1888
1889 :function:::void:do_h_extr:int rt, int ac, int shift
1890 {
1891 int i;
1892 unsigned32 lo = DSPLO(ac);
1893 unsigned32 hi = DSPHI(ac);
1894 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1895 signed64 result = (signed64)prod;
1896 signed64 value = 0xffffffffffff8000LL;
1897 result >>= shift;
1898 if (result > 0x7fff)
1899 {
1900 result = 0x7fff;
1901 DSPCR |= DSPCR_OUFLAG7;
1902 }
1903 else if (result < value)
1904 {
1905 result = value;
1906 DSPCR |= DSPCR_OUFLAG7;
1907 }
1908 GPR[rt] = EXTEND32 (result);
1909 }
1910
1911 011111,5.SHIFT,5.RT,000,2.AC,01110,111000:SPECIAL3:32::EXTR_S.H
1912 "extr_s.h r<RT>, ac<AC>, <SHIFT>"
1913 *dsp:
1914 {
1915 do_h_extr (SD_, RT, AC, SHIFT);
1916 }
1917
1918 011111,5.RS,5.RT,000,2.AC,01111,111000:SPECIAL3:32::EXTRV_S.H
1919 "extrv_s.h r<RT>, ac<AC>, r<RS>"
1920 *dsp:
1921 {
1922 do_extrv_s_h (SD_, RT, AC, RS);
1923 }
1924
1925 // op: 0 = EXTP, 1 = EXTPDP
1926 :function:::void:do_extp:int rt, int ac, int size, int op
1927 {
1928 signed32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
1929 unsigned32 lo = DSPLO(ac);
1930 unsigned32 hi = DSPHI(ac);
1931 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1932 unsigned64 result = 0;
1933 if (pos - (size + 1) >= -1)
1934 {
1935 prod >>= (pos - size);
1936 result = prod & (((unsigned64)1 << (size + 1)) - 1);
1937 DSPCR &= (~DSPCR_EFI_SMASK);
1938 if (op == 1) // EXTPDP
1939 {
1940 if (pos - (size + 1) >= 0)
1941 {
1942 DSPCR &= (~DSPCR_POS_SMASK);
1943 DSPCR |= ((pos - (size + 1)) & DSPCR_POS_MASK) << DSPCR_POS_SHIFT;
1944 }
1945 else if (pos - (size + 1) == -1)
1946 {
1947 DSPCR |= DSPCR_POS_SMASK;
1948 }
1949 }
1950 }
1951 else
1952 {
1953 DSPCR |= DSPCR_EFI;
1954 Unpredictable ();
1955 }
1956 GPR[rt] = EXTEND32 (result);
1957 }
1958
1959 011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP
1960 "extp r<RT>, ac<AC>, <SIZE>"
1961 *dsp:
1962 {
1963 do_extp (SD_, RT, AC, SIZE, 0);
1964 }
1965
1966 011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV
1967 "extpv r<RT>, ac<AC>, r<RS>"
1968 *dsp:
1969 {
1970 do_extpv (SD_, RT, AC, RS, 0);
1971 }
1972
1973 011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP
1974 "extpdp r<RT>, ac<AC>, <SIZE>"
1975 *dsp:
1976 {
1977 do_extp (SD_, RT, AC, SIZE, 1);
1978 }
1979
1980 011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV
1981 "extpdpv r<RT>, ac<AC>, r<RS>"
1982 *dsp:
1983 {
1984 do_extpv (SD_, RT, AC, RS, 1);
1985 }
1986
1987 :function:::void:do_shilo:int ac, int shift
1988 {
1989 unsigned32 lo = DSPLO(ac);
1990 unsigned32 hi = DSPHI(ac);
1991 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo;
1992 if (shift > 31)
1993 shift = shift - 64;
1994 if (shift >= 0)
1995 prod >>= shift;
1996 else
1997 prod <<= (-shift);
1998 DSPLO(ac) = EXTEND32 (prod);
1999 DSPHI(ac) = EXTEND32 (prod >> 32);
2000 }
2001
2002 011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO
2003 "shilo ac<AC>, <SHIFT6>"
2004 *dsp:
2005 {
2006 do_shilo (SD_, AC, SHIFT6);
2007 }
2008
2009 011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV
2010 "shilov ac<AC>, r<RS>"
2011 *dsp:
2012 {
2013 do_shilov (SD_, AC, RS);
2014 }
2015
2016 011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP
2017 "mthlip r<RS>, ac<AC>"
2018 *dsp:
2019 {
2020 do_mthlip (SD_, RS, AC);
2021 }
2022
2023 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
2024 "wrdsp r<RS>":MASK10 == 1111111111
2025 "wrdsp r<RS>, <MASK10>"
2026 *dsp:
2027 {
2028 do_wrdsp (SD_, RS, MASK10);
2029 }
2030
2031 011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP
2032 "rddsp r<RD>":MASK10 == 1111111111
2033 "rddsp r<RD>, <MASK10>"
2034 *dsp:
2035 {
2036 do_rddsp (SD_, RD, MASK10);
2037 }
2038
2039 011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX
2040 "lbux r<RD>, r<INDEX>(r<BASE>)"
2041 *dsp:
2042 {
2043 do_lxx (SD_, RD, BASE, INDEX, 0);
2044 }
2045
2046 011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX
2047 "lhx r<RD>, r<INDEX>(r<BASE>)"
2048 *dsp:
2049 {
2050 do_lxx (SD_, RD, BASE, INDEX, 1);
2051 }
2052
2053 011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX
2054 "lwx r<RD>, r<INDEX>(r<BASE>)"
2055 *dsp:
2056 {
2057 do_lxx (SD_, RD, BASE, INDEX, 2);
2058 }
2059
2060 000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32
2061 "bposge32 <OFFSET>"
2062 *dsp:
2063 {
2064 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
2065 address_word offset = EXTEND16 (OFFSET) << 2;
2066 if (pos >= 32)
2067 {
2068 DELAY_SLOT (NIA + offset);
2069 }
2070 }
This page took 0.076825 seconds and 4 git commands to generate.