1 /* maverick.c -- Cirrus/DSP co-processor interface.
2 Copyright (C) 2003-2014 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 3 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, see <http://www.gnu.org/licenses/>. */
23 /*#define CIRRUS_DEBUG 1 */
25 # define printfdbg printf
27 # define printfdbg printf_nothing
30 #define POS64(i) ( (~(i)) >> 63 )
31 #define NEG64(i) ( (i) >> 63 )
33 /* Define Co-Processor instruction handlers here. */
35 /* Here's ARMulator's DSP definition. A few things to note:
36 1) it has 16 64-bit registers and 4 72-bit accumulators
37 2) you can only access its registers with MCR and MRC. */
39 /* We can't define these in here because this file might not be linked
40 unless the target is arm9e-*. They are defined in wrapper.c.
41 Eventually the simulator should be made to handle any coprocessor
58 union maverick_acc_regs
60 long double ld; /* Acc registers are 72-bits. */
63 struct maverick_regs DSPregs[16];
64 union maverick_acc_regs DSPacc[4];
67 #define DEST_REG (BITS (12, 15))
68 #define SRC1_REG (BITS (16, 19))
69 #define SRC2_REG (BITS (0, 3))
71 static int lsw_int_index, msw_int_index;
72 static int lsw_float_index, msw_float_index;
74 static double mv_getRegDouble (int);
75 static long long mv_getReg64int (int);
76 static void mv_setRegDouble (int, double val);
77 static void mv_setReg64int (int, long long val);
87 printf_nothing (void * foo, ...)
92 cirrus_not_implemented (char * insn)
94 fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn);
95 fprintf (stderr, "aborting!\n");
101 DSPMRC4 (ARMul_State * state ATTRIBUTE_UNUSED,
102 unsigned type ATTRIBUTE_UNUSED,
108 case 0: /* cfmvrdl */
109 /* Move lower half of a DF stored in a DSP reg into an Arm reg. */
110 printfdbg ("cfmvrdl\n");
111 printfdbg ("\tlower half=0x%x\n", DSPregs[SRC1_REG].lower.i);
112 printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
114 *value = (ARMword) DSPregs[SRC1_REG].lower.i;
117 case 1: /* cfmvrdh */
118 /* Move upper half of a DF stored in a DSP reg into an Arm reg. */
119 printfdbg ("cfmvrdh\n");
120 printfdbg ("\tupper half=0x%x\n", DSPregs[SRC1_REG].upper.i);
121 printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
123 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
127 /* Move SF from upper half of a DSP register to an Arm register. */
128 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
129 printfdbg ("cfmvrs = mvf%d <-- %f\n",
131 DSPregs[SRC1_REG].upper.f);
140 a = DSPregs[SRC1_REG].upper.f;
141 b = DSPregs[SRC2_REG].upper.f;
143 printfdbg ("cfcmps\n");
144 printfdbg ("\tcomparing %f and %f\n", a, b);
146 z = a == b; /* zero */
147 n = a != b; /* negative */
148 v = a > b; /* overflow */
150 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
159 a = mv_getRegDouble (SRC1_REG);
160 b = mv_getRegDouble (SRC2_REG);
162 printfdbg ("cfcmpd\n");
163 printfdbg ("\tcomparing %g and %g\n", a, b);
165 z = a == b; /* zero */
166 n = a != b; /* negative */
167 v = a > b; /* overflow */
169 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
178 a = DSPregs[SRC1_REG].upper.f;
179 b = DSPregs[SRC2_REG].upper.f;
181 printfdbg ("cfcmps\n");
182 printfdbg ("\tcomparing %f and %f\n", a, b);
184 z = a == b; /* zero */
185 n = a < b; /* negative */
186 c = a > b; /* carry */
188 printfdbg ("\tz = %d, n = %d\n", z, n);
189 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
198 a = mv_getRegDouble (SRC1_REG);
199 b = mv_getRegDouble (SRC2_REG);
201 printfdbg ("cfcmpd\n");
202 printfdbg ("\tcomparing %g and %g\n", a, b);
204 z = a == b; /* zero */
205 n = a < b; /* negative */
206 c = a > b; /* carry */
208 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
213 fprintf (stderr, "unknown opcode in DSPMRC4 0x%x\n", instr);
214 cirrus_not_implemented ("unknown");
222 DSPMRC5 (ARMul_State * state ATTRIBUTE_UNUSED,
223 unsigned type ATTRIBUTE_UNUSED,
229 case 0: /* cfmvr64l */
230 /* Move lower half of 64bit int from Cirrus to Arm. */
231 *value = (ARMword) DSPregs[SRC1_REG].lower.i;
232 printfdbg ("cfmvr64l ARM_REG = mvfx%d <-- %d\n",
237 case 1: /* cfmvr64h */
238 /* Move upper half of 64bit int from Cirrus to Arm. */
239 *value = (ARMword) DSPregs[SRC1_REG].upper.i;
240 printfdbg ("cfmvr64h <-- %d\n", (int) *value);
243 case 4: /* cfcmp32 */
249 printfdbg ("cfcmp32 mvfx%d - mvfx%d\n",
253 /* FIXME: see comment for cfcmps. */
254 a = DSPregs[SRC1_REG].lower.i;
255 b = DSPregs[SRC2_REG].lower.i;
257 res = DSPregs[SRC1_REG].lower.i - DSPregs[SRC2_REG].lower.i;
263 v = SubOverflow (DSPregs[SRC1_REG].lower.i, DSPregs[SRC2_REG].lower.i,
266 c = (NEG (a) && POS (b))
267 || (NEG (a) && POS (res))
268 || (POS (b) && POS (res));
270 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
274 case 5: /* cfcmp64 */
278 unsigned long long a, b;
280 printfdbg ("cfcmp64 mvdx%d - mvdx%d\n",
284 /* fixme: see comment for cfcmps. */
286 a = mv_getReg64int (SRC1_REG);
287 b = mv_getReg64int (SRC2_REG);
289 res = mv_getReg64int (SRC1_REG) - mv_getReg64int (SRC2_REG);
295 v = ((NEG64 (a) && POS64 (b) && POS64 (res))
296 || (POS64 (a) && NEG64 (b) && NEG64 (res)));
298 c = (NEG64 (a) && POS64 (b))
299 || (NEG64 (a) && POS64 (res))
300 || (POS64 (b) && POS64 (res));
302 *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
307 fprintf (stderr, "unknown opcode in DSPMRC5 0x%x\n", instr);
308 cirrus_not_implemented ("unknown");
316 DSPMRC6 (ARMul_State * state ATTRIBUTE_UNUSED,
317 unsigned type ATTRIBUTE_UNUSED,
323 case 0: /* cfmval32 */
324 cirrus_not_implemented ("cfmval32");
327 case 1: /* cfmvam32 */
328 cirrus_not_implemented ("cfmvam32");
331 case 2: /* cfmvah32 */
332 cirrus_not_implemented ("cfmvah32");
335 case 3: /* cfmva32 */
336 cirrus_not_implemented ("cfmva32");
339 case 4: /* cfmva64 */
340 cirrus_not_implemented ("cfmva64");
343 case 5: /* cfmvsc32 */
344 cirrus_not_implemented ("cfmvsc32");
348 fprintf (stderr, "unknown opcode in DSPMRC6 0x%x\n", instr);
349 cirrus_not_implemented ("unknown");
357 DSPMCR4 (ARMul_State * state,
358 unsigned type ATTRIBUTE_UNUSED,
364 case 0: /* cfmvdlr */
365 /* Move the lower half of a DF value from an Arm register into
366 the lower half of a Cirrus register. */
367 printfdbg ("cfmvdlr <-- 0x%x\n", (int) value);
368 DSPregs[SRC1_REG].lower.i = (int) value;
371 case 1: /* cfmvdhr */
372 /* Move the upper half of a DF value from an Arm register into
373 the upper half of a Cirrus register. */
374 printfdbg ("cfmvdhr <-- 0x%x\n", (int) value);
375 DSPregs[SRC1_REG].upper.i = (int) value;
379 /* Move SF from Arm register into upper half of Cirrus register. */
380 printfdbg ("cfmvsr <-- 0x%x\n", (int) value);
381 DSPregs[SRC1_REG].upper.i = (int) value;
385 fprintf (stderr, "unknown opcode in DSPMCR4 0x%x\n", instr);
386 cirrus_not_implemented ("unknown");
394 DSPMCR5 (ARMul_State * state,
395 unsigned type ATTRIBUTE_UNUSED,
407 case 0: /* cfmv64lr */
408 /* Move lower half of a 64bit int from an ARM register into the
409 lower half of a DSP register and sign extend it. */
410 printfdbg ("cfmv64lr mvdx%d <-- 0x%x\n", SRC1_REG, (int) value);
411 DSPregs[SRC1_REG].lower.i = (int) value;
414 case 1: /* cfmv64hr */
415 /* Move upper half of a 64bit int from an ARM register into the
416 upper half of a DSP register. */
417 printfdbg ("cfmv64hr ARM_REG = mvfx%d <-- 0x%x\n",
420 DSPregs[SRC1_REG].upper.i = (int) value;
423 case 2: /* cfrshl32 */
424 printfdbg ("cfrshl32\n");
427 DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i << value;
429 DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -value;
432 case 3: /* cfrshl64 */
433 printfdbg ("cfrshl64\n");
436 mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) << value);
438 mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) >> -value);
442 fprintf (stderr, "unknown opcode in DSPMCR5 0x%x\n", instr);
443 cirrus_not_implemented ("unknown");
451 DSPMCR6 (ARMul_State * state,
452 unsigned type ATTRIBUTE_UNUSED,
458 case 0: /* cfmv32al */
459 cirrus_not_implemented ("cfmv32al");
462 case 1: /* cfmv32am */
463 cirrus_not_implemented ("cfmv32am");
466 case 2: /* cfmv32ah */
467 cirrus_not_implemented ("cfmv32ah");
470 case 3: /* cfmv32a */
471 cirrus_not_implemented ("cfmv32a");
474 case 4: /* cfmv64a */
475 cirrus_not_implemented ("cfmv64a");
478 case 5: /* cfmv32sc */
479 cirrus_not_implemented ("cfmv32sc");
483 fprintf (stderr, "unknown opcode in DSPMCR6 0x%x\n", instr);
484 cirrus_not_implemented ("unknown");
492 DSPLDC4 (ARMul_State * state ATTRIBUTE_UNUSED,
497 static unsigned words;
499 if (type != ARMul_DATA)
506 { /* it's a long access, get two words */
509 printfdbg ("cfldrd: %x (words = %d) (bigend = %d) DESTREG = %d\n",
510 data, words, state->bigendSig, DEST_REG);
514 if (state->bigendSig)
515 DSPregs[DEST_REG].upper.i = (int) data;
517 DSPregs[DEST_REG].lower.i = (int) data;
521 if (state->bigendSig)
522 DSPregs[DEST_REG].lower.i = (int) data;
524 DSPregs[DEST_REG].upper.i = (int) data;
531 printfdbg ("\tmvd%d <-- mem = %g\n", DEST_REG,
532 mv_getRegDouble (DEST_REG));
541 /* Get just one word. */
544 printfdbg ("cfldrs\n");
546 DSPregs[DEST_REG].upper.i = (int) data;
548 printfdbg ("\tmvf%d <-- mem = %f\n", DEST_REG,
549 DSPregs[DEST_REG].upper.f);
556 DSPLDC5 (ARMul_State * state ATTRIBUTE_UNUSED,
561 static unsigned words;
563 if (type != ARMul_DATA)
571 /* It's a long access, get two words. */
574 printfdbg ("cfldr64: %d\n", data);
578 if (state->bigendSig)
579 DSPregs[DEST_REG].upper.i = (int) data;
581 DSPregs[DEST_REG].lower.i = (int) data;
585 if (state->bigendSig)
586 DSPregs[DEST_REG].lower.i = (int) data;
588 DSPregs[DEST_REG].upper.i = (int) data;
595 printfdbg ("\tmvdx%d <-- mem = %lld\n", DEST_REG,
596 mv_getReg64int (DEST_REG));
605 /* Get just one word. */
608 printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data);
610 /* 32bit ints should be sign extended to 64bits when loaded. */
611 mv_setReg64int (DEST_REG, (long long) data);
618 DSPSTC4 (ARMul_State * state ATTRIBUTE_UNUSED,
623 static unsigned words;
625 if (type != ARMul_DATA)
633 /* It's a long access, get two words. */
635 printfdbg ("cfstrd\n");
639 if (state->bigendSig)
640 *data = (ARMword) DSPregs[DEST_REG].upper.i;
642 *data = (ARMword) DSPregs[DEST_REG].lower.i;
646 if (state->bigendSig)
647 *data = (ARMword) DSPregs[DEST_REG].lower.i;
649 *data = (ARMword) DSPregs[DEST_REG].upper.i;
656 printfdbg ("\tmem = mvd%d = %g\n", DEST_REG,
657 mv_getRegDouble (DEST_REG));
666 /* Get just one word. */
668 printfdbg ("cfstrs mvf%d <-- %f\n", DEST_REG,
669 DSPregs[DEST_REG].upper.f);
671 *data = (ARMword) DSPregs[DEST_REG].upper.i;
678 DSPSTC5 (ARMul_State * state ATTRIBUTE_UNUSED,
683 static unsigned words;
685 if (type != ARMul_DATA)
693 /* It's a long access, store two words. */
695 printfdbg ("cfstr64\n");
699 if (state->bigendSig)
700 *data = (ARMword) DSPregs[DEST_REG].upper.i;
702 *data = (ARMword) DSPregs[DEST_REG].lower.i;
706 if (state->bigendSig)
707 *data = (ARMword) DSPregs[DEST_REG].lower.i;
709 *data = (ARMword) DSPregs[DEST_REG].upper.i;
716 printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG,
717 mv_getReg64int (DEST_REG));
726 /* Store just one word. */
728 *data = (ARMword) DSPregs[DEST_REG].lower.i;
730 printfdbg ("cfstr32 MEM = %d\n", (int) *data);
737 DSPCDP4 (ARMul_State * state,
743 opcode2 = BITS (5,7);
745 switch (BITS (20,21))
751 printfdbg ("cfcpys mvf%d = mvf%d = %f\n",
754 DSPregs[SRC1_REG].upper.f);
755 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f;
759 printfdbg ("cfcpyd mvd%d = mvd%d = %g\n",
762 mv_getRegDouble (SRC1_REG));
763 mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG));
766 case 2: /* cfcvtds */
767 printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n",
770 (float) mv_getRegDouble (SRC1_REG));
771 DSPregs[DEST_REG].upper.f = (float) mv_getRegDouble (SRC1_REG);
774 case 3: /* cfcvtsd */
775 printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n",
778 (double) DSPregs[SRC1_REG].upper.f);
779 mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].upper.f);
782 case 4: /* cfcvt32s */
783 printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n",
786 (float) DSPregs[SRC1_REG].lower.i);
787 DSPregs[DEST_REG].upper.f = (float) DSPregs[SRC1_REG].lower.i;
790 case 5: /* cfcvt32d */
791 printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n",
794 (double) DSPregs[SRC1_REG].lower.i);
795 mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].lower.i);
798 case 6: /* cfcvt64s */
799 printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n",
802 (float) mv_getReg64int (SRC1_REG));
803 DSPregs[DEST_REG].upper.f = (float) mv_getReg64int (SRC1_REG);
806 case 7: /* cfcvt64d */
807 printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n",
810 (double) mv_getReg64int (SRC1_REG));
811 mv_setRegDouble (DEST_REG, (double) mv_getReg64int (SRC1_REG));
820 printfdbg ("cfmuls mvf%d = mvf%d = %f\n",
823 DSPregs[SRC1_REG].upper.f * DSPregs[SRC2_REG].upper.f);
825 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
826 * DSPregs[SRC2_REG].upper.f;
830 printfdbg ("cfmuld mvd%d = mvd%d = %g\n",
833 mv_getRegDouble (SRC1_REG) * mv_getRegDouble (SRC2_REG));
835 mv_setRegDouble (DEST_REG,
836 mv_getRegDouble (SRC1_REG)
837 * mv_getRegDouble (SRC2_REG));
841 fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
842 cirrus_not_implemented ("unknown");
851 DSPregs[DEST_REG].upper.f = (DSPregs[SRC1_REG].upper.f < 0.0F ?
852 -DSPregs[SRC1_REG].upper.f
853 : DSPregs[SRC1_REG].upper.f);
854 printfdbg ("cfabss mvf%d = |mvf%d| = %f\n",
857 DSPregs[DEST_REG].upper.f);
861 mv_setRegDouble (DEST_REG,
862 (mv_getRegDouble (SRC1_REG) < 0.0 ?
863 -mv_getRegDouble (SRC1_REG)
864 : mv_getRegDouble (SRC1_REG)));
865 printfdbg ("cfabsd mvd%d = |mvd%d| = %g\n",
868 mv_getRegDouble (DEST_REG));
872 DSPregs[DEST_REG].upper.f = -DSPregs[SRC1_REG].upper.f;
873 printfdbg ("cfnegs mvf%d = -mvf%d = %f\n",
876 DSPregs[DEST_REG].upper.f);
880 mv_setRegDouble (DEST_REG,
881 -mv_getRegDouble (SRC1_REG));
882 printfdbg ("cfnegd mvd%d = -mvd%d = %g\n",
884 mv_getRegDouble (DEST_REG));
888 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
889 + DSPregs[SRC2_REG].upper.f;
890 printfdbg ("cfadds mvf%d = mvf%d + mvf%d = %f\n",
894 DSPregs[DEST_REG].upper.f);
898 mv_setRegDouble (DEST_REG,
899 mv_getRegDouble (SRC1_REG)
900 + mv_getRegDouble (SRC2_REG));
901 printfdbg ("cfaddd: mvd%d = mvd%d + mvd%d = %g\n",
905 mv_getRegDouble (DEST_REG));
909 DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
910 - DSPregs[SRC2_REG].upper.f;
911 printfdbg ("cfsubs: mvf%d = mvf%d - mvf%d = %f\n",
915 DSPregs[DEST_REG].upper.f);
919 mv_setRegDouble (DEST_REG,
920 mv_getRegDouble (SRC1_REG)
921 - mv_getRegDouble (SRC2_REG));
922 printfdbg ("cfsubd: mvd%d = mvd%d - mvd%d = %g\n",
926 mv_getRegDouble (DEST_REG));
932 fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
933 cirrus_not_implemented ("unknown");
941 DSPCDP5 (ARMul_State * state,
948 opcode2 = BITS (5,7);
950 /* Shift constants are 7bit signed numbers in bits 0..3|5..7. */
951 shift = BITS (0, 3) | (BITS (5, 7)) << 4;
955 switch (BITS (20,21))
959 printfdbg ("cfsh32 %s amount=%d\n", shift < 0 ? "right" : "left",
962 /* Negative shift is a right shift. */
963 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -shift;
965 /* Positive shift is a left shift. */
966 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i << shift;
972 case 0: /* cfmul32 */
973 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
974 * DSPregs[SRC2_REG].lower.i;
975 printfdbg ("cfmul32 mvfx%d = mvfx%d * mvfx%d = %d\n",
979 DSPregs[DEST_REG].lower.i);
982 case 1: /* cfmul64 */
983 mv_setReg64int (DEST_REG,
984 mv_getReg64int (SRC1_REG)
985 * mv_getReg64int (SRC2_REG));
986 printfdbg ("cfmul64 mvdx%d = mvdx%d * mvdx%d = %lld\n",
990 mv_getReg64int (DEST_REG));
993 case 2: /* cfmac32 */
994 DSPregs[DEST_REG].lower.i
995 += DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
996 printfdbg ("cfmac32 mvfx%d += mvfx%d * mvfx%d = %d\n",
1000 DSPregs[DEST_REG].lower.i);
1003 case 3: /* cfmsc32 */
1004 DSPregs[DEST_REG].lower.i
1005 -= DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
1006 printfdbg ("cfmsc32 mvfx%d -= mvfx%d * mvfx%d = %d\n",
1010 DSPregs[DEST_REG].lower.i);
1013 case 4: /* cfcvts32 */
1014 /* fixme: this should round */
1015 DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
1016 printfdbg ("cfcvts32 mvfx%d = mvf%d = %d\n",
1019 DSPregs[DEST_REG].lower.i);
1022 case 5: /* cfcvtd32 */
1023 /* fixme: this should round */
1024 DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
1025 printfdbg ("cfcvtd32 mvdx%d = mvd%d = %d\n",
1028 DSPregs[DEST_REG].lower.i);
1031 case 6: /* cftruncs32 */
1032 DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
1033 printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n",
1036 DSPregs[DEST_REG].lower.i);
1039 case 7: /* cftruncd32 */
1040 DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
1041 printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n",
1044 DSPregs[DEST_REG].lower.i);
1051 printfdbg ("cfsh64\n");
1054 /* Negative shift is a right shift. */
1055 mv_setReg64int (DEST_REG,
1056 mv_getReg64int (SRC1_REG) >> -shift);
1058 /* Positive shift is a left shift. */
1059 mv_setReg64int (DEST_REG,
1060 mv_getReg64int (SRC1_REG) << shift);
1061 printfdbg ("\t%llx\n", mv_getReg64int(DEST_REG));
1067 case 0: /* cfabs32 */
1068 DSPregs[DEST_REG].lower.i = (DSPregs[SRC1_REG].lower.i < 0
1069 ? -DSPregs[SRC1_REG].lower.i : DSPregs[SRC1_REG].lower.i);
1070 printfdbg ("cfabs32 mvfx%d = |mvfx%d| = %d\n",
1074 DSPregs[DEST_REG].lower.i);
1077 case 1: /* cfabs64 */
1078 mv_setReg64int (DEST_REG,
1079 (mv_getReg64int (SRC1_REG) < 0
1080 ? -mv_getReg64int (SRC1_REG)
1081 : mv_getReg64int (SRC1_REG)));
1082 printfdbg ("cfabs64 mvdx%d = |mvdx%d| = %lld\n",
1086 mv_getReg64int (DEST_REG));
1089 case 2: /* cfneg32 */
1090 DSPregs[DEST_REG].lower.i = -DSPregs[SRC1_REG].lower.i;
1091 printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n",
1095 DSPregs[DEST_REG].lower.i);
1098 case 3: /* cfneg64 */
1099 mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG));
1100 printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n",
1104 mv_getReg64int (DEST_REG));
1107 case 4: /* cfadd32 */
1108 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
1109 + DSPregs[SRC2_REG].lower.i;
1110 printfdbg ("cfadd32 mvfx%d = mvfx%d + mvfx%d = %d\n",
1114 DSPregs[DEST_REG].lower.i);
1117 case 5: /* cfadd64 */
1118 mv_setReg64int (DEST_REG,
1119 mv_getReg64int (SRC1_REG)
1120 + mv_getReg64int (SRC2_REG));
1121 printfdbg ("cfadd64 mvdx%d = mvdx%d + mvdx%d = %lld\n",
1125 mv_getReg64int (DEST_REG));
1128 case 6: /* cfsub32 */
1129 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
1130 - DSPregs[SRC2_REG].lower.i;
1131 printfdbg ("cfsub32 mvfx%d = mvfx%d - mvfx%d = %d\n",
1135 DSPregs[DEST_REG].lower.i);
1138 case 7: /* cfsub64 */
1139 mv_setReg64int (DEST_REG,
1140 mv_getReg64int (SRC1_REG)
1141 - mv_getReg64int (SRC2_REG));
1142 printfdbg ("cfsub64 mvdx%d = mvdx%d - mvdx%d = %d\n",
1146 mv_getReg64int (DEST_REG));
1152 fprintf (stderr, "unknown opcode in DSPCDP5 0x%x\n", instr);
1153 cirrus_not_implemented ("unknown");
1161 DSPCDP6 (ARMul_State * state,
1165 switch (BITS (20,21))
1169 cirrus_not_implemented ("cfmadd32");
1174 cirrus_not_implemented ("cfmsub32");
1179 cirrus_not_implemented ("cfmadda32");
1184 cirrus_not_implemented ("cfmsuba32");
1188 fprintf (stderr, "unknown opcode in DSPCDP6 0x%x\n", instr);
1194 /* Conversion functions.
1196 32-bit integers are stored in the LOWER half of a 64-bit physical
1199 Single precision floats are stored in the UPPER half of a 64-bit
1200 physical register. */
1203 mv_getRegDouble (int regnum)
1205 reg_conv.ints[lsw_float_index] = DSPregs[regnum].upper.i;
1206 reg_conv.ints[msw_float_index] = DSPregs[regnum].lower.i;
1211 mv_setRegDouble (int regnum, double val)
1214 DSPregs[regnum].upper.i = reg_conv.ints[lsw_float_index];
1215 DSPregs[regnum].lower.i = reg_conv.ints[msw_float_index];
1219 mv_getReg64int (int regnum)
1221 reg_conv.ints[lsw_int_index] = DSPregs[regnum].lower.i;
1222 reg_conv.ints[msw_int_index] = DSPregs[regnum].upper.i;
1227 mv_setReg64int (int regnum, long long val)
1230 DSPregs[regnum].lower.i = reg_conv.ints[lsw_int_index];
1231 DSPregs[regnum].upper.i = reg_conv.ints[msw_int_index];
1234 /* Compute LSW in a double and a long long. */
1237 mv_compute_host_endianness (ARMul_State * state)
1249 /* Calculate where's the LSW in a 64bit int. */
1252 if (conv.ints[0] == 0)
1259 assert (conv.ints[1] == 0);
1264 /* Calculate where's the LSW in a double. */
1267 if (conv.ints[0] == 0)
1269 msw_float_index = 0;
1270 lsw_float_index = 1;
1274 assert (conv.ints[1] == 0);
1275 msw_float_index = 1;
1276 lsw_float_index = 0;
1279 printfdbg ("lsw_int_index %d\n", lsw_int_index);
1280 printfdbg ("lsw_float_index %d\n", lsw_float_index);