This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: Add support for Cirrus EP9312


Hi Guys,

  May I have permission to apply the following patch ?

  It adds support for Cirrus's EP9312 chip, an ARM variant with their
  own floating point co-processor called the Maverick.

Cheers
        Nick

gdb/ChangeLog
2003-02-10  Nick Clifton  <nickc@redhat.com>

	* Contribute support for Cirrus Maverick ARM co-processor:

	2000-06-02  Andrew Cagney  <cagney@b1.cygnus.com>

		* remote-rdi.c (arm_rdi_fetch_registers): Add #ifdef
		COPRO_REGNUM.  Only return those registers when COPRO is
		defined.

	2000-05-30  Jeff Holcomb  <jeffh@cygnus.com>

		* configure.tgt: Add ep9312-elf target for the Cirrus DSP.
		* config/arm/cirrus.mt: New.
		* config/arm/tm-cirrus.h: Ditto.

	Fri May 12 16:20:51 2000  glen mccready  <gkm@pobox.com>

		* arm-tdep.c, remote-rdi.c, config/arm/tm-arm.h:
		Cirrus DSP coprocessor modifications.

include/gdb/ChangeLog
2003-02-10  Nick Clifton  <nickc@redhat.com>

	* sim-arm.h (sim_arm_regs): Add Maverick co-processor
	registers.

sim/arm/ChangeLog
2003-02-10  Nick Clifton  <nickc@redhat.com>

	* Contribute support for Cirrus Maverick ARM co-processor,
        written by Aldy Hernandez  <aldyh@redhat.com> and
        Andrew Cagney  <cagney@redhat.com>:

	* maverick.c: New file: Support for Maverick floating point
	co-processor. 
        * Makefile.in: Add maverick.o target.
        * configure.in (COPRO): Add maverick.o.
        * configure: Regenerate.
        * armcopro.c (ARMul_CoProInit): Only initialise co-processors
	available on target processor.  Add code to initialse Maverick
	co-processor support code.
        * armdefs.h (ARMul_state): Add is_ep9312 field.
        (ARM_ep9312_Prop): Define.
        * armemu.h: Add prototypes for Maverick co-processor
	functions.
        * arminit.c (ARMul_SelectProcessor): Initialise the
	co-processor support once the chip has been selected.
        * wrapper.c: Add support for Maverick co-processor.
        (init): Do not call ARMul_CoProInit.  Delays this until the
	chip has been selected.

Index: gdb/arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.98
diff -c -3 -p -w -r1.98 arm-tdep.c
*** gdb/arm-tdep.c	3 Feb 2003 20:03:00 -0000	1.98
--- gdb/arm-tdep.c	10 Feb 2003 11:52:22 -0000
*************** static char * arm_register_name_strings[
*** 115,121 ****
   "r12", "sp",  "lr",  "pc",	/* 12 13 14 15 */
   "f0",  "f1",  "f2",  "f3",	/* 16 17 18 19 */
   "f4",  "f5",  "f6",  "f7",	/* 20 21 22 23 */
!  "fps", "cpsr" };		/* 24 25       */
  static char **arm_register_names = arm_register_name_strings;
  
  /* Valid register name flavors.  */
--- 115,129 ----
   "r12", "sp",  "lr",  "pc",	/* 12 13 14 15 */
   "f0",  "f1",  "f2",  "f3",	/* 16 17 18 19 */
   "f4",  "f5",  "f6",  "f7",	/* 20 21 22 23 */
!  "fps", "cpsr",  		/* 24 25       */
!  "cr1", "cr2", "cr3", "cr4",	/* 26 27 28 29 */
!  "cr5", "cr6", "cr7", "cr8",	/* 30 31 32 33 */
!  "cr9", "cr10","cr11","cr12",	/* 34 35 36 37 */
!  "cr13","cr14","cr15","cr16",	/* 38 39 40 41 */
!  "dspsc"			/* 42          */
!  /* There are also 4 internal accumulators on the
!     chip that could/should be fetchable/settable.  */
! };
  static char **arm_register_names = arm_register_name_strings;
  
  /* Valid register name flavors.  */
*************** set_disassembly_flavor (void)
*** 2613,2618 ****
--- 2621,2630 ----
    /* Fill our copy.  */
    for (j = 0; j < numregs; j++)
      arm_register_names[j] = (char *) regnames[j];
+ 
+   /* GKM - unfortunate that this swapping of names couldn't have included
+      the cirrus dsp registers since they can flip names depending on the
+      opcode and what's stored in them.  */
  
    /* Adjust case.  */
    if (isupper (*regnames[ARM_PC_REGNUM]))

Index: gdb/configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.98
diff -c -3 -p -w -r1.98 configure.tgt
*** gdb/configure.tgt	5 Feb 2003 23:14:47 -0000	1.98
--- gdb/configure.tgt	10 Feb 2003 11:52:22 -0000
*************** arm*-*-* | thumb*-*-* | strongarm*-*-*)
*** 55,60 ****
--- 55,63 ----
  			gdb_target=embed
                          configdirs="$configdirs rdi-share"
                          ;;
+ ep9312-*-*)		gdb_target=cirrus
+ 			configdirs="$configdirs rdi-share"
+ 			;;
  xscale-*-*)		gdb_target=embed
                          configdirs="$configdirs rdi-share"
                          ;;

Index: gdb/remote-rdi.c
===================================================================
RCS file: /cvs/src/src/gdb/remote-rdi.c,v
retrieving revision 1.25
diff -c -3 -p -w -r1.25 remote-rdi.c
*** gdb/remote-rdi.c	2 Nov 2002 14:59:10 -0000	1.25
--- gdb/remote-rdi.c	10 Feb 2003 11:52:24 -0000
*************** arm_rdi_fetch_registers (int regno)
*** 548,553 ****
--- 548,569 ----
        store_unsigned_integer (cookedreg, 4, rawregs[15]);
        supply_register (ARM_PS_REGNUM, (char *) cookedreg);
        arm_rdi_fetch_registers (ARM_PC_REGNUM);
+ 
+ #ifdef COPRO_REGNUM
+       for (regno = COPRO_REGNUM; regno <= NUM_REGS; regno++)
+ 	{
+ 	  /* This code has not been tested; we don't have hardware.  */
+ 	  char regval[8];
+ 	  unsigned long mask;
+ 
+ 	  mask = 1 << regno;
+ 	  angel_RDI_CPread (0, mask, (ARMword *) & regval);
+           if (rslt)
+ 	    printf_filtered ("RDI_CPread: %s\n", rdi_error_message (rslt));
+ 
+ 	  supply_register (regno, (char *) regval);
+ 	}
+ #endif
      }
    else
      {
*************** arm_rdi_fetch_registers (int regno)
*** 557,562 ****
--- 573,594 ----
  	rdi_regmask = RDIReg_CPSR;
        else if (regno < 0 || regno > 15)
  	{
+ #ifdef COPRO_REGNUM
+ 	  if (regno >= COPRO_REGNUM && regno <= NUM_REGS)
+ 	    {
+ 	      /* This code has not been tested; we don't have hardware.  */
+ 	      char regval[8];
+ 	      unsigned long mask;
+ 
+ 	      mask = 1 << regno;
+ 	      rslt = angel_RDI_CPread (0, mask, (ARMword *) & regval);
+               if (rslt)
+ 		printf_filtered ("RDI_CPread: %s\n", rdi_error_message (rslt));
+ 
+ 	      supply_register (regno, (char *) regval);
+ 	      return;
+ 	    }
+ #endif
  	  rawreg = 0;
  	  supply_register (regno, (char *) &rawreg);
  	  return;
*************** arm_rdi_store_registers (int regno)
*** 598,603 ****
--- 630,652 ----
      }
    else
      {
+ #ifdef COPRO_REGNUM
+       if (regno >= COPRO_REGNUM && regno <= NUM_REGS)
+ 	{
+ 	  /* This code has not been tested; we don't have hardware.  */
+ 	  char regval[8];
+ 	  unsigned long mask;
+ 
+ 	  mask = 1 << regno;
+ 	  deprecated_read_register_gen (regno, (char *) regval);
+ 	  /* byte ordering? */
+ 	  rslt = angel_RDI_CPwrite (0, mask, (ARMword *) regval);
+           if (rslt)
+ 	    printf_filtered ("RDI_CPwrite: %s\n", rdi_error_message (rslt));
+ 
+ 	  return;
+ 	}
+ #endif
        deprecated_read_register_gen (regno, (char *) rawreg);
        /* RDI manipulates data in host byte order, so convert now. */
        store_unsigned_integer (rawerreg, 4, rawreg[0]);

*** /dev/null	Sat Oct 19 15:41:17 2002
--- gdb/config/arm/cirrus.mt	Sat Feb  8 11:28:47 2003
***************
*** 0 ****
--- 1,7 ----
+ # Target: ARM embedded system
+ TDEPFILES= arm-tdep.o remote-rdp.o remote-rdi.o
+ TDEPLIBS= rdi-share/libangsd.a
+ TM_FILE= tm-cirrus.h
+ 
+ SIM_OBS = remote-sim.o
+ SIM = ../sim/arm/libsim.a
*** /dev/null	Sat Oct 19 15:41:17 2002
--- gdb/config/arm/tm-cirrus.h	Sat Feb  8 11:30:04 2003
***************
*** 0 ****
--- 1,89 ----
+ /* Definitions to target GDB for Cirrus
+    Copyright 2003 Free Software Foundation, Inc.
+ 
+    Contributed by Red Hat.
+    
+    This file is part of GDB.
+ 
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+ 
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #ifndef TM_CIRRUS_H
+ #define TM_CIRRUS_H
+ 
+ #include "arm/tm-embed.h"
+ 
+ #undef  TARGET_DOUBLE_FORMAT
+ #define TARGET_DOUBLE_FORMAT  (target_byte_order == BFD_ENDIAN_BIG \
+ 			       ? & floatformat_ieee_double_big    \
+ 			       : & floatformat_ieee_double_little)
+ 
+ /* Co-processors can be used directly with the ARM chips; this should
+    define the size of the copros registers.  */
+ 
+ #define COPRO_REGISTER_SIZE	8
+ 
+ #define COPRO_REGISTER_TYPE	builtin_type_int64
+ 
+ #define NUM_COPRO_REGS		(16 + 1)
+ 
+ #undef  NUM_REGS
+ #define NUM_REGS	(NUM_GREGS + NUM_FREGS + NUM_SREGS + NUM_COPRO_REGS)
+ 
+ #define COPRO_REGNUM	26	/* Start listing coprocessor registers...  */
+ #define DSPSC_REGNUM	42
+ 
+ #undef  REGISTER_BYTES
+ #define REGISTER_BYTES ((NUM_GREGS * REGISTER_SIZE) + \
+ 			(NUM_FREGS * FP_REGISTER_RAW_SIZE) + \
+ 			(NUM_SREGS * STATUS_REGISTER_SIZE) + \
+ 			(NUM_COPRO_REGS * COPRO_REGISTER_SIZE))
+ 
+ #undef  REGISTER_BYTE
+ #define REGISTER_BYTE(N) \
+      ((N) < F0_REGNUM  \
+         ? (N) * REGISTER_SIZE \
+         : ((N) < PS_REGNUM \
+            ? (NUM_GREGS * REGISTER_SIZE + ((N) - F0_REGNUM) * \
+               FP_REGISTER_RAW_SIZE) \
+            : ((N) < COPRO_REGNUM \
+               ? (NUM_GREGS * REGISTER_SIZE + NUM_FREGS * \
+                  FP_REGISTER_RAW_SIZE + ((N) - FPS_REGNUM) * \
+                  STATUS_REGISTER_SIZE) \
+               : (NUM_GREGS * REGISTER_SIZE + NUM_FREGS * \
+                  FP_REGISTER_RAW_SIZE + ((N) - FPS_REGNUM) * \
+                  STATUS_REGISTER_SIZE + ((N) - COPRO_REGNUM) * \
+                  COPRO_REGISTER_SIZE))))
+ 
+ #undef  REGISTER_RAW_SIZE
+ #define REGISTER_RAW_SIZE(N) \
+      ((N) < F0_REGNUM ? REGISTER_SIZE : \
+       (N) < FPS_REGNUM ? FP_REGISTER_RAW_SIZE : \
+       (N) < COPRO_REGNUM ? STATUS_REGISTER_SIZE : COPRO_REGISTER_SIZE)
+ 
+ #undef  REGISTER_VIRTUAL_SIZE
+ #define REGISTER_VIRTUAL_SIZE(N) \
+         ((N) < F0_REGNUM ? REGISTER_SIZE : \
+          (N) < FPS_REGNUM ? FP_REGISTER_VIRTUAL_SIZE : \
+          (N) < COPRO_REGNUM ? STATUS_REGISTER_SIZE : COPRO_REGISTER_SIZE)
+ 
+ #undef  REGISTER_VIRTUAL_TYPE
+ #define REGISTER_VIRTUAL_TYPE(N) \
+      (((unsigned)(N) - F0_REGNUM) < NUM_FREGS \
+       ? builtin_type_double : \
+       ((unsigned)(N) < COPRO_REGNUM) \
+         ? builtin_type_int : COPRO_REGISTER_TYPE)
+ 
+ #endif /* TM_CIRRUS_H */

Index: include/gdb/sim-arm.h
===================================================================
RCS file: /cvs/src/src/include/gdb/sim-arm.h,v
retrieving revision 1.2
diff -c -3 -p -w -r1.2 sim-arm.h
*** include/gdb/sim-arm.h	15 Jun 2002 22:49:38 -0000	1.2
--- include/gdb/sim-arm.h	10 Feb 2003 11:52:15 -0000
*************** enum sim_arm_regs
*** 55,61 ****
    SIM_ARM_FP6_REGNUM,
    SIM_ARM_FP7_REGNUM,
    SIM_ARM_FPS_REGNUM,
!   SIM_ARM_PS_REGNUM
  };
  
  #ifdef __cplusplus
--- 55,78 ----
    SIM_ARM_FP6_REGNUM,
    SIM_ARM_FP7_REGNUM,
    SIM_ARM_FPS_REGNUM,
!   SIM_ARM_PS_REGNUM,
!   SIM_ARM_MAVERIC_COP0R0_REGNUM,
!   SIM_ARM_MAVERIC_COP0R1_REGNUM,
!   SIM_ARM_MAVERIC_COP0R2_REGNUM,
!   SIM_ARM_MAVERIC_COP0R3_REGNUM,
!   SIM_ARM_MAVERIC_COP0R4_REGNUM,
!   SIM_ARM_MAVERIC_COP0R5_REGNUM,
!   SIM_ARM_MAVERIC_COP0R6_REGNUM,
!   SIM_ARM_MAVERIC_COP0R7_REGNUM,
!   SIM_ARM_MAVERIC_COP0R8_REGNUM,
!   SIM_ARM_MAVERIC_COP0R9_REGNUM,
!   SIM_ARM_MAVERIC_COP0R10_REGNUM,
!   SIM_ARM_MAVERIC_COP0R11_REGNUM,
!   SIM_ARM_MAVERIC_COP0R12_REGNUM,
!   SIM_ARM_MAVERIC_COP0R13_REGNUM,
!   SIM_ARM_MAVERIC_COP0R14_REGNUM,
!   SIM_ARM_MAVERIC_COP0R15_REGNUM,
!   SIM_ARM_MAVERIC_DSPSC_REGNUM
  };
  
  #ifdef __cplusplus

Index: sim/arm/Makefile.in
===================================================================
RCS file: /cvs/src/src/sim/arm/Makefile.in,v
retrieving revision 1.5
diff -c -3 -p -w -r1.5 Makefile.in
*** sim/arm/Makefile.in	12 Jun 2002 21:19:43 -0000	1.5
--- sim/arm/Makefile.in	10 Feb 2003 11:52:08 -0000
*************** SIM_OBJS = armemu26.o armemu32.o arminit
*** 31,36 ****
--- 31,37 ----
  armos.o: armos.c armdefs.h armos.h armfpe.h
  
  armcopro.o: armcopro.c armdefs.h
+ maverick.o: maverick.c armdefs.h
  
  armemu26.o: armemu.c armdefs.h armemu.h 
  	$(CC) -c $(srcdir)/armemu.c -o armemu26.o $(ALL_CFLAGS)

Index: sim/arm/armcopro.c
===================================================================
RCS file: /cvs/src/src/sim/arm/armcopro.c,v
retrieving revision 1.10
diff -c -3 -p -w -r1.10 armcopro.c
*** sim/arm/armcopro.c	29 May 2002 19:01:36 -0000	1.10
--- sim/arm/armcopro.c	10 Feb 2003 11:52:08 -0000
*************** ARMul_CoProInit (ARMul_State * state)
*** 1328,1342 ****
  			MRC routine, MCR routine,
                          CDP routine,
  			Read Reg routine, Write Reg routine).  */
    ARMul_CoProAttach (state, 4, NULL, NULL,
  		     ValLDC, ValSTC, ValMRC, ValMCR, ValCDP, NULL, NULL);
  
    ARMul_CoProAttach (state, 5, NULL, NULL,
  		     NULL, NULL, ValMRC, ValMCR, IntCDP, NULL, NULL);
  
!   ARMul_CoProAttach (state, 15, MMUInit, NULL,
! 		     NULL, NULL, MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
! 
    ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL,
  		     XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC,
  		     XScale_cp13_MCR, NULL, XScale_cp13_read_reg,
--- 1328,1353 ----
  			MRC routine, MCR routine,
                          CDP routine,
  			Read Reg routine, Write Reg routine).  */
+   if (state->is_ep9312)
+     {
+       ARMul_CoProAttach (state, 4, NULL, NULL,
+ 			 DSPLDC4, DSPSTC4, DSPMRC4, DSPMCR4, DSPCDP4, NULL, NULL);
+       ARMul_CoProAttach (state, 5, NULL, NULL,
+ 			 DSPLDC5, DSPSTC5, DSPMRC5, DSPMCR5, DSPCDP5, NULL, NULL);
+       ARMul_CoProAttach (state, 6, NULL, NULL,
+ 			 NULL, NULL, DSPMRC6, DSPMCR6, DSPCDP6, NULL, NULL);
+     }
+   else
+     {
        ARMul_CoProAttach (state, 4, NULL, NULL,
  			 ValLDC, ValSTC, ValMRC, ValMCR, ValCDP, NULL, NULL);
  
        ARMul_CoProAttach (state, 5, NULL, NULL,
  			 NULL, NULL, ValMRC, ValMCR, IntCDP, NULL, NULL);
+     }
  
!   if (state->is_XScale)
!     {
        ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL,
  			 XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC,
  			 XScale_cp13_MCR, NULL, XScale_cp13_read_reg,
*************** ARMul_CoProInit (ARMul_State * state)
*** 1350,1355 ****
--- 1361,1372 ----
        ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL,
  			 NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR,
  			 NULL, XScale_cp15_read_reg, XScale_cp15_write_reg);
+     }
+   else
+     {
+       ARMul_CoProAttach (state, 15, MMUInit, NULL,
+ 			 NULL, NULL, MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
+     }
  
    /* No handlers below here.  */
  
Index: sim/arm/armdefs.h
===================================================================
RCS file: /cvs/src/src/sim/arm/armdefs.h,v
retrieving revision 1.9
diff -c -3 -p -w -r1.9 armdefs.h
*** sim/arm/armdefs.h	18 Apr 2001 16:39:37 -0000	1.9
--- sim/arm/armdefs.h	10 Feb 2003 11:52:09 -0000
*************** struct ARMul_State
*** 135,140 ****
--- 135,141 ----
    unsigned is_v5;		/* Are we emulating a v5 architecture ?  */
    unsigned is_v5e;		/* Are we emulating a v5e architecture ?  */
    unsigned is_XScale;		/* Are we emulating an XScale architecture ?  */
+   unsigned is_ep9312;		/* Are we emulating a Cirrus Maverick co-processor ?  */
    unsigned verbose;		/* Print various messages like the banner */
  };
  
*************** struct ARMul_State
*** 162,167 ****
--- 163,169 ----
  #define ARM_v5_Prop      0x80
  #define ARM_v5e_Prop     0x100
  #define ARM_XScale_Prop  0x200
+ #define ARM_ep9312_Prop  0x400
  
  /***************************************************************************\
  *                   Macros to extract instruction fields                    *

Index: sim/arm/armemu.h
===================================================================
RCS file: /cvs/src/src/sim/arm/armemu.h,v
retrieving revision 1.14
diff -c -3 -p -w -r1.14 armemu.h
*** sim/arm/armemu.h	10 Jan 2002 11:14:57 -0000	1.14
--- sim/arm/armemu.h	10 Feb 2003 11:52:09 -0000
*************** extern void     ARMul_CoProAttach   (ARM
*** 530,532 ****
--- 530,548 ----
  extern void     ARMul_CoProDetach   (ARMul_State *, unsigned);
  extern ARMword  read_cp15_reg       (unsigned, unsigned, unsigned);
  
+ extern unsigned DSPLDC4 (ARMul_State *, unsigned, ARMword, ARMword);
+ extern unsigned DSPMCR4 (ARMul_State *, unsigned, ARMword, ARMword);
+ extern unsigned DSPMRC4 (ARMul_State *, unsigned, ARMword, ARMword *);
+ extern unsigned	DSPSTC4 (ARMul_State *, unsigned, ARMword, ARMword *);
+ extern unsigned	DSPCDP4 (ARMul_State *, unsigned, ARMword);
+ extern unsigned DSPMCR5 (ARMul_State *, unsigned, ARMword, ARMword);
+ extern unsigned DSPMRC5 (ARMul_State *, unsigned, ARMword, ARMword *);
+ extern unsigned DSPLDC5 (ARMul_State *, unsigned, ARMword, ARMword);
+ extern unsigned	DSPSTC5 (ARMul_State *, unsigned, ARMword, ARMword *);
+ extern unsigned	DSPCDP5 (ARMul_State *, unsigned, ARMword);
+ extern unsigned DSPMCR6 (ARMul_State *, unsigned, ARMword, ARMword);
+ extern unsigned DSPMRC6 (ARMul_State *, unsigned, ARMword, ARMword *);
+ extern unsigned	DSPCDP6 (ARMul_State *, unsigned, ARMword);

Index: sim/arm/arminit.c
===================================================================
RCS file: /cvs/src/src/sim/arm/arminit.c,v
retrieving revision 1.8
diff -c -3 -p -w -r1.8 arminit.c
*** sim/arm/arminit.c	10 Jan 2002 11:14:57 -0000	1.8
--- sim/arm/arminit.c	10 Feb 2003 11:52:10 -0000
*************** ARMul_SelectProcessor (ARMul_State * sta
*** 157,162 ****
--- 157,167 ----
    state->is_v5 = (properties & ARM_v5_Prop) ? HIGH : LOW;
    state->is_v5e = (properties & ARM_v5e_Prop) ? HIGH : LOW;
    state->is_XScale = (properties & ARM_XScale_Prop) ? HIGH : LOW;
+   state->is_ep9312 = (properties & ARM_ep9312_Prop) ? HIGH : LOW;
+ 
+   /* Only initialse the coprocessor support once we
+      know what kind of chip we are dealing with.  */
+   ARMul_CoProInit (state);
  }
  
  /***************************************************************************\
  
Index: sim/arm/configure.in
===================================================================
RCS file: /cvs/src/src/sim/arm/configure.in,v
retrieving revision 1.2
diff -c -3 -p -w -r1.2 configure.in
*** sim/arm/configure.in	30 May 2000 17:13:37 -0000	1.2
--- sim/arm/configure.in	10 Feb 2003 11:52:13 -0000
*************** SIM_AC_COMMON
*** 7,13 ****
  
  AC_CHECK_HEADERS(unistd.h)
  
! COPRO=armcopro.o
  AC_SUBST(COPRO)
  
  SIM_AC_OUTPUT
--- 7,14 ----
  
  AC_CHECK_HEADERS(unistd.h)
  
! COPRO="armcopro.o maverick.o"
! 
  AC_SUBST(COPRO)
  
  SIM_AC_OUTPUT

Index: sim/arm/wrapper.c
===================================================================
RCS file: /cvs/src/src/sim/arm/wrapper.c,v
retrieving revision 1.23
diff -c -3 -p -w -r1.23 wrapper.c
*** sim/arm/wrapper.c	27 Sep 2002 23:57:50 -0000	1.23
--- sim/arm/wrapper.c	10 Feb 2003 11:52:13 -0000
*************** static int big_endian;
*** 59,64 ****
--- 59,96 ----
  
  int stop_simulator;
  
+ /* Cirrus DSP registers.
+ 
+    We need to define these registers outside of maverick.c because
+    maverick.c might not be linked in unless --target=arm9e-* in which
+    case wrapper.c will not compile because it tries to access Cirrus
+    registers.  This should all go away once we get the Cirrus and ARM
+    Coprocessor to coexist in armcopro.c-- aldyh.  */
+ 
+ struct maverick_regs
+ {
+   union
+   {
+     int i;
+     float f;
+   } upper;
+   
+   union
+   {
+     int i;
+     float f;
+   } lower;
+ };
+ 
+ union maverick_acc_regs
+ {
+   long double ld;		/* Acc registers are 72-bits.  */
+ };
+ 
+ struct maverick_regs     DSPregs[16];
+ union maverick_acc_regs  DSPacc[4];
+ ARMword DSPsc;
+ 
  static void
  init ()
  {
*************** init ()
*** 71,77 ****
        state->bigendSig = (big_endian ? HIGH : LOW);
        ARMul_MemoryInit (state, mem_size);
        ARMul_OSInit (state);
-       ARMul_CoProInit (state);
        state->verbose = verbosity;
        done = 1;
      }
--- 103,108 ----
*************** sim_create_inferior (sd, abfd, argv, env
*** 250,255 ****
--- 281,290 ----
  	}
        /* Otherwise drop through.  */
  
+     case bfd_mach_arm_ep9312:
+       ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop);
+       break;
+ 
      case bfd_mach_arm_5T:
        ARMul_SelectProcessor (state, ARM_v5_Prop);
        break;
*************** sim_store_register (sd, rn, memory, leng
*** 422,427 ****
--- 457,486 ----
        ARMul_CPSRAltered (state);
        break;
  
+     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
+       memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
+ 	      memory, sizeof (struct maverick_regs));
+       return sizeof (struct maverick_regs);
+ 
+     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
+       memcpy (&DSPsc, memory, sizeof DSPsc);
+       return sizeof DSPsc;
+ 
      default:
        return 0;
      }
*************** sim_fetch_register (sd, rn, memory, leng
*** 476,481 ****
--- 535,564 ----
      case SIM_ARM_PS_REGNUM:
        regval = ARMul_GetCPSR (state);
        break;
+ 
+     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
+     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
+       memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
+ 	      sizeof (struct maverick_regs));
+       return sizeof (struct maverick_regs);
+ 
+     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
+       memcpy (memory, & DSPsc, sizeof DSPsc);
+       return sizeof DSPsc;
  
      default:
        return 0;
*** /dev/null	Sat Oct 19 15:41:17 2002
--- sim/arm/maverick.c	Sat Feb  8 12:58:09 2003
***************
*** 0 ****
--- 1,1291 ----
+ /*  maverick.c -- Cirrus/DSP co-processor interface.
+     Copyright (C) 2003 Free Software Foundation, Inc.
+     Contributed by Aldy Hernandez (aldyh@redhat.com).
+  
+     This program is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published by
+     the Free Software Foundation; either version 2 of the License, or
+     (at your option) any later version.
+  
+     This program is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+  
+     You should have received a copy of the GNU General Public License
+     along with this program; if not, write to the Free Software
+     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ 
+ #include <assert.h>
+ #include "armdefs.h"
+ #include "ansidecl.h"
+ #include "armemu.h"
+ 
+ /*#define CIRRUS_DEBUG 1	/**/
+ #if CIRRUS_DEBUG
+ #  define printfdbg printf
+ #else
+ #  define printfdbg printf_nothing
+ #endif
+ 
+ #define POS64(i) ( (~(i)) >> 63 )
+ #define NEG64(i) ( (i) >> 63 )
+ 
+ /* Define Co-Processor instruction handlers here.  */
+ 
+ /* Here's ARMulator's DSP definition.  A few things to note:
+    1) it has 16 64-bit registers and 4 72-bit accumulators
+    2) you can only access its registers with MCR and MRC.  */
+ 
+ /* We can't define these in here because this file might not be linked
+    unless the target is arm9e-*.  They are defined in wrapper.c.
+    Eventually the simulator should be made to handle any coprocessor
+    at run time.  */
+ struct maverick_regs
+ {
+   union
+   {
+     int i;
+     float f;
+   } upper;
+   
+   union
+   {
+     int i;
+     float f;
+   } lower;
+ };
+ 
+ union maverick_acc_regs
+ {
+   long double ld;		/* Acc registers are 72-bits.  */
+ };
+ 
+ struct maverick_regs DSPregs[16];
+ union maverick_acc_regs DSPacc[4];
+ ARMword DSPsc;
+ 
+ #define DEST_REG	(BITS (12, 15))
+ #define SRC1_REG	(BITS (16, 19))
+ #define SRC2_REG	(BITS (0, 3))
+ 
+ static int lsw_int_index, msw_int_index;
+ static int lsw_float_index, msw_float_index;
+ 
+ static double mv_getRegDouble (int);
+ static long long mv_getReg64int (int);
+ static void mv_setRegDouble (int, double val);
+ static void mv_setReg64int (int, long long val);
+ 
+ static union
+ {
+   double d;
+   long long ll;
+   int ints[2];
+ } reg_conv;
+ 
+ static void
+ printf_nothing (void * foo, ...)
+ {
+ }
+ 
+ static void
+ cirrus_not_implemented (char * insn)
+ {
+   fprintf (stderr, "Cirrus instruction '%s' not implemented.\n", insn);
+   fprintf (stderr, "aborting!\n");
+   
+   exit (1);
+ }
+ 
+ static unsigned
+ DSPInit (ARMul_State * state)
+ {
+   ARMul_ConsolePrint (state, ", DSP present");
+   return TRUE;
+ }
+ 
+ unsigned
+ DSPMRC4 (ARMul_State * state ATTRIBUTE_UNUSED,
+ 	 unsigned      type  ATTRIBUTE_UNUSED,
+ 	 ARMword       instr,
+ 	 ARMword *     value)
+ {
+   switch (BITS (5, 7))
+     {
+     case 0: /* cfmvrdl */
+       /* Move lower half of a DF stored in a DSP reg into an Arm reg.  */
+       printfdbg ("cfmvrdl\n");
+       printfdbg ("\tlower half=0x%x\n", DSPregs[SRC1_REG].lower.i);
+       printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
+       
+       *value = (ARMword) DSPregs[SRC1_REG].lower.i;
+       break;
+       
+     case 1: /* cfmvrdh */
+       /* Move upper half of a DF stored in a DSP reg into an Arm reg.  */
+       printfdbg ("cfmvrdh\n");
+       printfdbg ("\tupper half=0x%x\n", DSPregs[SRC1_REG].upper.i);
+       printfdbg ("\tentire thing=%g\n", mv_getRegDouble (SRC1_REG));
+       
+       *value = (ARMword) DSPregs[SRC1_REG].upper.i;
+       break;
+       
+     case 2: /* cfmvrs */
+       /* Move SF from upper half of a DSP register to an Arm register.  */
+       *value = (ARMword) DSPregs[SRC1_REG].upper.i;
+       printfdbg ("cfmvrs = mvf%d <-- %f\n",
+ 		 SRC1_REG,
+ 		 DSPregs[SRC1_REG].upper.f);
+       break;
+       
+ #ifdef doesnt_work
+     case 4: /* cfcmps */
+       {
+ 	float a, b;
+ 	int n, z, c, v;
+ 
+ 	a = DSPregs[SRC1_REG].upper.f;
+ 	b = DSPregs[SRC2_REG].upper.f;
+ 
+ 	printfdbg ("cfcmps\n");
+ 	printfdbg ("\tcomparing %f and %f\n", a, b);
+ 
+ 	z = a == b;		/* zero */
+ 	n = a != b;		/* negative */
+ 	v = a > b;		/* overflow */
+ 	c = 0;			/* carry */
+ 	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
+ 	break;
+       }
+       
+     case 5: /* cfcmpd */
+       {
+ 	double a, b;
+ 	int n, z, c, v;
+ 
+ 	a = mv_getRegDouble (SRC1_REG);
+ 	b = mv_getRegDouble (SRC2_REG);
+ 
+ 	printfdbg ("cfcmpd\n");
+ 	printfdbg ("\tcomparing %g and %g\n", a, b);
+ 
+ 	z = a == b;		/* zero */
+ 	n = a != b;		/* negative */
+ 	v = a > b;		/* overflow */
+ 	c = 0;			/* carry */
+ 	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
+ 	break;
+       }
+ #else
+       case 4: /* cfcmps */
+         {
+ 	  float a, b;
+ 	  int n, z, c, v;
+ 
+ 	  a = DSPregs[SRC1_REG].upper.f;
+ 	  b = DSPregs[SRC2_REG].upper.f;
+   
+ 	  printfdbg ("cfcmps\n");
+ 	  printfdbg ("\tcomparing %f and %f\n", a, b);
+ 
+ 	  z = a == b;		/* zero */
+ 	  n = a < b;		/* negative */
+ 	  c = a > b;		/* carry */
+ 	  v = 0;		/* fixme */
+ 	  printfdbg ("\tz = %d, n = %d\n", z, n);
+ 	  *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
+ 	  break;
+         }
+ 	
+       case 5: /* cfcmpd */
+         {
+ 	  double a, b;
+ 	  int n, z, c, v;
+ 
+ 	  a = mv_getRegDouble (SRC1_REG);
+ 	  b = mv_getRegDouble (SRC2_REG);
+   
+ 	  printfdbg ("cfcmpd\n");
+ 	  printfdbg ("\tcomparing %g and %g\n", a, b);
+   
+ 	  z = a == b;		/* zero */
+ 	  n = a < b;		/* negative */
+ 	  c = a > b;		/* carry */
+ 	  v = 0;		/* fixme */
+ 	  *value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
+ 	  break;
+         }
+ #endif
+     default:
+       fprintf (stderr, "unknown opcode in DSPMRC4 0x%x\n", instr);
+       cirrus_not_implemented ("unknown");
+       break;
+     }
+ 
+   return ARMul_DONE;
+ }
+ 
+ unsigned
+ DSPMRC5 (ARMul_State * state ATTRIBUTE_UNUSED,
+ 	 unsigned      type  ATTRIBUTE_UNUSED,
+ 	 ARMword       instr,
+ 	 ARMword *     value)
+ {
+   switch (BITS (5, 7))
+     {
+     case 0: /* cfmvr64l */
+       /* Move lower half of 64bit int from Cirrus to Arm.  */
+       *value = (ARMword) DSPregs[SRC1_REG].lower.i;
+       printfdbg ("cfmvr64l ARM_REG = mvfx%d <-- %d\n",
+ 		 DEST_REG,
+ 		 (int) *value);
+       break;
+       
+     case 1: /* cfmvr64h */
+       /* Move upper half of 64bit int from Cirrus to Arm.  */
+       *value = (ARMword) DSPregs[SRC1_REG].upper.i;
+       printfdbg ("cfmvr64h <-- %d\n", (int) *value);
+       break;
+       
+     case 4: /* cfcmp32 */
+       {
+ 	int res;
+ 	int n, z, c, v;
+ 	unsigned int a, b;
+ 
+ 	printfdbg ("cfcmp32 mvfx%d - mvfx%d\n",
+ 		   SRC1_REG,
+ 		   SRC2_REG);
+ 
+ 	/* FIXME: see comment for cfcmps.  */
+ 	a = DSPregs[SRC1_REG].lower.i;
+ 	b = DSPregs[SRC2_REG].lower.i;
+ 
+ 	res = DSPregs[SRC1_REG].lower.i - DSPregs[SRC2_REG].lower.i;
+ 	/* zero */
+ 	z = res == 0;
+ 	/* negative */
+ 	n = res < 0;
+ 	/* overflow */
+ 	v = SubOverflow (DSPregs[SRC1_REG].lower.i, DSPregs[SRC2_REG].lower.i,
+ 			 res);
+ 	/* carry */
+ 	c = (NEG (a) && POS (b) ||
+ 	     (NEG (a) && POS (res)) || (POS (b) && POS (res)));
+ 
+ 	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
+ 	break;
+       }
+       
+     case 5: /* cfcmp64 */
+       {
+ 	long long res;
+ 	int n, z, c, v;
+ 	unsigned long long a, b;
+ 
+ 	printfdbg ("cfcmp64 mvdx%d - mvdx%d\n",
+ 		   SRC1_REG,
+ 		   SRC2_REG);
+ 
+ 	/* fixme: see comment for cfcmps.  */
+ 
+ 	a = mv_getReg64int (SRC1_REG);
+ 	b = mv_getReg64int (SRC2_REG);
+ 
+ 	res = mv_getReg64int (SRC1_REG) - mv_getReg64int (SRC2_REG);
+ 	/* zero */
+ 	z = res == 0;
+ 	/* negative */
+ 	n = res < 0;
+ 	/* overflow */
+ 	v = ((NEG64 (a) && POS64 (b) && POS64 (res))
+ 	     || (POS64 (a) && NEG64 (b) && NEG64 (res)));
+ 	/* carry */
+ 	c = (NEG64 (a) && POS64 (b) ||
+ 	     (NEG64 (a) && POS64 (res)) || (POS64 (b) && POS64 (res)));
+ 
+ 	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
+ 	break;
+       }
+       
+     default:
+       fprintf (stderr, "unknown opcode in DSPMRC5 0x%x\n", instr);
+       cirrus_not_implemented ("unknown");
+       break;
+     }
+ 
+   return ARMul_DONE;
+ }
+ 
+ unsigned
+ DSPMRC6 (ARMul_State * state ATTRIBUTE_UNUSED,
+ 	 unsigned      type  ATTRIBUTE_UNUSED,
+ 	 ARMword       instr,
+ 	 ARMword *     value)
+ {
+   switch (BITS (5, 7))
+     {
+     case 0: /* cfmval32 */
+       cirrus_not_implemented ("cfmval32");
+       break;
+       
+     case 1: /* cfmvam32 */
+       cirrus_not_implemented ("cfmvam32");
+       break;
+       
+     case 2: /* cfmvah32 */
+       cirrus_not_implemented ("cfmvah32");
+       break;
+       
+     case 3: /* cfmva32 */
+       cirrus_not_implemented ("cfmva32");
+       break;
+       
+     case 4: /* cfmva64 */
+       cirrus_not_implemented ("cfmva64");
+       break;
+       
+     case 5: /* cfmvsc32 */
+       cirrus_not_implemented ("cfmvsc32");
+       break;
+       
+     default:
+       fprintf (stderr, "unknown opcode in DSPMRC6 0x%x\n", instr);
+       cirrus_not_implemented ("unknown");
+       break;
+     }
+ 
+   return ARMul_DONE;
+ }
+ 
+ unsigned
+ DSPMCR4 (ARMul_State * state,
+ 	 unsigned      type ATTRIBUTE_UNUSED,
+ 	 ARMword       instr,
+ 	 ARMword       value)
+ {
+   switch (BITS (5, 7))
+     {
+     case 0: /* cfmvdlr */
+       /* Move the lower half of a DF value from an Arm register into
+ 	 the lower half of a Cirrus register.  */
+       printfdbg ("cfmvdlr <-- 0x%x\n", (int) value);
+       DSPregs[SRC1_REG].lower.i = (int) value;
+       break;
+       
+     case 1: /* cfmvdhr */
+       /* Move the upper half of a DF value from an Arm register into
+ 	 the upper half of a Cirrus register.  */
+       printfdbg ("cfmvdhr <-- 0x%x\n", (int) value);
+       DSPregs[SRC1_REG].upper.i = (int) value;
+       break;
+       
+     case 2: /* cfmvsr */
+       /* Move SF from Arm register into upper half of Cirrus register.  */
+       printfdbg ("cfmvsr <-- 0x%x\n", (int) value);
+       DSPregs[SRC1_REG].upper.i = (int) value;
+       break;
+       
+     default:
+       fprintf (stderr, "unknown opcode in DSPMCR4 0x%x\n", instr);
+       cirrus_not_implemented ("unknown");
+       break;
+     }
+ 
+   return ARMul_DONE;
+ }
+ 
+ unsigned
+ DSPMCR5 (ARMul_State * state,
+ 	 unsigned      type   ATTRIBUTE_UNUSED,
+ 	 ARMword       instr,
+ 	 ARMword       value)
+ {
+   union
+   {
+     int s;
+     unsigned int us;
+   } val;
+ 
+   switch (BITS (5, 7))
+     {
+     case 0: /* cfmv64lr */
+       /* Move lower half of a 64bit int from an ARM register into the
+          lower half of a DSP register and sign extend it.  */
+       printfdbg ("cfmv64lr mvdx%d <-- 0x%x\n", SRC1_REG, (int) value);
+       DSPregs[SRC1_REG].lower.i = (int) value;
+       break;
+       
+     case 1: /* cfmv64hr */
+       /* Move upper half of a 64bit int from an ARM register into the
+ 	 upper half of a DSP register.  */
+       printfdbg ("cfmv64hr ARM_REG = mvfx%d <-- 0x%x\n",
+ 		 SRC1_REG,
+ 		 (int) value);
+       DSPregs[SRC1_REG].upper.i = (int) value;
+       break;
+       
+     case 2: /* cfrshl32 */
+       printfdbg ("cfrshl32\n");
+       val.us = value;
+       if (val.s > 0)
+ 	DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i << value;
+       else
+ 	DSPregs[SRC2_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -value;
+       break;
+       
+     case 3: /* cfrshl64 */
+       printfdbg ("cfrshl64\n");
+       val.us = value;
+       if (val.s > 0)
+ 	mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) << value);
+       else
+ 	mv_setReg64int (SRC2_REG, mv_getReg64int (SRC1_REG) >> -value);
+       break;
+       
+     default:
+       fprintf (stderr, "unknown opcode in DSPMCR5 0x%x\n", instr);
+       cirrus_not_implemented ("unknown");
+       break;
+     }
+ 
+   return ARMul_DONE;
+ }
+ 
+ unsigned
+ DSPMCR6 (ARMul_State * state,
+ 	 unsigned      type   ATTRIBUTE_UNUSED,
+ 	 ARMword       instr,
+ 	 ARMword       value)
+ {
+   switch (BITS (5, 7))
+     {
+     case 0: /* cfmv32al */
+       cirrus_not_implemented ("cfmv32al");
+       break;
+       
+     case 1: /* cfmv32am */
+       cirrus_not_implemented ("cfmv32am");
+       break;
+       
+     case 2: /* cfmv32ah */
+       cirrus_not_implemented ("cfmv32ah");
+       break;
+       
+     case 3: /* cfmv32a */
+       cirrus_not_implemented ("cfmv32a");
+       break;
+       
+     case 4: /* cfmv64a */
+       cirrus_not_implemented ("cfmv64a");
+       break;
+       
+     case 5: /* cfmv32sc */
+       cirrus_not_implemented ("cfmv32sc");
+       break;
+       
+     default:
+       fprintf (stderr, "unknown opcode in DSPMCR6 0x%x\n", instr);
+       cirrus_not_implemented ("unknown");
+       break;
+     }
+ 
+   return ARMul_DONE;
+ }
+ 
+ unsigned
+ DSPLDC4 (ARMul_State * state ATTRIBUTE_UNUSED,
+ 	 unsigned      type,
+ 	 ARMword       instr,
+ 	 ARMword       data)
+ {
+   static unsigned words;
+ 
+   if (type != ARMul_DATA)
+     {
+       words = 0;
+       return ARMul_DONE;
+     }
+   
+   if (BIT (22))
+     {				/* it's a long access, get two words */
+       /* cfldrd */
+ 
+       printfdbg ("cfldrd: %x (words = %d) (bigend = %d) DESTREG = %d\n",
+ 		 data, words, state->bigendSig, DEST_REG);
+       
+       if (words == 0)
+ 	{
+ 	  if (state->bigendSig)
+ 	    DSPregs[DEST_REG].upper.i = (int) data;
+ 	  else
+ 	    DSPregs[DEST_REG].lower.i = (int) data;
+ 	}
+       else
+ 	{
+ 	  if (state->bigendSig)
+ 	    DSPregs[DEST_REG].lower.i = (int) data;
+ 	  else
+ 	    DSPregs[DEST_REG].upper.i = (int) data;
+ 	}
+       
+       ++ words;
+       
+       if (words == 2)
+ 	{
+ 	  printfdbg ("\tmvd%d <-- mem = %g\n", DEST_REG,
+ 		     mv_getRegDouble (DEST_REG));
+ 	  
+ 	  return ARMul_DONE;
+ 	}
+       else
+ 	return ARMul_INC;
+     }
+   else
+     {
+       /* Get just one word.  */
+       
+       /* cfldrs */
+       printfdbg ("cfldrs\n");
+ 
+       DSPregs[DEST_REG].upper.i = (int) data;
+ 
+       printfdbg ("\tmvf%d <-- mem = %f\n", DEST_REG,
+ 		 DSPregs[DEST_REG].upper.f);
+ 
+       return ARMul_DONE;
+     }
+ }
+ 
+ unsigned
+ DSPLDC5 (ARMul_State * state ATTRIBUTE_UNUSED,
+ 	 unsigned      type,
+ 	 ARMword       instr,
+ 	 ARMword       data)
+ {
+   static unsigned words;
+ 
+   if (type != ARMul_DATA)
+     {
+       words = 0;
+       return ARMul_DONE;
+     }
+   
+   if (BIT (22))
+     {
+       /* It's a long access, get two words.  */
+       
+       /* cfldr64 */
+       printfdbg ("cfldr64: %d\n", data);
+ 
+       if (words == 0)
+ 	{
+ 	  if (state->bigendSig)
+ 	    DSPregs[DEST_REG].upper.i = (int) data;
+ 	  else
+ 	    DSPregs[DEST_REG].lower.i = (int) data;
+ 	}
+       else
+ 	{
+ 	  if (state->bigendSig)
+ 	    DSPregs[DEST_REG].lower.i = (int) data;
+ 	  else
+ 	    DSPregs[DEST_REG].upper.i = (int) data;
+ 	}
+       
+       ++ words;
+       
+       if (words == 2)
+ 	{
+ 	  printfdbg ("\tmvdx%d <-- mem = %lld\n", DEST_REG,
+ 		     mv_getReg64int (DEST_REG));
+ 	  
+ 	  return ARMul_DONE;
+ 	}
+       else
+ 	return ARMul_INC;
+     }
+   else
+     {
+       /* Get just one word.  */
+       
+       /* cfldr32 */
+       printfdbg ("cfldr32 mvfx%d <-- %d\n", DEST_REG, (int) data);
+       
+       /* 32bit ints should be sign extended to 64bits when loaded.  */
+       mv_setReg64int (DEST_REG, (long long) data);
+ 
+       return ARMul_DONE;
+     }
+ }
+ 
+ unsigned
+ DSPSTC4 (ARMul_State * state ATTRIBUTE_UNUSED,
+ 	 unsigned      type,
+ 	 ARMword       instr,
+ 	 ARMword *     data)
+ {
+   static unsigned words;
+ 
+   if (type != ARMul_DATA)
+     {
+       words = 0;
+       return ARMul_DONE;
+     }
+   
+   if (BIT (22))
+     {
+       /* It's a long access, get two words.  */
+       /* cfstrd */
+       printfdbg ("cfstrd\n");
+ 
+       if (words == 0)
+ 	{
+ 	  if (state->bigendSig)
+ 	    *data = (ARMword) DSPregs[DEST_REG].upper.i;
+ 	  else
+ 	    *data = (ARMword) DSPregs[DEST_REG].lower.i;
+ 	}
+       else
+ 	{
+ 	  if (state->bigendSig)
+ 	    *data = (ARMword) DSPregs[DEST_REG].lower.i;
+ 	  else
+ 	    *data = (ARMword) DSPregs[DEST_REG].upper.i;
+ 	}
+       
+       ++ words;
+       
+       if (words == 2)
+ 	{
+ 	  printfdbg ("\tmem = mvd%d = %g\n", DEST_REG,
+ 		     mv_getRegDouble (DEST_REG));
+ 	  
+ 	  return ARMul_DONE;
+ 	}
+       else
+ 	return ARMul_INC;
+     }
+   else
+     {
+       /* Get just one word.  */
+       /* cfstrs */
+       printfdbg ("cfstrs mvf%d <-- %f\n", DEST_REG,
+ 		 DSPregs[DEST_REG].upper.f);
+ 
+       *data = (ARMword) DSPregs[DEST_REG].upper.i;
+ 
+       return ARMul_DONE;
+     }
+ }
+ 
+ unsigned
+ DSPSTC5 (ARMul_State * state ATTRIBUTE_UNUSED,
+ 	 unsigned      type,
+ 	 ARMword       instr,
+ 	 ARMword *     data)
+ {
+   static unsigned words;
+ 
+   if (type != ARMul_DATA)
+     {
+       words = 0;
+       return ARMul_DONE;
+     }
+   
+   if (BIT (22))
+     {
+       /* It's a long access, store two words.  */
+       /* cfstr64 */
+       printfdbg ("cfstr64\n");
+ 
+       if (words == 0)
+ 	{
+ 	  if (state->bigendSig)
+ 	    *data = (ARMword) DSPregs[DEST_REG].upper.i;
+ 	  else
+ 	    *data = (ARMword) DSPregs[DEST_REG].lower.i;
+ 	}
+       else
+ 	{
+ 	  if (state->bigendSig)
+ 	    *data = (ARMword) DSPregs[DEST_REG].lower.i;
+ 	  else
+ 	    *data = (ARMword) DSPregs[DEST_REG].upper.i;
+ 	}
+       
+       ++ words;
+       
+       if (words == 2)
+ 	{
+ 	  printfdbg ("\tmem = mvd%d = %lld\n", DEST_REG,
+ 		     mv_getReg64int (DEST_REG));
+ 	  
+ 	  return ARMul_DONE;
+ 	}
+       else
+ 	return ARMul_INC;
+     }
+   else
+     {
+       /* Store just one word.  */
+       /* cfstr32 */
+       *data = (ARMword) DSPregs[DEST_REG].lower.i;
+       
+       printfdbg ("cfstr32 MEM = %d\n", (int) *data);
+ 
+       return ARMul_DONE;
+     }
+ }
+ 
+ unsigned
+ DSPCDP4 (ARMul_State * state,
+ 	 unsigned      type,
+ 	 ARMword       instr)
+ {
+   int opcode2;
+ 
+   opcode2 = BITS (5,7);
+ 
+   switch (BITS (20,21))
+     {
+     case 0:
+       switch (opcode2)
+ 	{
+ 	case 0: /* cfcpys */
+ 	  printfdbg ("cfcpys mvf%d = mvf%d = %f\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     DSPregs[SRC1_REG].upper.f);
+ 	  DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f;
+ 	  break;
+ 	  
+ 	case 1: /* cfcpyd */
+ 	  printfdbg ("cfcpyd mvd%d = mvd%d = %g\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     mv_getRegDouble (SRC1_REG));
+ 	  mv_setRegDouble (DEST_REG, mv_getRegDouble (SRC1_REG));
+ 	  break;
+ 	  
+ 	case 2: /* cfcvtds */
+ 	  printfdbg ("cfcvtds mvf%d = (float) mvd%d = %f\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     (float) mv_getRegDouble (SRC1_REG));
+ 	  DSPregs[DEST_REG].upper.f = (float) mv_getRegDouble (SRC1_REG);
+ 	  break;
+ 	  
+ 	case 3: /* cfcvtsd */
+ 	  printfdbg ("cfcvtsd mvd%d = mvf%d = %g\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     (double) DSPregs[SRC1_REG].upper.f);
+ 	  mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].upper.f);
+ 	  break;
+ 	  
+ 	case 4: /* cfcvt32s */
+ 	  printfdbg ("cfcvt32s mvf%d = mvfx%d = %f\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     (float) DSPregs[SRC1_REG].lower.i);
+ 	  DSPregs[DEST_REG].upper.f = (float) DSPregs[SRC1_REG].lower.i;
+ 	  break;
+ 	  
+ 	case 5: /* cfcvt32d */
+ 	  printfdbg ("cfcvt32d mvd%d = mvfx%d = %g\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     (double) DSPregs[SRC1_REG].lower.i);
+ 	  mv_setRegDouble (DEST_REG, (double) DSPregs[SRC1_REG].lower.i);
+ 	  break;
+ 	  
+ 	case 6: /* cfcvt64s */
+ 	  printfdbg ("cfcvt64s mvf%d = mvdx%d = %f\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     (float) mv_getReg64int (SRC1_REG));
+ 	  DSPregs[DEST_REG].upper.f = (float) mv_getReg64int (SRC1_REG);
+ 	  break;
+ 	  
+ 	case 7: /* cfcvt64d */
+ 	  printfdbg ("cfcvt64d mvd%d = mvdx%d = %g\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     (double) mv_getReg64int (SRC1_REG));
+ 	  mv_setRegDouble (DEST_REG, (double) mv_getReg64int (SRC1_REG));
+ 	  break;
+ 	}
+       break;
+ 
+     case 1:
+       switch (opcode2)
+ 	{
+ 	case 0: /* cfmuls */
+ 	  printfdbg ("cfmuls mvf%d = mvf%d = %f\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     DSPregs[SRC1_REG].upper.f * DSPregs[SRC2_REG].upper.f);
+ 		     
+ 	  DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
+ 	    * DSPregs[SRC2_REG].upper.f;
+ 	  break;
+ 	  
+ 	case 1: /* cfmuld */
+ 	  printfdbg ("cfmuld mvd%d = mvd%d = %g\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     mv_getRegDouble (SRC1_REG) * mv_getRegDouble (SRC2_REG));
+ 
+ 	  mv_setRegDouble (DEST_REG,
+ 			   mv_getRegDouble (SRC1_REG)
+ 			   * mv_getRegDouble (SRC2_REG));
+ 	  break;
+ 	  
+ 	default:
+ 	  fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
+ 	  cirrus_not_implemented ("unknown");
+ 	  break;
+ 	}
+       break;
+ 
+     case 3:
+       switch (opcode2)
+ 	{
+ 	case 0: /* cfabss */
+ 	  DSPregs[DEST_REG].upper.f = (DSPregs[SRC1_REG].upper.f < 0.0F ?
+ 				       -DSPregs[SRC1_REG].upper.f
+ 				       : DSPregs[SRC1_REG].upper.f);
+ 	  printfdbg ("cfabss mvf%d = |mvf%d| = %f\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     DSPregs[DEST_REG].upper.f);
+ 	  break;
+ 	  
+ 	case 1: /* cfabsd */
+ 	  mv_setRegDouble (DEST_REG,
+ 			   (mv_getRegDouble (SRC1_REG) < 0.0 ?
+ 			    -mv_getRegDouble (SRC1_REG)
+ 			    : mv_getRegDouble (SRC1_REG)));
+ 	  printfdbg ("cfabsd mvd%d = |mvd%d| = %g\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     mv_getRegDouble (DEST_REG));
+ 	  break;
+ 	  
+ 	case 2: /* cfnegs */
+ 	  DSPregs[DEST_REG].upper.f = -DSPregs[SRC1_REG].upper.f;
+ 	  printfdbg ("cfnegs mvf%d = -mvf%d = %f\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     DSPregs[DEST_REG].upper.f);
+ 	  break;
+ 	  
+ 	case 3: /* cfnegd */
+ 	  mv_setRegDouble (DEST_REG,
+ 			   -mv_getRegDouble (SRC1_REG));
+ 	  printfdbg ("cfnegd mvd%d = -mvd%d = %g\n",
+ 		     DEST_REG,
+ 		     mv_getRegDouble (DEST_REG));
+ 	  break;
+ 	  
+ 	case 4: /* cfadds */
+ 	  DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
+ 	    + DSPregs[SRC2_REG].upper.f;
+ 	  printfdbg ("cfadds mvf%d = mvf%d + mvf%d = %f\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     SRC2_REG,
+ 		     DSPregs[DEST_REG].upper.f);
+ 	  break;
+ 	  
+ 	case 5: /* cfaddd */
+ 	  mv_setRegDouble (DEST_REG,
+ 			   mv_getRegDouble (SRC1_REG)
+ 			   + mv_getRegDouble (SRC2_REG));
+ 	  printfdbg ("cfaddd: mvd%d = mvd%d + mvd%d = %g\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     SRC2_REG,
+ 		     mv_getRegDouble (DEST_REG));
+ 	  break;
+ 	  
+ 	case 6: /* cfsubs */
+ 	  DSPregs[DEST_REG].upper.f = DSPregs[SRC1_REG].upper.f
+ 	    - DSPregs[SRC2_REG].upper.f;
+ 	  printfdbg ("cfsubs: mvf%d = mvf%d - mvf%d = %f\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     SRC2_REG,
+ 		     DSPregs[DEST_REG].upper.f);
+ 	  break;
+ 	  
+ 	case 7: /* cfsubd */
+ 	  mv_setRegDouble (DEST_REG,
+ 			   mv_getRegDouble (SRC1_REG)
+ 			   - mv_getRegDouble (SRC2_REG));
+ 	  printfdbg ("cfsubd: mvd%d = mvd%d - mvd%d = %g\n",
+ 		     DEST_REG,
+ 		     SRC1_REG,
+ 		     SRC2_REG,
+ 		     mv_getRegDouble (DEST_REG));
+ 	  break;
+ 	}
+       break;
+ 
+     default:
+       fprintf (stderr, "unknown opcode in DSPCDP4 0x%x\n", instr);
+       cirrus_not_implemented ("unknown");
+       break;
+     }
+ 
+   return ARMul_DONE;
+ }
+ 
+ unsigned
+ DSPCDP5 (ARMul_State * state,
+ 	 unsigned      type,
+ 	 ARMword       instr)
+ {
+    int opcode2;
+    char shift;
+ 
+    opcode2 = BITS (5,7);
+ 
+    /* Shift constants are 7bit signed numbers in bits 0..3|5..7.  */
+    shift = BITS (0, 3) | (BITS (5, 7)) << 4;
+    if (shift & 0x40)
+      shift |= 0xc0;
+ 
+    switch (BITS (20,21))
+      {
+      case 0:
+        /* cfsh32 */
+        printfdbg ("cfsh32 %s amount=%d\n", shift < 0 ? "right" : "left",
+ 		  shift);
+        if (shift < 0)
+ 	 /* Negative shift is a right shift.  */
+ 	 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i >> -shift;
+        else
+ 	 /* Positive shift is a left shift.  */
+ 	 DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i << shift;
+        break;
+ 
+      case 1:
+        switch (opcode2)
+          {
+          case 0: /* cfmul32 */
+ 	   DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
+ 	     * DSPregs[SRC2_REG].lower.i;
+ 	   printfdbg ("cfmul32 mvfx%d = mvfx%d * mvfx%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 1: /* cfmul64 */
+ 	   mv_setReg64int (DEST_REG,
+ 			   mv_getReg64int (SRC1_REG)
+ 			   * mv_getReg64int (SRC2_REG));
+ 	   printfdbg ("cfmul64 mvdx%d = mvdx%d * mvdx%d = %lld\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      mv_getReg64int (DEST_REG));
+            break;
+ 	   
+          case 2: /* cfmac32 */
+ 	   DSPregs[DEST_REG].lower.i
+ 	     += DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
+ 	   printfdbg ("cfmac32 mvfx%d += mvfx%d * mvfx%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 3: /* cfmsc32 */
+ 	   DSPregs[DEST_REG].lower.i
+ 	     -= DSPregs[SRC1_REG].lower.i * DSPregs[SRC2_REG].lower.i;
+ 	   printfdbg ("cfmsc32 mvfx%d -= mvfx%d * mvfx%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 4: /* cfcvts32 */
+ 	   /* fixme: this should round */
+ 	   DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
+ 	   printfdbg ("cfcvts32 mvfx%d = mvf%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 5: /* cfcvtd32 */
+ 	   /* fixme: this should round */
+ 	   DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
+ 	   printfdbg ("cfcvtd32 mvdx%d = mvd%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 6: /* cftruncs32 */
+ 	   DSPregs[DEST_REG].lower.i = (int) DSPregs[SRC1_REG].upper.f;
+ 	   printfdbg ("cftruncs32 mvfx%d = mvf%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 7: /* cftruncd32 */
+ 	   DSPregs[DEST_REG].lower.i = (int) mv_getRegDouble (SRC1_REG);
+ 	   printfdbg ("cftruncd32 mvfx%d = mvd%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+          }
+        break;
+ 
+      case 2:
+        /* cfsh64 */
+        printfdbg ("cfsh64\n");
+        
+        if (shift < 0)
+ 	 /* Negative shift is a right shift.  */
+ 	 mv_setReg64int (DEST_REG,
+ 			 mv_getReg64int (SRC1_REG) >> -shift);
+        else
+ 	 /* Positive shift is a left shift.  */
+ 	 mv_setReg64int (DEST_REG,
+ 			 mv_getReg64int (SRC1_REG) << shift);
+        printfdbg ("\t%llx\n", mv_getReg64int(DEST_REG));
+        break;
+ 
+      case 3:
+        switch (opcode2)
+          {
+          case 0: /* cfabs32 */
+ 	   DSPregs[DEST_REG].lower.i = (DSPregs[SRC1_REG].lower.i < 0
+ 	     ? -DSPregs[SRC1_REG].lower.i : DSPregs[SRC1_REG].lower.i);
+ 	   printfdbg ("cfabs32 mvfx%d = |mvfx%d| = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 1: /* cfabs64 */
+ 	   mv_setReg64int (DEST_REG,
+ 			   (mv_getReg64int (SRC1_REG) < 0
+ 			    ? -mv_getReg64int (SRC1_REG)
+ 			    : mv_getReg64int (SRC1_REG)));
+ 	   printfdbg ("cfabs64 mvdx%d = |mvdx%d| = %lld\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      mv_getReg64int (DEST_REG));
+            break;
+ 	   
+          case 2: /* cfneg32 */
+ 	   DSPregs[DEST_REG].lower.i = -DSPregs[SRC1_REG].lower.i;
+ 	   printfdbg ("cfneg32 mvfx%d = -mvfx%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 3: /* cfneg64 */
+ 	   mv_setReg64int (DEST_REG, -mv_getReg64int (SRC1_REG));
+ 	   printfdbg ("cfneg64 mvdx%d = -mvdx%d = %lld\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      mv_getReg64int (DEST_REG));
+            break;
+ 	   
+          case 4: /* cfadd32 */
+ 	   DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
+ 	     + DSPregs[SRC2_REG].lower.i;
+ 	   printfdbg ("cfadd32 mvfx%d = mvfx%d + mvfx%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 5: /* cfadd64 */
+ 	   mv_setReg64int (DEST_REG,
+ 			   mv_getReg64int (SRC1_REG)
+ 			   + mv_getReg64int (SRC2_REG));
+ 	   printfdbg ("cfadd64 mvdx%d = mvdx%d + mvdx%d = %lld\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      mv_getReg64int (DEST_REG));
+            break;
+ 	   
+          case 6: /* cfsub32 */
+ 	   DSPregs[DEST_REG].lower.i = DSPregs[SRC1_REG].lower.i
+ 	     - DSPregs[SRC2_REG].lower.i;
+ 	   printfdbg ("cfsub32 mvfx%d = mvfx%d - mvfx%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      DSPregs[DEST_REG].lower.i);
+            break;
+ 	   
+          case 7: /* cfsub64 */
+ 	   mv_setReg64int (DEST_REG,
+ 			   mv_getReg64int (SRC1_REG)
+ 			   - mv_getReg64int (SRC2_REG));
+ 	   printfdbg ("cfsub64 mvdx%d = mvdx%d - mvdx%d = %d\n",
+ 		      DEST_REG,
+ 		      SRC1_REG,
+ 		      SRC2_REG,
+ 		      mv_getReg64int (DEST_REG));
+            break;
+          }
+        break;
+ 
+      default:
+        fprintf (stderr, "unknown opcode in DSPCDP5 0x%x\n", instr);
+        cirrus_not_implemented ("unknown");
+        break;
+      }
+ 
+   return ARMul_DONE;
+ }
+ 
+ unsigned
+ DSPCDP6 (ARMul_State * state,
+ 	 unsigned      type,
+ 	 ARMword       instr)
+ {
+    int opcode2;
+ 
+    opcode2 = BITS (5,7);
+ 
+    switch (BITS (20,21))
+      {
+      case 0:
+        /* cfmadd32 */
+        cirrus_not_implemented ("cfmadd32");
+        break;
+        
+      case 1:
+        /* cfmsub32 */
+        cirrus_not_implemented ("cfmsub32");
+        break;
+        
+      case 2:
+        /* cfmadda32 */
+        cirrus_not_implemented ("cfmadda32");
+        break;
+        
+      case 3:
+        /* cfmsuba32 */
+        cirrus_not_implemented ("cfmsuba32");
+        break;
+ 
+      default:
+        fprintf (stderr, "unknown opcode in DSPCDP6 0x%x\n", instr);
+      }
+ 
+    return ARMul_DONE;
+ }
+ 
+ /* Conversion functions.
+ 
+    32-bit integers are stored in the LOWER half of a 64-bit physical
+    register.
+ 
+    Single precision floats are stored in the UPPER half of a 64-bit
+    physical register.  */
+ 
+ static double
+ mv_getRegDouble (int regnum)
+ {
+   reg_conv.ints[lsw_float_index] = DSPregs[regnum].upper.i;
+   reg_conv.ints[msw_float_index] = DSPregs[regnum].lower.i;
+   return reg_conv.d;
+ }
+ 
+ static void
+ mv_setRegDouble (int regnum, double val)
+ {
+   reg_conv.d = val;
+   DSPregs[regnum].upper.i = reg_conv.ints[lsw_float_index];
+   DSPregs[regnum].lower.i = reg_conv.ints[msw_float_index];
+ }
+ 
+ static long long
+ mv_getReg64int (int regnum)
+ {
+   reg_conv.ints[lsw_int_index] = DSPregs[regnum].lower.i;
+   reg_conv.ints[msw_int_index] = DSPregs[regnum].upper.i;
+   return reg_conv.ll;
+ }
+ 
+ static void
+ mv_setReg64int (int regnum, long long val)
+ {
+   reg_conv.ll = val;
+   DSPregs[regnum].lower.i = reg_conv.ints[lsw_int_index];
+   DSPregs[regnum].upper.i = reg_conv.ints[msw_int_index];
+ }
+ 
+ /* Compute LSW in a double and a long long.  */
+ 
+ void
+ mv_compute_host_endianness (ARMul_State * state)
+ {
+   static union
+   {
+     long long ll;
+     long ints[2];
+     long i;
+     double d;
+     float floats[2];
+     float f;
+   } conv;
+ 
+   /* Calculate where's the LSW in a 64bit int.  */
+   conv.ll = 45;
+   
+   if (conv.ints[0] == 0)
+     {
+       msw_int_index = 0;
+       lsw_int_index = 1;
+     }
+   else
+     {
+       assert (conv.ints[1] == 0);
+       msw_int_index = 1;
+       lsw_int_index = 0;
+     }
+ 
+   /* Calculate where's the LSW in a double.  */
+   conv.d = 3.0;
+   
+   if (conv.ints[0] == 0)
+     {
+       msw_float_index = 0;
+       lsw_float_index = 1;
+     }
+   else
+     {
+       assert (conv.ints[1] == 0);
+       msw_float_index = 1;
+       lsw_float_index = 0;
+     }
+ 
+   printfdbg ("lsw_int_index   %d\n", lsw_int_index);
+   printfdbg ("lsw_float_index %d\n", lsw_float_index);
+ }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]