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