* acconfig.h: Remove.
[deliverable/binutils-gdb.git] / sim / mips / dsp.igen
CommitLineData
40a5538e
CF
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;
02f97da7 72 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000))
40a5538e
CF
73 {
74 DSPCR |= DSPCR_OUFLAG4;
02f97da7 75 if (h0 & 0x100000000LL)
40a5538e
CF
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 {
69088b17
CF
196 if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1))))
197 h0 = (h0 >> shift) + 1;
198 else
199 h0 = h0 >> shift;
40a5538e
CF
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;
69088b17
CF
250 if (shift != 0 && (h0 & (1 << (shift-1))))
251 h0 = (h0 >> shift) + 1;
252 else
253 h0 = h0 >> shift;
40a5538e
CF
254 GPR[rd] = EXTEND32 (h0);
255}
256
257011111,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
264011111,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
271011111,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
278011111,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
285011111,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
292011111,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
299011111,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
306011111,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
313011111,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
320011111,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
327011111,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
340011111,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
356011111,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
372011111,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
388011111,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
411011111,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
427011111,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
440011111,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
451011111,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
480011111,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
538011111,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
546011111,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
554011111,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
562011111,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
570011111,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
578011111,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
586011111,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
594011111,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
602011111,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
610011111,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
618011111,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
625011111,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
633011111,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
640011111,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
648011111,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
655011111,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
663011111,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
670011111,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
678011111,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
685011111,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
693011111,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
700011111,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
708011111,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
715011111,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
723011111,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
730011111,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
764011111,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
771011111,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
778011111,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
832011111,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
839011111,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
875011111,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
882011111,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
889011111,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
896011111,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
935011111,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
942011111,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
949011111,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
1042011111,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
1049011111,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
1117011111,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
1124011111,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
1131011111,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
1138011111,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
1145011111,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
1160011111,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
1182011111,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
1189011111,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
1198011111,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
1208011111,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
1240011111,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
1247011111,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
1254011111,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
1283011111,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
1290011111,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
1297011111,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
1327011111,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
1334011111,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
1341011111,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
1348011111,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
1369011111,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
1390011111,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
1463011111,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
1470011111,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
1478011111,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
1485011111,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
1493011111,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
1500011111,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
1530011111,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
1537011111,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
1579011111,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
1586011111,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
1594011111,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
1601011111,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
1624011111,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
1631011111,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
1639011111,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
1654000000,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
1669000000,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
1684000000,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
1698000000,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
1712011111,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
1750011111,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
1789011111,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
1796011111,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
1803011111,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
1810000001,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.125546 seconds and 4 git commands to generate.