gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / sim / mips / dsp.igen
CommitLineData
40a5538e
CF
1// -*- C -*-
2
3// Simulator definition for the MIPS DSP ASE.
b811d2c2 4// Copyright (C) 2005-2020 Free Software Foundation, Inc.
40a5538e
CF
5// Contributed by MIPS Technologies, Inc. Written by Chao-ying Fu.
6//
8e394ffc 7// This file is part of the MIPS sim
40a5538e
CF
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
4744ac1b
JB
11// the Free Software Foundation; either version 3 of the License, or
12// (at your option) any later version.
13//
40a5538e
CF
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.
4744ac1b 18//
8bf3ddc8 19// You should have received a copy of the GNU General Public License
4744ac1b 20// along with this program. If not, see <http://www.gnu.org/licenses/>.
40a5538e
CF
21
22
8b082fb1 23// op: 0 = ADD, 1 = SUB, 2 = MUL
40a5538e
CF
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;
8b082fb1 28 signed32 h0 = 0;
40a5538e
CF
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;
8b082fb1 39 else if (op == 1) // SUB
40a5538e 40 h0 = (signed32)h1 - (signed32)h2;
8b082fb1
TS
41 else // MUL
42 h0 = (signed32)h1 * (signed32)h2;
43 if (h0 > (signed32)0x7fff || h0 < (signed32)0xffff8000)
40a5538e 44 {
8b082fb1
TS
45 if (op == 0 || op == 1) // ADD, SUB
46 DSPCR |= DSPCR_OUFLAG4;
47 else if (op == 2) // MUL
48 DSPCR |= DSPCR_OUFLAG5;
40a5538e
CF
49 if (sat == 1)
50 {
8b082fb1 51 if (h0 > (signed32)0x7fff)
40a5538e 52 h0 = 0x7fff;
8b082fb1
TS
53 else
54 h0 = 0x8000;
40a5538e
CF
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;
02f97da7 76 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
40a5538e
CF
77 {
78 DSPCR |= DSPCR_OUFLAG4;
02f97da7 79 if (h0 & 0x100000000LL)
40a5538e
CF
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 {
69088b17
CF
200 if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1))))
201 h0 = (h0 >> shift) + 1;
202 else
203 h0 = h0 >> shift;
40a5538e
CF
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
8e394ffc
AB
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
40a5538e
CF
866:function:::void:do_w_shra:int rd, int rt, int shift
867{
868 unsigned32 result = GPR[rt];
869 signed32 h0 = (signed32)result;
69088b17
CF
870 if (shift != 0 && (h0 & (1 << (shift-1))))
871 h0 = (h0 >> shift) + 1;
872 else
873 h0 = h0 >> shift;
40a5538e
CF
874 GPR[rd] = EXTEND32 (h0);
875}
876
877011111,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
884011111,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
891011111,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
898011111,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
905011111,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
912011111,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
919011111,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
926011111,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
933011111,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
940011111,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
947011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC
948"addsc r<RD>, r<RS>, r<RT>"
949*dsp:
950{
8e394ffc 951 do_addsc (SD_, RD, RS, RT);
40a5538e
CF
952}
953
954011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC
955"addwc r<RD>, r<RS>, r<RT>"
956*dsp:
957{
8e394ffc 958 do_addwc (SD_, RD, RS, RT);
40a5538e
CF
959}
960
961011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB
962"modsub r<RD>, r<RS>, r<RT>"
963*dsp:
964{
8e394ffc 965 do_modsub (SD_, RD, RS, RT);
40a5538e
CF
966}
967
968011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB
969"raddu.w.qb r<RD>, r<RS>"
970*dsp:
971{
8e394ffc 972 do_qb_w_raddu (SD_, RD, RS);
40a5538e
CF
973}
974
975011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH
976"absq_s.ph r<RD>, r<RT>"
977*dsp:
978{
8e394ffc 979 do_ph_s_absq (SD_, RD, RT);
40a5538e
CF
980}
981
982011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W
983"absq_s.w r<RD>, r<RT>"
984*dsp:
985{
8e394ffc 986 do_w_s_absq (SD_, RD, RT);
40a5538e
CF
987}
988
989011111,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{
8e394ffc 993 do_ph_qb_precrq (SD_, RD, RS, RT, 0);
40a5538e
CF
994}
995
996011111,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{
8e394ffc 1000 do_w_ph_precrq (SD_, RD, RS, RT);
40a5538e
CF
1001}
1002
1003011111,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{
8e394ffc 1007 do_w_ph_rs_precrq (SD_, RD, RS, RT);
40a5538e
CF
1008}
1009
1010011111,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{
8e394ffc 1014 do_ph_qb_precrq (SD_, RD, RS, RT, 1);
40a5538e
CF
1015}
1016
1017011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL
1018"preceq.w.phl r<RD>, r<RT>"
1019*dsp:
1020{
8e394ffc 1021 do_w_preceq (SD_, RD, RT, 0);
40a5538e
CF
1022}
1023
1024011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR
1025"preceq.w.phr r<RD>, r<RT>"
1026*dsp:
1027{
8e394ffc 1028 do_w_preceq (SD_, RD, RT, 1);
40a5538e
CF
1029}
1030
1031011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL
1032"precequ.ph.qbl r<RD>, r<RT>"
1033*dsp:
1034{
8e394ffc 1035 do_qb_ph_precequ (SD_, RD, RT, 2);
40a5538e
CF
1036}
1037
1038011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR
1039"precequ.ph.qbr r<RD>, r<RT>"
1040*dsp:
1041{
8e394ffc 1042 do_qb_ph_precequ (SD_, RD, RT, 0);
40a5538e
CF
1043}
1044
1045011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA
1046"precequ.ph.qbla r<RD>, r<RT>"
1047*dsp:
1048{
8e394ffc 1049 do_qb_ph_precequ (SD_, RD, RT, 3);
40a5538e
CF
1050}
1051
1052011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA
1053"precequ.ph.qbra r<RD>, r<RT>"
1054*dsp:
1055{
8e394ffc 1056 do_qb_ph_precequ (SD_, RD, RT, 1);
40a5538e
CF
1057}
1058
1059011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL
1060"preceu.ph.qbl r<RD>, r<RT>"
1061*dsp:
1062{
8e394ffc 1063 do_qb_ph_preceu (SD_, RD, RT, 2);
40a5538e
CF
1064}
1065
1066011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR
1067"preceu.ph.qbr r<RD>, r<RT>"
1068*dsp:
1069{
8e394ffc 1070 do_qb_ph_preceu (SD_, RD, RT, 0);
40a5538e
CF
1071}
1072
1073011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA
1074"preceu.ph.qbla r<RD>, r<RT>"
1075*dsp:
1076{
8e394ffc 1077 do_qb_ph_preceu (SD_, RD, RT, 3);
40a5538e
CF
1078}
1079
1080011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA
1081"preceu.ph.qbra r<RD>, r<RT>"
1082*dsp:
1083{
8e394ffc 1084 do_qb_ph_preceu (SD_, RD, RT, 1);
40a5538e
CF
1085}
1086
1087011111,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
1094011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB
1095"shllv.qb r<RD>, r<RT>, r<RS>"
1096*dsp:
1097{
8e394ffc 1098 do_qb_shl (SD_, RD, RT, RS, 0);
40a5538e
CF
1099}
1100
1101011111,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
1108011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH
1109"shllv.ph r<RD>, r<RT>, r<RS>"
1110*dsp:
1111{
8e394ffc 1112 do_ph_shl (SD_, RD, RT, RS, 0, 0);
40a5538e
CF
1113}
1114
1115011111,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
1122011111,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{
8e394ffc 1126 do_ph_shl (SD_, RD, RT, RS, 0, 1);
40a5538e
CF
1127}
1128
1129011111,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
1136011111,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{
8e394ffc 1140 do_w_s_shllv (SD_, RD, RT, RS);
40a5538e
CF
1141}
1142
1143011111,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
1150011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB
1151"shrlv.qb r<RD>, r<RT>, r<RS>"
1152*dsp:
1153{
8e394ffc 1154 do_qb_shl (SD_, RD, RT, RS, 1);
40a5538e
CF
1155}
1156
1157011111,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
1164011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH
1165"shrav.ph r<RD>, r<RT>, r<RS>"
1166*dsp:
1167{
8e394ffc 1168 do_ph_shl (SD_, RD, RT, RS, 1, 0);
40a5538e
CF
1169}
1170
1171011111,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
1178011111,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{
8e394ffc 1182 do_ph_shl (SD_, RD, RT, RS, 1, 1);
40a5538e
CF
1183}
1184
1185011111,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
1192011111,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{
8e394ffc 1196 do_w_r_shrav (SD_, RD, RT, RS);
40a5538e
CF
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
1225011111,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
1232011111,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
8b082fb1
TS
1239// round: 0 = no rounding, 1 = rounding
1240:function:::void:do_ph_mulq:int rd, int rs, int rt, int round
40a5538e
CF
1241{
1242 int i;
1243 unsigned32 result = 0;
8b082fb1
TS
1244 unsigned32 v1 = GPR[rs];
1245 unsigned32 v2 = GPR[rt];
40a5538e
CF
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
8b082fb1
TS
1258 {
1259 prod = ((signed32)h1 * (signed32)h2) << 1;
1260 if (round == 1)
1261 prod += (signed32)0x8000;
1262 }
40a5538e
CF
1263 result |= (((unsigned32)prod >> 16) << i);
1264 }
8b082fb1
TS
1265 GPR[rd] = EXTEND32 (result);
1266}
1267
1268011111,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);
40a5538e
CF
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
1302011111,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
1309011111,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
1345011111,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
1352011111,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
1359011111,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
1366011111,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
1405011111,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
1412011111,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
1419011111,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{
8e394ffc 1423 do_mulsaq_s_w_ph (SD_, AC, RS, RT);
40a5538e
CF
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
1486011111,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
1493011111,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
1561011111,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
1568011111,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
1575011111,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
1582011111,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
1589011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV
1590"bitrev r<RD>, r<RT>"
1591*dsp:
1592{
8e394ffc 1593 do_bitrev (SD_, RD, RT);
40a5538e
CF
1594}
1595
1596011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV
1597"insv r<RT>, r<RS>"
1598*dsp:
1599{
8e394ffc 1600 do_insv (SD_, RT, RS);
40a5538e
CF
1601}
1602
1603011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB
1604"repl.qb r<RD>, <IMM8>"
1605*dsp:
1606{
8e394ffc 1607 do_repl (SD_, RD, IMM8, 0);
40a5538e
CF
1608}
1609
1610011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB
1611"replv.qb r<RD>, r<RT>"
1612*dsp:
1613{
8e394ffc 1614 do_repl (SD_, RD, RT, 1);
40a5538e
CF
1615}
1616
1617011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH
1618"repl.ph r<RD>, <IMM10>"
1619*dsp:
1620{
8e394ffc 1621 do_repl (SD_, RD, IMM10, 2);
40a5538e
CF
1622}
1623
1624011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH
1625"replv.ph r<RD>, r<RT>"
1626*dsp:
1627{
8e394ffc 1628 do_repl (SD_, RD, RT, 3);
40a5538e
CF
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
1654011111,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
1661011111,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
1668011111,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
1697011111,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
1704011111,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
1711011111,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
1741011111,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
1748011111,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
1755011111,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
1762011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB
1763"pick.qb r<RD>, r<RS>, r<RT>"
1764*dsp:
1765{
8e394ffc 1766 do_qb_pick (SD_, RD, RS, RT);
40a5538e
CF
1767}
1768
1769011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH
1770"pick.ph r<RD>, r<RS>, r<RT>"
1771*dsp:
1772{
8e394ffc 1773 do_ph_pick (SD_, RD, RS, RT);
40a5538e
CF
1774}
1775
1776011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH
1777"packrl.ph r<RD>, r<RS>, r<RT>"
1778*dsp:
1779{
8e394ffc 1780 do_ph_packrl (SD_, RD, RS, RT);
40a5538e
CF
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
1847011111,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
1854011111,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{
8e394ffc 1858 do_extrv (SD_, RT, AC, RS, 0);
40a5538e
CF
1859}
1860
1861011111,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
1868011111,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{
8e394ffc 1872 do_extrv (SD_, RT, AC, RS, 1);
40a5538e
CF
1873}
1874
1875011111,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
1882011111,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{
8e394ffc 1886 do_extrv (SD_, RT, AC, RS, 2);
40a5538e
CF
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
1911011111,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
1918011111,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{
8e394ffc 1922 do_extrv_s_h (SD_, RT, AC, RS);
40a5538e
CF
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
1959011111,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
1966011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV
1967"extpv r<RT>, ac<AC>, r<RS>"
1968*dsp:
1969{
8e394ffc 1970 do_extpv (SD_, RT, AC, RS, 0);
40a5538e
CF
1971}
1972
1973011111,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
1980011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV
1981"extpdpv r<RT>, ac<AC>, r<RS>"
1982*dsp:
1983{
8e394ffc 1984 do_extpv (SD_, RT, AC, RS, 1);
40a5538e
CF
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
2002011111,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
2009011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV
2010"shilov ac<AC>, r<RS>"
2011*dsp:
2012{
8e394ffc 2013 do_shilov (SD_, AC, RS);
40a5538e
CF
2014}
2015
2016011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP
2017"mthlip r<RS>, ac<AC>"
2018*dsp:
2019{
8e394ffc 2020 do_mthlip (SD_, RS, AC);
40a5538e
CF
2021}
2022
40a5538e
CF
2023011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP
2024"wrdsp r<RS>":MASK10 == 1111111111
2025"wrdsp r<RS>, <MASK10>"
2026*dsp:
2027{
8e394ffc 2028 do_wrdsp (SD_, RS, MASK10);
40a5538e
CF
2029}
2030
2031011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP
2032"rddsp r<RD>":MASK10 == 1111111111
2033"rddsp r<RD>, <MASK10>"
2034*dsp:
2035{
8e394ffc 2036 do_rddsp (SD_, RD, MASK10);
40a5538e
CF
2037}
2038
2039011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX
2040"lbux r<RD>, r<INDEX>(r<BASE>)"
2041*dsp:
2042{
8e394ffc 2043 do_lxx (SD_, RD, BASE, INDEX, 0);
40a5538e
CF
2044}
2045
2046011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX
2047"lhx r<RD>, r<INDEX>(r<BASE>)"
2048*dsp:
2049{
8e394ffc 2050 do_lxx (SD_, RD, BASE, INDEX, 1);
40a5538e
CF
2051}
2052
2053011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX
2054"lwx r<RD>, r<INDEX>(r<BASE>)"
2055*dsp:
2056{
8e394ffc 2057 do_lxx (SD_, RD, BASE, INDEX, 2);
40a5538e
CF
2058}
2059
2060000001,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.76127 seconds and 4 git commands to generate.