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