1 /* maverick.c -- Cirrus/DSP co-processor interface.
2 Copyright (C) 2003, 2007 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez (aldyh@redhat.com).
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
24 /*#define CIRRUS_DEBUG 1 /**/
26 # define printfdbg printf
28 # define printfdbg printf_nothing
31 #define POS64(i) ( (~(i)) >> 63 )
32 #define NEG64(i) ( (i) >> 63 )
34 /* Define Co-Processor instruction handlers here. */
36 /* Here's ARMulator's DSP definition. A few things to note:
37 1) it has 16 64-bit registers and 4 72-bit accumulators
38 2) you can only access its registers with MCR and MRC. */
40 /* We can't define these in here because this file might not be linked
41 unless the target is arm9e-*. They are defined in wrapper.c.
42 Eventually the simulator should be made to handle any coprocessor
59 union maverick_acc_regs
61 long double ld; /* Acc registers are 72-bits. */
64 struct maverick_regs DSPregs[16];
65 union maverick_acc_regs DSPacc[4];
68 #define DEST_REG (BITS (12, 15))
69 #define SRC1_REG (BITS (16, 19))
70 #define SRC2_REG (BITS (0, 3))
72 static int lsw_int_index, msw_int_index;
73 static int lsw_float_index, msw_float_index;
75 static double mv_getRegDouble (int);
76 static long long mv_getReg64int (int);
77 static void mv_setRegDouble (int, double val);
78 static void mv_setReg64int (int, long long val);
88 printf_nothing (void * foo, ...)
93 cirrus_not_implemented (char * insn)
95 fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn);
96 fprintf (stderr, "aborting!\n");
102 DSPInit (ARMul_State * state)
104 ARMul_ConsolePrint (state, ", DSP present");
109 DSPMRC4 (ARMul_State * state ATTRIBUTE_UNUSED,
110 unsigned type ATTRIBUTE_UNUSED,
116 case 0: /* cfmvrdl */
117 /* Move lower half of a DF stored in a DSP reg into an Arm reg. */
118 printfdbg ("cfmvrdl\n");
119 printfdbg ("\tlower half=0x%x\n", DSPregs[SRC1_REG].lower.i);
120 printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
122 *value = (ARMword) DSPregs[SRC1_REG].lower.i;
125 case 1: /* cfmvrdh */
126 /* Move upper half of a DF stored in a DSP reg into an Arm reg. */
127 printfdbg ("cfmvrdh\n");
128 printfdbg ("\tupper half=0x%x\n", DSPregs[SRC1_REG].upper.i);
129 printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
131 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
135 /* Move SF from upper half of a DSP register to an Arm register. */
136 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
137 printfdbg ("cfmvrs = mvf%d <-- %f\n",
139 DSPregs[SRC1_REG].upper.f);
148 a = DSPregs[SRC1_REG].upper.f;
149 b = DSPregs[SRC2_REG].upper.f;
151 printfdbg ("cfcmps\n");
152 printfdbg ("\tcomparing %f and %f\n", a, b);
154 z = a == b; /* zero */
155 n = a != b; /* negative */
156 v = a > b; /* overflow */
158 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
167 a = mv_getRegDouble (SRC1_REG);
168 b = mv_getRegDouble (SRC2_REG);
170 printfdbg ("cfcmpd\n");
171 printfdbg ("\tcomparing %g and %g\n", a, b);
173 z = a == b; /* zero */
174 n = a != b; /* negative */
175 v = a > b; /* overflow */
177 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
186 a = DSPregs[SRC1_REG].upper.f;
187 b = DSPregs[SRC2_REG].upper.f;
189 printfdbg ("cfcmps\n");
190 printfdbg ("\tcomparing %f and %f\n", a, b);
192 z = a == b; /* zero */
193 n = a < b; /* negative */
194 c = a > b; /* carry */
196 printfdbg ("\tz = %d, n = %d\n", z, n);
197 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
206 a = mv_getRegDouble (SRC1_REG);
207 b = mv_getRegDouble (SRC2_REG);
209 printfdbg ("cfcmpd\n");
210 printfdbg ("\tcomparing %g and %g\n", a, b);
212 z = a == b; /* zero */
213 n = a < b; /* negative */
214 c = a > b; /* carry */
216 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
221 fprintf (stderr, "unknown opcode in DSPMRC4 0x%x\n", instr);
222 cirrus_not_implemented ("unknown");
230 DSPMRC5 (ARMul_State * state ATTRIBUTE_UNUSED,
231 unsigned type ATTRIBUTE_UNUSED,
237 case 0: /* cfmvr64l */
238 /* Move lower half of 64bit int from Cirrus to Arm. */
239 *value = (ARMword) DSPregs[SRC1_REG].lower.i;
240 printfdbg ("cfmvr64l ARM_REG = mvfx%d <-- %d\n",
245 case 1: /* cfmvr64h */
246 /* Move upper half of 64bit int from Cirrus to Arm. */
247 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
248 printfdbg ("cfmvr64h <-- %d\n", (int) *value);
251 case 4: /* cfcmp32 */
257 printfdbg ("cfcmp32 mvfx%d - mvfx%d\n",
261 /* FIXME: see comment for cfcmps. */
262 a = DSPregs[SRC1_REG].lower.i;
263 b = DSPregs[SRC2_REG].lower.i;
265 res = DSPregs[SRC1_REG].lower.i - DSPregs[SRC2_REG].lower.i;
271 v = SubOverflow (DSPregs[SRC1_REG].lower.i, DSPregs[SRC2_REG].lower.i,
274 c = (NEG (a) && POS (b) ||
275 (NEG (a) && POS (res)) || (POS (b) && POS (res)));
277 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
281 case 5: /* cfcmp64 */
285 unsigned long long a, b;
287 printfdbg ("cfcmp64 mvdx%d - mvdx%d\n",
291 /* fixme: see comment for cfcmps. */
293 a = mv_getReg64int (SRC1_REG);
294 b = mv_getReg64int (SRC2_REG);
296 res = mv_getReg64int (SRC1_REG) - mv_getReg64int (SRC2_REG);
302 v = ((NEG64 (a) && POS64 (b) && POS64 (res))
303 || (POS64 (a) && NEG64 (b) && NEG64 (res)));
305 c = (NEG64 (a) && POS64 (b) ||
306 (NEG64 (a) && POS64 (res)) || (POS64 (b) && POS64 (res)));
308 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
313 fprintf (stderr, "unknown opcode in DSPMRC5 0x%x\n", instr);
314 cirrus_not_implemented ("unknown");
322 DSPMRC6 (ARMul_State * state ATTRIBUTE_UNUSED,
323 unsigned type ATTRIBUTE_UNUSED,
329 case 0: /* cfmval32 */
330 cirrus_not_implemented ("cfmval32");
333 case 1: /* cfmvam32 */
334 cirrus_not_implemented ("cfmvam32");
337 case 2: /* cfmvah32 */
338 cirrus_not_implemented ("cfmvah32");
341 case 3: /* cfmva32 */
342 cirrus_not_implemented ("cfmva32");
345 case 4: /* cfmva64 */
346 cirrus_not_implemented ("cfmva64");
349 case 5: /* cfmvsc32 */
350 cirrus_not_implemented ("cfmvsc32");
354 fprintf (stderr, "unknown opcode in DSPMRC6 0x%x\n", instr);
355 cirrus_not_implemented ("unknown");
363 DSPMCR4 (ARMul_State * state,
364 unsigned type ATTRIBUTE_UNUSED,
370 case 0: /* cfmvdlr */
371 /* Move the lower half of a DF value from an Arm register into
372 the lower half of a Cirrus register. */
373 printfdbg ("cfmvdlr <-- 0x%x\n", (int) value);
374 DSPregs[SRC1_REG].lower.i = (int) value;
377 case 1: /* cfmvdhr */
378 /* Move the upper half of a DF value from an Arm register into
379 the upper half of a Cirrus register. */
380 printfdbg ("cfmvdhr <-- 0x%x\n", (int) value);
381 DSPregs[SRC1_REG].upper.i = (int) value;
385 /* Move SF from Arm register into upper half of Cirrus register. */
386 printfdbg ("cfmvsr <-- 0x%x\n", (int) value);
387 DSPregs[SRC1_REG].upper.i = (int) value;
391 fprintf (stderr, "unknown opcode in DSPMCR4 0x%x\n", instr);
392 cirrus_not_implemented ("unknown");
400 DSPMCR5 (ARMul_State * state,
401 unsigned type ATTRIBUTE_UNUSED,
413 case 0: /* cfmv64lr */
414 /* Move lower half of a 64bit int from an ARM register into the
415 lower half of a DSP register and sign extend it. */
416 printfdbg ("cfmv64lr mvdx%d <-- 0x%x\n", SRC1_REG, (int) value);
417 DSPregs[SRC1_REG].lower.i = (int) value;
420 case 1: /* cfmv64hr */
421 /* Move upper half of a 64bit int from an ARM register into the
422 upper half of a DSP register. */
423 printfdbg ("cfmv64hr ARM_REG = mvfx%d <-- 0x%x\n",
426 DSPregs[SRC1_REG].upper.i = (int) value;
429 case 2: /* cfrshl32 */
430 printfdbg ("cfrshl32\n");
433 DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i << value;
435 DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -value;
438 case 3: /* cfrshl64 */
439 printfdbg ("cfrshl64\n");
442 mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) << value);
444 mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) >> -value);
448 fprintf (stderr, "unknown opcode in DSPMCR5 0x%x\n", instr);
449 cirrus_not_implemented ("unknown");
457 DSPMCR6 (ARMul_State * state,
458 unsigned type ATTRIBUTE_UNUSED,
464 case 0: /* cfmv32al */
465 cirrus_not_implemented ("cfmv32al");
468 case 1: /* cfmv32am */
469 cirrus_not_implemented ("cfmv32am");
472 case 2: /* cfmv32ah */
473 cirrus_not_implemented ("cfmv32ah");
476 case 3: /* cfmv32a */
477 cirrus_not_implemented ("cfmv32a");
480 case 4: /* cfmv64a */
481 cirrus_not_implemented ("cfmv64a");
484 case 5: /* cfmv32sc */
485 cirrus_not_implemented ("cfmv32sc");
489 fprintf (stderr, "unknown opcode in DSPMCR6 0x%x\n", instr);
490 cirrus_not_implemented ("unknown");
498 DSPLDC4 (ARMul_State * state ATTRIBUTE_UNUSED,
503 static unsigned words;
505 if (type != ARMul_DATA)
512 { /* it's a long access, get two words */
515 printfdbg ("cfldrd: %x (words = %d) (bigend = %d) DESTREG = %d\n",
516 data, words, state->bigendSig, DEST_REG);
520 if (state->bigendSig)
521 DSPregs[DEST_REG].upper.i = (int) data;
523 DSPregs[DEST_REG].lower.i = (int) data;
527 if (state->bigendSig)
528 DSPregs[DEST_REG].lower.i = (int) data;
530 DSPregs[DEST_REG].upper.i = (int) data;
537 printfdbg ("\tmvd%d <-- mem = %g\n", DEST_REG,
538 mv_getRegDouble (DEST_REG));
547 /* Get just one word. */
550 printfdbg ("cfldrs\n");
552 DSPregs[DEST_REG].upper.i = (int) data;
554 printfdbg ("\tmvf%d <-- mem = %f\n", DEST_REG,
555 DSPregs[DEST_REG].upper.f);
562 DSPLDC5 (ARMul_State * state ATTRIBUTE_UNUSED,
567 static unsigned words;
569 if (type != ARMul_DATA)
577 /* It's a long access, get two words. */
580 printfdbg ("cfldr64: %d\n", data);
584 if (state->bigendSig)
585 DSPregs[DEST_REG].upper.i = (int) data;
587 DSPregs[DEST_REG].lower.i = (int) data;
591 if (state->bigendSig)
592 DSPregs[DEST_REG].lower.i = (int) data;
594 DSPregs[DEST_REG].upper.i = (int) data;
601 printfdbg ("\tmvdx%d <-- mem = %lld\n", DEST_REG,
602 mv_getReg64int (DEST_REG));
611 /* Get just one word. */
614 printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data);
616 /* 32bit ints should be sign extended to 64bits when loaded. */
617 mv_setReg64int (DEST_REG, (long long) data);
624 DSPSTC4 (ARMul_State * state ATTRIBUTE_UNUSED,
629 static unsigned words;
631 if (type != ARMul_DATA)
639 /* It's a long access, get two words. */
641 printfdbg ("cfstrd\n");
645 if (state->bigendSig)
646 *data = (ARMword) DSPregs[DEST_REG].upper.i;
648 *data = (ARMword) DSPregs[DEST_REG].lower.i;
652 if (state->bigendSig)
653 *data = (ARMword) DSPregs[DEST_REG].lower.i;
655 *data = (ARMword) DSPregs[DEST_REG].upper.i;
662 printfdbg ("\tmem = mvd%d = %g\n", DEST_REG,
663 mv_getRegDouble (DEST_REG));
672 /* Get just one word. */
674 printfdbg ("cfstrs mvf%d <-- %f\n", DEST_REG,
675 DSPregs[DEST_REG].upper.f);
677 *data = (ARMword) DSPregs[DEST_REG].upper.i;
684 DSPSTC5 (ARMul_State * state ATTRIBUTE_UNUSED,
689 static unsigned words;
691 if (type != ARMul_DATA)
699 /* It's a long access, store two words. */
701 printfdbg ("cfstr64\n");
705 if (state->bigendSig)
706 *data = (ARMword) DSPregs[DEST_REG].upper.i;
708 *data = (ARMword) DSPregs[DEST_REG].lower.i;
712 if (state->bigendSig)
713 *data = (ARMword) DSPregs[DEST_REG].lower.i;
715 *data = (ARMword) DSPregs[DEST_REG].upper.i;
722 printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG,
723 mv_getReg64int (DEST_REG));
732 /* Store just one word. */
734 *data = (ARMword) DSPregs[DEST_REG].lower.i;
736 printfdbg ("cfstr32 MEM = %d\n", (int) *data);
743 DSPCDP4 (ARMul_State * state,
749 opcode2 = BITS (5,7);
751 switch (BITS (20,21))
757 printfdbg ("cfcpys mvf%d = mvf%d = %f\n",
760 DSPregs[SRC1_REG].upper.f);
761 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f;
765 printfdbg ("cfcpyd mvd%d = mvd%d = %g\n",
768 mv_getRegDouble (SRC1_REG));
769 mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG));
772 case 2: /* cfcvtds */
773 printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n",
776 (float) mv_getRegDouble (SRC1_REG));
777 DSPregs[DEST_REG].upper.f = (float) mv_getRegDouble (SRC1_REG);
780 case 3: /* cfcvtsd */
781 printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n",
784 (double) DSPregs[SRC1_REG].upper.f);
785 mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].upper.f);
788 case 4: /* cfcvt32s */
789 printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n",
792 (float) DSPregs[SRC1_REG].lower.i);
793 DSPregs[DEST_REG].upper.f = (float) DSPregs[SRC1_REG].lower.i;
796 case 5: /* cfcvt32d */
797 printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n",
800 (double) DSPregs[SRC1_REG].lower.i);
801 mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].lower.i);
804 case 6: /* cfcvt64s */
805 printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n",
808 (float) mv_getReg64int (SRC1_REG));
809 DSPregs[DEST_REG].upper.f = (float) mv_getReg64int (SRC1_REG);
812 case 7: /* cfcvt64d */
813 printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n",
816 (double) mv_getReg64int (SRC1_REG));
817 mv_setRegDouble (DEST_REG, (double) mv_getReg64int (SRC1_REG));
826 printfdbg ("cfmuls mvf%d = mvf%d = %f\n",
829 DSPregs[SRC1_REG].upper.f * DSPregs[SRC2_REG].upper.f);
831 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
832 * DSPregs[SRC2_REG].upper.f;
836 printfdbg ("cfmuld mvd%d = mvd%d = %g\n",
839 mv_getRegDouble (SRC1_REG) * mv_getRegDouble (SRC2_REG));
841 mv_setRegDouble (DEST_REG,
842 mv_getRegDouble (SRC1_REG)
843 * mv_getRegDouble (SRC2_REG));
847 fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
848 cirrus_not_implemented ("unknown");
857 DSPregs[DEST_REG].upper.f = (DSPregs[SRC1_REG].upper.f < 0.0F ?
858 -DSPregs[SRC1_REG].upper.f
859 : DSPregs[SRC1_REG].upper.f);
860 printfdbg ("cfabss mvf%d = |mvf%d| = %f\n",
863 DSPregs[DEST_REG].upper.f);
867 mv_setRegDouble (DEST_REG,
868 (mv_getRegDouble (SRC1_REG) < 0.0 ?
869 -mv_getRegDouble (SRC1_REG)
870 : mv_getRegDouble (SRC1_REG)));
871 printfdbg ("cfabsd mvd%d = |mvd%d| = %g\n",
874 mv_getRegDouble (DEST_REG));
878 DSPregs[DEST_REG].upper.f = -DSPregs[SRC1_REG].upper.f;
879 printfdbg ("cfnegs mvf%d = -mvf%d = %f\n",
882 DSPregs[DEST_REG].upper.f);
886 mv_setRegDouble (DEST_REG,
887 -mv_getRegDouble (SRC1_REG));
888 printfdbg ("cfnegd mvd%d = -mvd%d = %g\n",
890 mv_getRegDouble (DEST_REG));
894 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
895 + DSPregs[SRC2_REG].upper.f;
896 printfdbg ("cfadds mvf%d = mvf%d + mvf%d = %f\n",
900 DSPregs[DEST_REG].upper.f);
904 mv_setRegDouble (DEST_REG,
905 mv_getRegDouble (SRC1_REG)
906 + mv_getRegDouble (SRC2_REG));
907 printfdbg ("cfaddd: mvd%d = mvd%d + mvd%d = %g\n",
911 mv_getRegDouble (DEST_REG));
915 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
916 - DSPregs[SRC2_REG].upper.f;
917 printfdbg ("cfsubs: mvf%d = mvf%d - mvf%d = %f\n",
921 DSPregs[DEST_REG].upper.f);
925 mv_setRegDouble (DEST_REG,
926 mv_getRegDouble (SRC1_REG)
927 - mv_getRegDouble (SRC2_REG));
928 printfdbg ("cfsubd: mvd%d = mvd%d - mvd%d = %g\n",
932 mv_getRegDouble (DEST_REG));
938 fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
939 cirrus_not_implemented ("unknown");
947 DSPCDP5 (ARMul_State * state,
954 opcode2 = BITS (5,7);
956 /* Shift constants are 7bit signed numbers in bits 0..3|5..7. */
957 shift = BITS (0, 3) | (BITS (5, 7)) << 4;
961 switch (BITS (20,21))
965 printfdbg ("cfsh32 %s amount=%d\n", shift < 0 ? "right" : "left",
968 /* Negative shift is a right shift. */
969 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -shift;
971 /* Positive shift is a left shift. */
972 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i << shift;
978 case 0: /* cfmul32 */
979 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
980 * DSPregs[SRC2_REG].lower.i;
981 printfdbg ("cfmul32 mvfx%d = mvfx%d * mvfx%d = %d\n",
985 DSPregs[DEST_REG].lower.i);
988 case 1: /* cfmul64 */
989 mv_setReg64int (DEST_REG,
990 mv_getReg64int (SRC1_REG)
991 * mv_getReg64int (SRC2_REG));
992 printfdbg ("cfmul64 mvdx%d = mvdx%d * mvdx%d = %lld\n",
996 mv_getReg64int (DEST_REG));
999 case 2: /* cfmac32 */
1000 DSPregs[DEST_REG].lower.i
1001 += DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
1002 printfdbg ("cfmac32 mvfx%d += mvfx%d * mvfx%d = %d\n",
1006 DSPregs[DEST_REG].lower.i);
1009 case 3: /* cfmsc32 */
1010 DSPregs[DEST_REG].lower.i
1011 -= DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
1012 printfdbg ("cfmsc32 mvfx%d -= mvfx%d * mvfx%d = %d\n",
1016 DSPregs[DEST_REG].lower.i);
1019 case 4: /* cfcvts32 */
1020 /* fixme: this should round */
1021 DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
1022 printfdbg ("cfcvts32 mvfx%d = mvf%d = %d\n",
1025 DSPregs[DEST_REG].lower.i);
1028 case 5: /* cfcvtd32 */
1029 /* fixme: this should round */
1030 DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
1031 printfdbg ("cfcvtd32 mvdx%d = mvd%d = %d\n",
1034 DSPregs[DEST_REG].lower.i);
1037 case 6: /* cftruncs32 */
1038 DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
1039 printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n",
1042 DSPregs[DEST_REG].lower.i);
1045 case 7: /* cftruncd32 */
1046 DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
1047 printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n",
1050 DSPregs[DEST_REG].lower.i);
1057 printfdbg ("cfsh64\n");
1060 /* Negative shift is a right shift. */
1061 mv_setReg64int (DEST_REG,
1062 mv_getReg64int (SRC1_REG) >> -shift);
1064 /* Positive shift is a left shift. */
1065 mv_setReg64int (DEST_REG,
1066 mv_getReg64int (SRC1_REG) << shift);
1067 printfdbg ("\t%llx\n", mv_getReg64int(DEST_REG));
1073 case 0: /* cfabs32 */
1074 DSPregs[DEST_REG].lower.i = (DSPregs[SRC1_REG].lower.i < 0
1075 ? -DSPregs[SRC1_REG].lower.i : DSPregs[SRC1_REG].lower.i);
1076 printfdbg ("cfabs32 mvfx%d = |mvfx%d| = %d\n",
1080 DSPregs[DEST_REG].lower.i);
1083 case 1: /* cfabs64 */
1084 mv_setReg64int (DEST_REG,
1085 (mv_getReg64int (SRC1_REG) < 0
1086 ? -mv_getReg64int (SRC1_REG)
1087 : mv_getReg64int (SRC1_REG)));
1088 printfdbg ("cfabs64 mvdx%d = |mvdx%d| = %lld\n",
1092 mv_getReg64int (DEST_REG));
1095 case 2: /* cfneg32 */
1096 DSPregs[DEST_REG].lower.i = -DSPregs[SRC1_REG].lower.i;
1097 printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n",
1101 DSPregs[DEST_REG].lower.i);
1104 case 3: /* cfneg64 */
1105 mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG));
1106 printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n",
1110 mv_getReg64int (DEST_REG));
1113 case 4: /* cfadd32 */
1114 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
1115 + DSPregs[SRC2_REG].lower.i;
1116 printfdbg ("cfadd32 mvfx%d = mvfx%d + mvfx%d = %d\n",
1120 DSPregs[DEST_REG].lower.i);
1123 case 5: /* cfadd64 */
1124 mv_setReg64int (DEST_REG,
1125 mv_getReg64int (SRC1_REG)
1126 + mv_getReg64int (SRC2_REG));
1127 printfdbg ("cfadd64 mvdx%d = mvdx%d + mvdx%d = %lld\n",
1131 mv_getReg64int (DEST_REG));
1134 case 6: /* cfsub32 */
1135 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
1136 - DSPregs[SRC2_REG].lower.i;
1137 printfdbg ("cfsub32 mvfx%d = mvfx%d - mvfx%d = %d\n",
1141 DSPregs[DEST_REG].lower.i);
1144 case 7: /* cfsub64 */
1145 mv_setReg64int (DEST_REG,
1146 mv_getReg64int (SRC1_REG)
1147 - mv_getReg64int (SRC2_REG));
1148 printfdbg ("cfsub64 mvdx%d = mvdx%d - mvdx%d = %d\n",
1152 mv_getReg64int (DEST_REG));
1158 fprintf (stderr, "unknown opcode in DSPCDP5 0x%x\n", instr);
1159 cirrus_not_implemented ("unknown");
1167 DSPCDP6 (ARMul_State * state,
1173 opcode2 = BITS (5,7);
1175 switch (BITS (20,21))
1179 cirrus_not_implemented ("cfmadd32");
1184 cirrus_not_implemented ("cfmsub32");
1189 cirrus_not_implemented ("cfmadda32");
1194 cirrus_not_implemented ("cfmsuba32");
1198 fprintf (stderr, "unknown opcode in DSPCDP6 0x%x\n", instr);
1204 /* Conversion functions.
1206 32-bit integers are stored in the LOWER half of a 64-bit physical
1209 Single precision floats are stored in the UPPER half of a 64-bit
1210 physical register. */
1213 mv_getRegDouble (int regnum)
1215 reg_conv.ints[lsw_float_index] = DSPregs[regnum].upper.i;
1216 reg_conv.ints[msw_float_index] = DSPregs[regnum].lower.i;
1221 mv_setRegDouble (int regnum, double val)
1224 DSPregs[regnum].upper.i = reg_conv.ints[lsw_float_index];
1225 DSPregs[regnum].lower.i = reg_conv.ints[msw_float_index];
1229 mv_getReg64int (int regnum)
1231 reg_conv.ints[lsw_int_index] = DSPregs[regnum].lower.i;
1232 reg_conv.ints[msw_int_index] = DSPregs[regnum].upper.i;
1237 mv_setReg64int (int regnum, long long val)
1240 DSPregs[regnum].lower.i = reg_conv.ints[lsw_int_index];
1241 DSPregs[regnum].upper.i = reg_conv.ints[msw_int_index];
1244 /* Compute LSW in a double and a long long. */
1247 mv_compute_host_endianness (ARMul_State * state)
1259 /* Calculate where's the LSW in a 64bit int. */
1262 if (conv.ints[0] == 0)
1269 assert (conv.ints[1] == 0);
1274 /* Calculate where's the LSW in a double. */
1277 if (conv.ints[0] == 0)
1279 msw_float_index = 0;
1280 lsw_float_index = 1;
1284 assert (conv.ints[1] == 0);
1285 msw_float_index = 1;
1286 lsw_float_index = 0;
1289 printfdbg ("lsw_int_index %d\n", lsw_int_index);
1290 printfdbg ("lsw_float_index %d\n", lsw_float_index);