public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] new portlet: cirrus-maverick
@ 2002-08-14  8:50 Aldy Hernandez
  2002-08-14  9:22 ` Aldy Hernandez
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Aldy Hernandez @ 2002-08-14  8:50 UTC (permalink / raw)
  To: rearnsha, nickc, gcc-patches; +Cc: rsandifo

Hi Richard (Earnshaw and Sandiford).  Hi Nick.  Hi guys.

Here is a port for the Maverick DSP chip by Cirrus.  The port has been
sitting in our tree for at least a year, and has been tested and
retested.

I have tested this patch with a simulated arm-elf target.  No
regressions.  I have also done some minor testing with
armmaverick-elf with my hacked up tree providing newlib, binutils, sim
support.  I have yet to contribute the ld/bfd/newlib/sim bits.

The work was funded by Cirrus.  I wrote the port, and I believe there
was some additional work by Richard Sandiford, though I can't seem to
find ChangeLog entries with his name (Sandiford?).

The gas support presently in binutils uses arm9e-elf which you and
Nick agreed should be changed to armmaverick-elf.  The gcc bits use
armmaverick-elf as suggested, and I have patches for the rest of
binutils to use armmaverick (to follow shortly).

Ok to install?

2002-08-13  Aldy Hernandez  <aldyh@redhat.com>

	* config/arm/arm.h (TARGET_CPU_armmaverick): New.
	Check TARGET_CPU_DEFAULT for maverick.
	(CPP_CPU_ARCH_SPEC): Add support for maverick.
	(MAVERICK_FIX_INVALID_INSNS): New macro.
	(TARGET_ANY_HARD_FLOAT): Same.
	(TARGET_MAVERICK): Same.
	(TARGET_MAVERICK_FIX_INVALID_INSNS): Same.
	(TARGET_SWITCHES): Add maverick-fix-invalid-insns,
	no-maverick-fix-invalid-insns.
	(floating_point_type): Add FP_MAVERICK.
	(FLOAT_WORDS_BIG_ENDIAN): Adjust for maverick.
	(CONDITIONAL_REGISTER_USAGE): Same.
	(FIRST_MAVERICK_FP_REGNUM): New.
	(LAST_MAVERICK_FP_REGNUM): New.
	(IS_MAVERICK_REGNUM): New.
	(FIRST_PSEUDO_REGISTER): Change to 43.
	(reg_class): Add MAVERICK_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REG_CLASS_FROM_LETTER): Add 'v'.
	(EXTRA_CONSTRAINT_ARM): Add 'T'.
	(SECONDARY_INPUT_RELOAD_CLASS): Disallow constants in Maverick
	registers.
	(ARM_LEGITIMIZE_RELOAD_ADDRESS): Adjust for maverick.
	(CLASS_MAX_NREGS): Same.
	(REGISTER_MOVE_COST): Same.
	(LIBCALL_VALUE): Same.
	(FUNCTION_VALUE_REGNO_P): Same.
	(ARM_GO_IF_LEGITIMATE_INDEX): Same.
	(CLASS_CANNOT_CHANGE_MODE): New.
	(CLASS_CANNOT_CHANGE_MODE_P): New.
	(PREDICATE_CODES): Add maverick_fp_register, maverick_shift_const,
	maverick_register_operand.

	* config/arm/arm.c (FL_MAVERICK): New.
	New global arm_is_maverick.
	(all_cores): Change arm9e to armmaverick.
	(all_architectures): Add armmaverick.
	(arm_override_options): Adjust for maverick.
	(arm_select_cc_mode): Same.
	(maverick_memory_offset): New.
	(maverick_register_operand): New.
	(maverick_fp_register): New.
	(maverick_shift_const): New.
	(is_load_address): New.
	(is_maverick_insn): New.
	(maverick_reorg): New.
	(arm_reorg): Reorg maverick insns.
	(arm_print_operand): Add 's'.

	* config/arm/arm.md: New function units maverick_fpa.
	New attribute maverick.
	(adddi3): Adjust for maverick.

	Disallow all DI patterns for maverick.

	Change float SF patterns to expanders.  Rename patterns to
	*arm_blah.  Add a corresponding maverick pattern.
	
	New patterns: maverick_adddi3, *maverick_addsi3, *maverick_addsf3,
	*maverick_adddf3, maverick_subdi3, *maverick_subsi3_insn,
	*maverick_subsf3, *maverick_subdf3, *maverick_mulsi3, muldi3,
	*maverick_mulsi3addsi, *maverick_mulsi3subsi, *maverick_mulsf3,
	*maverick_muldf3, *maverick_ashl_const, *maverick_ashiftrt_const,
	*maverick_ashlsi3, *maverick_ashldi3, *maverick_ashldi_const,
	*maverick_ashiftrtdi_const, *maverick_ashldi3, *maverick_ashldi_const,
	*maverick_ashiftrtdi_const, *maverick_negdi2, *maverick_negsi2,
	"*maverick_negsf2, *arm_negdf2, *maverick_negdf2, *maverick_abssi2,
	*maverick_abssf2, *maverick_absdf2, *maverick_floatsisf2,
	*maverick_floatsidf2, floatdisf2, floatdidf2, *maverick_truncdfsi2,
	*maverick_truncdfsf2, *maverick_extendsfdf2, *maverick_arm_movdi,
	*maverick_arm_movsi_insn, *maverick_movsf_hard_insn,
	*maverick_movdf_hard_insn, *maverick_cmpsf, *maverick_cmpdf, cmpdi,
	*maverick_cmpdi, *maverick_cmpsi_1.

	Add v constraint to call_value_reg, call_value_mem,
	call_value_symbol, *sibcall_value_insn.

	* config/arm/arm-protos.h: Add prototypes for maverick_fp_register,
	maverick_general_operand, maverick_register_operand,
	maverick_shift_const, maverick_memory_offset.

	* gcc/doc/invoke.texi (ARM Options): Document
	maverick-fix-invalid-insns and no-maverick-fix-invalid-insns.

	* config/arm/aout.h (ADDITIONAL_REGISTER_NAMES): Add maverick
	registers.
	(REGISTER_NAMES): Same.

	* config/arm/t-maverick-elf: New.

	* config.gcc: Add support for armmaverick.


Index: config/arm/arm.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/arm.c,v
retrieving revision 1.221
diff -c -p -r1.221 arm.c
*** config/arm/arm.c	11 Aug 2002 18:48:50 -0000	1.221
--- config/arm/arm.c	14 Aug 2002 15:36:09 -0000
*************** static void	 arm_elf_asm_named_section	P
*** 123,128 ****
--- 123,131 ----
  #ifndef ARM_PE
  static void	 arm_encode_section_info	PARAMS ((tree, int));
  #endif
+ static int 	 is_load_address                PARAMS ((rtx));
+ static int       is_maverick_insn                 PARAMS ((rtx));
+ static void      maverick_reorg                   PARAMS ((rtx));
  
  #undef Hint
  #undef Mmode
*************** int    arm_structure_size_boundary = DEF
*** 230,235 ****
--- 233,239 ----
  #define FL_STRONG     (1 << 8)	      /* StrongARM */
  #define FL_ARCH5E     (1 << 9)        /* DSP extenstions to v5 */
  #define FL_XSCALE     (1 << 10)	      /* XScale */
+ #define FL_MAVERICK   (1 << 30)     /* Cirrus/DSP.  */
  
  /* The bits in this mask specify which
     instructions we are allowed to generate.  */
*************** int arm_ld_sched = 0;
*** 261,266 ****
--- 265,272 ----
  
  /* Nonzero if this chip is a StrongARM.  */
  int arm_is_strong = 0;
+ /* Nonzero if this chip is a Cirrus/DSP.  */
+ int arm_is_maverick = 0;
  
  /* Nonzero if this chip is an XScale.  */
  int arm_is_xscale = 0;
*************** static const struct processors all_cores
*** 357,363 ****
    {"arm920t",	                         FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
    {"arm940t",	                         FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
    {"arm9tdmi",	                         FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
!   {"arm9e",	       	      		 FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED },
    {"strongarm",	             FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
    {"strongarm110",           FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
    {"strongarm1100",          FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
--- 363,369 ----
    {"arm920t",	                         FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
    {"arm940t",	                         FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
    {"arm9tdmi",	                         FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
!   {"armmaverick",      	      		 FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED |             FL_MAVERICK },
    {"strongarm",	             FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
    {"strongarm110",           FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
    {"strongarm1100",          FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
*************** arm_override_options ()
*** 481,486 ****
--- 487,493 ----
  	{ TARGET_CPU_arm9,      "arm9" },
  	{ TARGET_CPU_strongarm, "strongarm" },
  	{ TARGET_CPU_xscale,    "xscale" },
+ 	{ TARGET_CPU_armmaverick, "armmaverick" },
  	{ TARGET_CPU_generic,   "arm" },
  	{ 0, 0 }
        };
*************** arm_override_options ()
*** 679,684 ****
--- 686,705 ----
    thumb_code	    = (TARGET_ARM == 0);
    arm_is_6_or_7     = (((tune_flags & (FL_MODE26 | FL_MODE32))
  		       && !(tune_flags & FL_ARCH4))) != 0;
+   arm_is_maverick   = (tune_flags & FL_MAVERICK) != 0;
+ 
+   if (arm_is_maverick)
+     {
+       arm_fpu = FP_MAVERICK;
+ 
+       if (TARGET_SOFT_FLOAT)
+ 	warning ("-msoft-float option ignored because armmaverick chip selected");
+ 
+       /* Ignore -mhard-float if -mcpu=armmaverick.  */
+       if (TARGET_HARD_FLOAT)
+ 	target_flags ^= ARM_FLAG_SOFT_FLOAT;
+     }
+   else
  
    /* Default value for floating point code... if no co-processor
       bus, then schedule for emulated floating point.  Otherwise,
*************** arm_override_options ()
*** 700,705 ****
--- 721,734 ----
    else
      arm_fpu_arch = FP_DEFAULT;
    
+   if (TARGET_FPE)
+     {
+       if (arm_fpu == FP_SOFT3)
+ 	arm_fpu = FP_SOFT2;
+       else if (arm_fpu == FP_MAVERICK)
+ 	warning ("-mpfpe switch not supported by armmaverick target cpu - ignored.");
+     }
+   else
    if (TARGET_FPE && arm_fpu != FP_HARD)
      arm_fpu = FP_SOFT2;
    
*************** fpu_add_operand (op, mode)
*** 3280,3285 ****
--- 3309,3570 ----
    return FALSE;
  }
  
+ /* Return nonzero if OP is a valid Maverick memory address pattern.  */
+ 
+ int
+ maverick_memory_offset (op)
+      rtx op;
+ {
+ 
+   /* Reject eliminable registers.  */
+   if (! (reload_in_progress || reload_completed)
+       && (   reg_mentioned_p (frame_pointer_rtx, op)
+ 	  || reg_mentioned_p (arg_pointer_rtx, op)
+ 	  || reg_mentioned_p (virtual_incoming_args_rtx, op)
+ 	  || reg_mentioned_p (virtual_outgoing_args_rtx, op)
+ 	  || reg_mentioned_p (virtual_stack_dynamic_rtx, op)
+ 	  || reg_mentioned_p (virtual_stack_vars_rtx, op)))
+     return 0;
+ 
+   if (GET_CODE (op) == MEM)
+     {
+       rtx ind;
+ 
+       ind = XEXP (op, 0);
+ 
+       /* Match: (mem (reg)).  */
+       if (GET_CODE (ind) == REG)
+ 	return 1;
+ 
+       /* Match:
+ 	 (mem (plus (reg)
+ 	            (const))).  */
+       if (GET_CODE (ind) == PLUS
+ 	  && GET_CODE (XEXP (ind, 0)) == REG
+ 	  && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
+ 	  && GET_CODE (XEXP (ind, 1)) == CONST_INT)
+ 	return 1;
+     }
+ 
+   return 0;
+ }
+ 
+ /* Return nonzero if OP is a Maverick or general register.  */
+ 
+ int
+ maverick_register_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   if (GET_MODE (op) != mode && mode != VOIDmode)
+     return FALSE;
+ 
+   if (GET_CODE (op) == SUBREG)
+     op = SUBREG_REG (op);
+ 
+   return (GET_CODE (op) == REG
+ 	  && (REGNO_REG_CLASS (REGNO (op)) == MAVERICK_REGS
+ 	      || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
+ }
+ 
+ /* Return nonzero if OP is a maverick FP register.  */
+ 
+ int
+ maverick_fp_register (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   if (GET_MODE (op) != mode && mode != VOIDmode)
+     return FALSE;
+ 
+   if (GET_CODE (op) == SUBREG)
+     op = SUBREG_REG (op);
+ 
+   return (GET_CODE (op) == REG
+ 	  && (REGNO (op) >= FIRST_PSEUDO_REGISTER
+ 	      || REGNO_REG_CLASS (REGNO (op)) == MAVERICK_REGS));
+ }
+ 
+ /* Return nonzero if OP is a 6bit constant (0..63).  */
+ 
+ int
+ maverick_shift_const (op, mode)
+      rtx op;
+      enum machine_mode mode ATTRIBUTE_UNUSED;
+ {
+   return (GET_CODE (op) == CONST_INT
+ 	  && INTVAL (op) >= 0
+ 	  && INTVAL (op) < 64);
+ }
+ 
+ /* Return nonzero if INSN is an LDR R0,ADDR instruction.  */
+ 
+ static int
+ is_load_address (insn)
+      rtx insn;
+ {
+   rtx body, lhs, rhs;;
+ 
+   if (!insn)
+     return 0;
+ 
+   if (GET_CODE (insn) != INSN)
+     return 0;
+ 
+   body = PATTERN (insn);
+ 
+   if (GET_CODE (body) != SET)
+     return 0;
+ 
+   lhs = XEXP (body, 0);
+   rhs = XEXP (body, 1);
+ 
+   return (GET_CODE (lhs) == REG
+ 	  && REGNO_REG_CLASS (REGNO (lhs)) == GENERAL_REGS
+ 	  && (GET_CODE (rhs) == MEM
+ 	      || GET_CODE (rhs) == SYMBOL_REF));
+ }
+ 
+ /* Return nonzero if INSN is a Maverick instruction.  */
+ 
+ static int
+ is_maverick_insn (insn)
+      rtx insn;
+ {
+   enum attr_maverick attr;
+ 
+   /* get_attr aborts on USE and CLOBBER.  */
+   if (!insn
+       || GET_CODE (insn) != INSN
+       || GET_CODE (PATTERN (insn)) == USE
+       || GET_CODE (PATTERN (insn)) == CLOBBER)
+     return 0;
+ 
+   attr = get_attr_maverick (insn);
+ 
+   return attr != MAVERICK_NO;
+ }
+ 
+ /* Maverick reorg for invalid instruction combinations.  */
+ 
+ static void
+ maverick_reorg (first)
+      rtx first;
+ {
+   enum attr_maverick attr;
+   rtx body = PATTERN (first);
+   rtx t;
+   int nops;
+ 
+   /* Any branch must be followed by 2 non Maverick instructions.  */
+   if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN)
+     {
+       nops = 0;
+       t = next_nonnote_insn (first);
+ 
+       if (is_maverick_insn (t))
+ 	++ nops;
+ 
+       if (is_maverick_insn (next_nonnote_insn (t)))
+ 	++ nops;
+ 
+       while (nops --)
+ 	emit_insn_after (gen_nop (), first);
+ 
+       return;
+     }
+ 
+   /* (float (blah)) is in parallel with a clobber.  */
+   if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
+     body = XVECEXP (body, 0, 0);
+ 
+   if (GET_CODE (body) == SET)
+     {
+       rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1);
+ 
+       /* cfldrd, cfldr64, cfstrd, cfstr64 must
+ 	 be followed by a non Maverick insn.  */
+       if (get_attr_maverick (first) == MAVERICK_DOUBLE)
+ 	{
+ 	  if (is_maverick_insn (next_nonnote_insn (first)))
+ 	    emit_insn_after (gen_nop (), first);
+ 
+ 	  return;
+ 	}
+       else if (is_load_address (first))
+ 	{
+ 	  unsigned int arm_regno;
+ 
+ 	  /* Any ldr/cfmvdlr, ldr/cfmvdhr, ldr/cfmvsr, ldr/cfmv64lr,
+ 	     ldr/cfmv64hr combination where the Rd field is the same
+ 	     in both instructions must be split with a non Maverick
+ 	     insn.  Example:
+ 
+ 	     ldr r0, blah
+ 	     nop
+ 	     cfmvsr mvf0, r0.  */
+ 
+ 	  /* Get Arm register number for ldr insn.  */
+ 	  if (GET_CODE (lhs) == REG)
+ 	    arm_regno = REGNO (lhs);
+ 	  else if (GET_CODE (rhs) == REG)
+ 	    arm_regno = REGNO (rhs);
+ 	  else
+ 	    abort ();
+ 
+ 	  /* Next insn.  */
+ 	  first = next_nonnote_insn (first);
+ 
+ 	  if (!is_maverick_insn (first))
+ 	    return;
+ 
+ 	  body = PATTERN (first);
+ 
+           /* (float (blah)) is in parallel with a clobber.  */
+           if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0))
+ 	    body = XVECEXP (body, 0, 0);
+ 
+ 	  if (GET_CODE (body) == FLOAT)
+ 	    body = XEXP (body, 0);
+ 
+ 	  if (get_attr_maverick (first) == MAVERICK_MOVE
+ 	      && GET_CODE (XEXP (body, 1)) == REG
+ 	      && arm_regno == REGNO (XEXP (body, 1)))
+ 	    emit_insn_after (gen_nop (), first);
+ 
+ 	  return;
+ 	}
+     }
+ 
+   /* get_attr aborts on USE and CLOBBER.  */
+   if (!first
+       || GET_CODE (first) != INSN
+       || GET_CODE (PATTERN (first)) == USE
+       || GET_CODE (PATTERN (first)) == CLOBBER)
+     return;
+ 
+   attr = get_attr_maverick (first);
+ 
+   /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...)
+      must be followed by a non-coprocessor instruction.  */
+   if (attr == MAVERICK_COMPARE)
+     {
+       nops = 0;
+ 
+       t = next_nonnote_insn (first);
+ 
+       if (is_maverick_insn (t))
+ 	++ nops;
+ 
+       if (is_maverick_insn (next_nonnote_insn (t)))
+ 	++ nops;
+ 
+       while (nops --)
+ 	emit_insn_after (gen_nop (), first);
+ 
+       return;
+     }
+ }
  /* Return nonzero if OP is a constant power of two.  */
  
  int
*************** arm_select_cc_mode (op, x, y)
*** 4779,4784 ****
--- 5064,5071 ----
  	case LE:
  	case GT:
  	case GE:
+ 	  if (TARGET_MAVERICK)
+ 	    return CCFPmode;
  	  return CCFPEmode;
  
  	default:
*************** arm_reorg (first)
*** 6089,6094 ****
--- 6376,6387 ----
    /* Scan all the insns and record the operands that will need fixing.  */
    for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn (insn))
      {
+       if (TARGET_MAVERICK_FIX_INVALID_INSNS
+           && (is_maverick_insn (insn)
+ 	      || GET_CODE (insn) == JUMP_INSN
+ 	      || is_load_address (insn)))
+ 	maverick_reorg (insn);
+ 
        if (GET_CODE (insn) == BARRIER)
  	push_minipool_barrier (insn, address);
        else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
*************** arm_print_operand (stream, x, code)
*** 8487,8492 ****
--- 8780,8795 ----
        fprintf (stream, "%s", arithmetic_instr (x, 1));
        return;
  
+     /* Truncate Maverick shift counts.  */
+     case 's':
+       if (GET_CODE (x) == CONST_INT)
+ 	{
+ 	  fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x3f);
+ 	  return;
+ 	}
+       arm_print_operand (stream, x, 0);
+       return;
+ 
      case 'I':
        fprintf (stream, "%s", arithmetic_instr (x, 0));
        return;
*************** arm_print_operand (stream, x, code)
*** 8593,8598 ****
--- 8896,8938 ----
  	fputs (thumb_condition_code (x, 1), stream);
        return;
  
+     /* Maverick registers can be accessed in a variety of ways:
+          single floating point (f)
+ 	 double floating point (d)
+ 	 32bit integer         (fx)
+ 	 64bit integer         (dx).  */
+     case 'W':			/* Maverick register in F mode.  */
+     case 'X':			/* Maverick register in D mode.  */
+     case 'Y':			/* Maverick register in FX mode.  */
+     case 'Z':			/* Maverick register in DX mode.  */
+       if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != MAVERICK_REGS)
+ 	abort ();
+ 
+       fprintf (stream, "mv%s%s",
+ 	       code == 'W' ? "f"
+ 	       : code == 'X' ? "d"
+ 	       : code == 'Y' ? "fx" : "dx", reg_names[REGNO (x)] + 2);
+ 
+       return;
+ 
+     /* Print maverick register in the mode specified by the register's
+        mode.  */
+     case 'V':
+       {
+ 	int mode = GET_MODE (x);
+ 
+ 	if (GET_CODE (x) != REG
+ 	    || REGNO_REG_CLASS (REGNO (x)) != MAVERICK_REGS)
+ 	  abort ();
+ 
+ 	fprintf (stream, "mv%s%s",
+ 		 mode == DFmode ? "d"
+ 		 : mode == SImode ? "fx"
+ 		 : mode == DImode ? "dx"
+ 		 : "f", reg_names[REGNO (x)] + 2);
+ 
+ 	return;
+       }
      default:
        if (x == 0)
  	abort ();
*************** arm_final_prescan_insn (insn)
*** 9084,9089 ****
--- 9424,9440 ----
  		    || GET_CODE (scanbody) == PARALLEL)
  		  || get_attr_conds (this_insn) != CONDS_NOCOND)
  		fail = TRUE;
+ 	      /* A conditional maverick instruction must be followed by
+ 		 a non Maverick instruction.  However, since we
+ 		 conditionalize instructions in this function and by
+ 		 the time we get here we can't add instructions
+ 		 (nops), because shorten_branches() has already been
+ 		 called, we will disable conditionalizing Maverick
+ 		 instructions to be safe.  */
+ 	      if (GET_CODE (scanbody) != USE
+ 		  && GET_CODE (scanbody) != CLOBBER
+ 		  && get_attr_maverick (this_insn) != MAVERICK_NO)
+ 		fail = TRUE;
  	      break;
  
  	    default:
*************** arm_hard_regno_mode_ok (regno, mode)
*** 9167,9172 ****
--- 9518,9531 ----
         start of an even numbered register pair.  */
      return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
  
+   if (IS_MAVERICK_REGNUM (regno))
+     /* We have outlawed SI values in Maverick registers because they
+        reside in the lower 32 bits, but SF values reside in the
+        upper 32 bits.  This causes gcc all sorts of grief.  We can't
+        even split the registers into pairs because Maverick SI values
+        get sign extended to 64bits.  */
+     return (GET_MODE_CLASS (mode) == MODE_FLOAT) || (mode == DImode);
+ 
    if (regno <= LAST_ARM_REGNUM)
      /* We allow any value to be stored in the general regisetrs.  */
      return 1;
*************** arm_regno_class (regno)
*** 9206,9211 ****
--- 9565,9572 ----
    if (regno == CC_REGNUM)
      return NO_REGS;
  
+   if (IS_MAVERICK_REGNUM (regno))
+     return MAVERICK_REGS;
    return FPU_REGS;
  }
  
Index: config/arm/arm.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/arm.h,v
retrieving revision 1.155
diff -c -p -r1.155 arm.h
*** config/arm/arm.h	8 Aug 2002 11:08:34 -0000	1.155
--- config/arm/arm.h	14 Aug 2002 15:36:18 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 91,96 ****
--- 91,97 ----
  #define TARGET_CPU_arm9		0x0080
  #define TARGET_CPU_arm9tdmi	0x0080
  #define TARGET_CPU_xscale       0x0100
+ #define TARGET_CPU_armmaverick	0x0200
  /* Configure didn't specify.  */
  #define TARGET_CPU_generic	0x8000
  
*************** extern GTY(()) rtx aof_pic_label;
*** 159,164 ****
--- 160,173 ----
  #if TARGET_CPU_DEFAULT == TARGET_CPU_xscale
  #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__"
  #else
+ #if TARGET_CPU_DEFAULT == TARGET_CPU_armmaverick
+ #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__ -D__MAVERICK__"
+ /* Set TARGET_DEFAULT to the default, but without soft-float.  */
+ #ifdef TARGET_DEFAULT
+ #undef TARGET_DEFAULT
+ #define TARGET_DEFAULT	(ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+ #endif /* TARGET_CPU_DEFAULT */
+ #else
  Unrecognized value in TARGET_CPU_DEFAULT.
  #endif
  #endif
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 166,171 ****
--- 175,181 ----
  #endif
  #endif
  #endif
+ #endif
  
  #undef  CPP_SPEC
  #define CPP_SPEC "%(cpp_cpu_arch) %(subtarget_cpp_spec)			\
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 207,212 ****
--- 217,224 ----
  %{march=strongarm1100:-D__ARM_ARCH_4__} \
  %{march=xscale:-D__ARM_ARCH_5TE__} \
  %{march=xscale:-D__XSCALE__} \
+ %{march=armmaverick:-D__ARM_ARCH_4T__} \
+ %{march=armmaverick:-D__MAVERICK__} \
  %{march=armv2:-D__ARM_ARCH_2__} \
  %{march=armv2a:-D__ARM_ARCH_2__} \
  %{march=armv3:-D__ARM_ARCH_3__} \
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 246,251 ****
--- 258,265 ----
   %{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
   %{mcpu=xscale:-D__ARM_ARCH_5TE__} \
   %{mcpu=xscale:-D__XSCALE__} \
+  %{mcpu=armmaverick:-D__ARM_ARCH_4T__} \
+  %{mcpu=armmaverick:-D__MAVERICK__} \
   %{!mcpu*:%(cpp_cpu_arch_default)}} \
  "
  
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 281,286 ****
--- 295,303 ----
  #define TARGET_VERSION fputs (" (ARM/generic)", stderr);
  #endif
  
+ /* Fix invalid Maverick instruction combinations by inserting NOPs.  */
+ #define MAVERICK_FIX_INVALID_INSNS	(1 << 24)
+ 
  /* Nonzero if the function prologue (and epilogue) should obey
     the ARM Procedure Call Standard.  */
  #define ARM_FLAG_APCS_FRAME	(1 << 0)
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 375,380 ****
--- 392,399 ----
  #define TARGET_MMU_TRAPS		(target_flags & ARM_FLAG_MMU_TRAPS)
  #define TARGET_SOFT_FLOAT		(target_flags & ARM_FLAG_SOFT_FLOAT)
  #define TARGET_HARD_FLOAT		(! TARGET_SOFT_FLOAT)
+ #define TARGET_MAVERICK			(arm_is_maverick)
+ #define TARGET_ANY_HARD_FLOAT		(TARGET_HARD_FLOAT || TARGET_MAVERICK)
  #define TARGET_BIG_END			(target_flags & ARM_FLAG_BIG_END)
  #define TARGET_INTERWORK		(target_flags & ARM_FLAG_INTERWORK)
  #define TARGET_LITTLE_WORDS		(target_flags & ARM_FLAG_LITTLE_WORDS)
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 390,395 ****
--- 409,415 ----
  #define TARGET_BACKTRACE	        (leaf_function_p ()	      			\
  				         ? (target_flags & THUMB_FLAG_LEAF_BACKTRACE)	\
  				         : (target_flags & THUMB_FLAG_BACKTRACE))
+ #define TARGET_MAVERICK_FIX_INVALID_INSNS	(target_flags & MAVERICK_FIX_INVALID_INSNS)
  
  /* SUBTARGET_SWITCHES is used to add flags on a per-config basis.  */
  #ifndef SUBTARGET_SWITCHES
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 468,473 ****
--- 488,497 ----
     N_("Thumb: Assume function pointers may go to non-Thumb aware code") }, \
    {"no-caller-super-interworking", -THUMB_FLAG_CALLER_SUPER_INTERWORKING,  \
     "" },								   \
+   {"maverick-fix-invalid-insns", MAVERICK_FIX_INVALID_INSNS,		   \
+    N_("Maverick: Place NOPs to avoid invalid instruction combinations") },   \
+   {"no-maverick-fix-invalid-insns", -MAVERICK_FIX_INVALID_INSNS,		   \
+    N_("Maverick: Not place NOPs to avoid invalid instruction combinations") }, \
    SUBTARGET_SWITCHES							   \
    {"",				TARGET_DEFAULT, "" }			   \
  }
*************** enum floating_point_type
*** 517,523 ****
  {
    FP_HARD,
    FP_SOFT2,
!   FP_SOFT3
  };
  
  /* Recast the floating point class to be the floating point attribute.  */
--- 541,548 ----
  {
    FP_HARD,
    FP_SOFT2,
!   FP_SOFT3,
!   FP_MAVERICK
  };
  
  /* Recast the floating point class to be the floating point attribute.  */
*************** extern enum floating_point_type arm_fpu_
*** 535,540 ****
--- 560,570 ----
  #define FP_DEFAULT FP_SOFT2
  #endif
  
+ #if TARGET_CPU_DEFAULT == TARGET_CPU_armmaverick
+ #undef FP_DEFAULT
+ #define FP_DEFAULT FP_MAVERICK
+ #endif
+ 
  /* Nonzero if the processor has a fast multiply insn, and one that does
     a 64-bit multiply of two 32-bit values.  */
  extern int arm_fast_multiply;
*************** extern int thumb_code;
*** 557,562 ****
--- 587,595 ----
  /* Nonzero if this chip is a StrongARM.  */
  extern int arm_is_strong;
  
+ /* Nonzero if this chip is a Maverick variant.  */
+ extern int arm_is_maverick;
+ 
  /* Nonzero if this chip is an XScale.  */
  extern int arm_is_xscale;
  
*************** extern int arm_is_6_or_7;
*** 667,673 ****
  
  /* Define this if most significant word of doubles is the lowest numbered.
     This is always true, even when in little-endian mode.  */
! #define FLOAT_WORDS_BIG_ENDIAN 1
  
  #define UNITS_PER_WORD	4
  
--- 700,706 ----
  
  /* Define this if most significant word of doubles is the lowest numbered.
     This is always true, even when in little-endian mode.  */
! #define FLOAT_WORDS_BIG_ENDIAN (!TARGET_MAVERICK || WORDS_BIG_ENDIAN)
  
  #define UNITS_PER_WORD	4
  
*************** extern const char * structure_size_strin
*** 755,760 ****
--- 788,797 ----
  			elimination code won't get rid of sfp.  It tracks
  			fp exactly at all times.
  
+   	mvf0		maverick floating point result
+ 	mvf1-mvf3	maverick floating point scratch
+ 	mvf4-mvf15   S	maverick floating point variable.
+ 
     *: See CONDITIONAL_REGISTER_USAGE  */
  
  /* The stack backtrace structure is as follows:
*************** extern const char * structure_size_strin
*** 819,824 ****
--- 856,873 ----
  	   regno <= LAST_ARM_FP_REGNUM; ++regno)		\
  	fixed_regs[regno] = call_used_regs[regno] = 1;		\
      }								\
+   if (TARGET_MAVERICK)						\
+     {								\
+       for (regno = FIRST_ARM_FP_REGNUM;				\
+ 	   regno <= LAST_ARM_FP_REGNUM; ++ regno)		\
+ 	fixed_regs[regno] = call_used_regs[regno] = 1;		\
+       for (regno = FIRST_MAVERICK_FP_REGNUM;			\
+ 	   regno <= LAST_MAVERICK_FP_REGNUM; ++ regno)		\
+ 	{							\
+ 	  fixed_regs[regno] = 0;				\
+ 	  call_used_regs[regno] = regno < FIRST_MAVERICK_FP_REGNUM + 4; \
+ 	}							\
+     }								\
    if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)		\
      {								\
        fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
*************** extern const char * structure_size_strin
*** 936,941 ****
--- 985,995 ----
  #define FIRST_ARM_FP_REGNUM 	16
  #define LAST_ARM_FP_REGNUM  	23
  
+ #define FIRST_MAVERICK_FP_REGNUM	27
+ #define LAST_MAVERICK_FP_REGNUM	42
+ #define IS_MAVERICK_REGNUM(REGNUM) \
+   (((REGNUM) >= FIRST_MAVERICK_FP_REGNUM) && ((REGNUM) <= LAST_MAVERICK_FP_REGNUM))
+ 
  /* Base register for access to local variables of the function.  */
  #define FRAME_POINTER_REGNUM	25
  
*************** extern const char * structure_size_strin
*** 943,949 ****
  #define ARG_POINTER_REGNUM	26
  
  /* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP.  */
! #define FIRST_PSEUDO_REGISTER	27
  
  /* Value should be nonzero if functions must have frame pointers.
     Zero means the frame pointer need not be set up (and parms may be accessed
--- 997,1003 ----
  #define ARG_POINTER_REGNUM	26
  
  /* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP.  */
! #define FIRST_PSEUDO_REGISTER	43
  
  /* Value should be nonzero if functions must have frame pointers.
     Zero means the frame pointer need not be set up (and parms may be accessed
*************** enum reg_class
*** 1009,1014 ****
--- 1063,1069 ----
  {
    NO_REGS,
    FPU_REGS,
+   MAVERICK_REGS,
    LO_REGS,
    STACK_REG,
    BASE_REGS,
*************** enum reg_class
*** 1026,1031 ****
--- 1081,1087 ----
  {			\
    "NO_REGS",		\
    "FPU_REGS",		\
+   "MAVERICK_REGS",	\
    "LO_REGS",		\
    "STACK_REG",		\
    "BASE_REGS",		\
*************** enum reg_class
*** 1042,1047 ****
--- 1098,1104 ----
  {					\
    { 0x0000000 }, /* NO_REGS  */		\
    { 0x0FF0000 }, /* FPU_REGS */		\
+   { 0xf8000000, 0x000007FF }, /* MAVERICK_REGS */	\
    { 0x00000FF }, /* LO_REGS */		\
    { 0x0002000 }, /* STACK_REG */	\
    { 0x00020FF }, /* BASE_REGS */	\
*************** enum reg_class
*** 1079,1084 ****
--- 1136,1142 ----
     ARM, but several more letters for the Thumb.  */
  #define REG_CLASS_FROM_LETTER(C)  	\
    (  (C) == 'f' ? FPU_REGS		\
+    : (C) == 'v' ? MAVERICK_REGS		\
     : (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS)	\
     : TARGET_ARM ? NO_REGS		\
     : (C) == 'h' ? HI_REGS		\
*************** enum reg_class
*** 1139,1144 ****
--- 1197,1203 ----
  
  #define EXTRA_CONSTRAINT_ARM(OP, C)					    \
    ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG :    \
+    (C) == 'T' ? maverick_memory_offset (OP) : 		    		    \
     (C) == 'R' ? (GET_CODE (OP) == MEM					    \
  		 && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF		    \
  		 && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) :		    \
*************** enum reg_class
*** 1187,1199 ****
     
  /* If we need to load shorts byte-at-a-time, then we need a scratch. */
  #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)		\
    (TARGET_ARM ?							\
     (((MODE) == HImode && ! arm_arch4 && TARGET_MMU_TRAPS	\
       && (GET_CODE (X) == MEM					\
  	 || ((GET_CODE (X) == REG || GET_CODE (X) == SUBREG)	\
  	     && true_regnum (X) == -1)))			\
      ? GENERAL_REGS : NO_REGS)					\
!    : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X))
  
  /* Try a machine-dependent way of reloading an illegitimate address
     operand.  If we find one, push the reload and jump to WIN.  This
--- 1246,1264 ----
     
  /* If we need to load shorts byte-at-a-time, then we need a scratch. */
  #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)		\
+   /* Cannot load constants into Maverick registers.  */		\
+   ((TARGET_MAVERICK						\
+      && (CLASS) == MAVERICK_REGS					\
+      && (CONSTANT_P (X)						\
+ 	 || GET_CODE (X) == SYMBOL_REF))			\
+     ? GENERAL_REGS :						\
    (TARGET_ARM ?							\
     (((MODE) == HImode && ! arm_arch4 && TARGET_MMU_TRAPS	\
       && (GET_CODE (X) == MEM					\
  	 || ((GET_CODE (X) == REG || GET_CODE (X) == SUBREG)	\
  	     && true_regnum (X) == -1)))			\
      ? GENERAL_REGS : NO_REGS)					\
!    : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X)))
  
  /* Try a machine-dependent way of reloading an illegitimate address
     operand.  If we find one, push the reload and jump to WIN.  This
*************** enum reg_class
*** 1216,1221 ****
--- 1281,1289 ----
  									   \
  	  if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode))	   \
  	    low = ((val & 0xf) ^ 0x8) - 0x8;				   \
+ 	  else if (TARGET_MAVERICK)					   \
+ 	    /* Need to be careful, -256 is not a valid offset.  */	   \
+ 	    low = val >= 0 ? (val & 0xff) : -((-val) & 0xff);		   \
  	  else if (MODE == SImode					   \
  		   || (MODE == SFmode && TARGET_SOFT_FLOAT)		   \
  		   || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
*************** enum reg_class
*** 1288,1299 ****
     needed to represent mode MODE in a register of class CLASS.
     ARM regs are UNITS_PER_WORD bits while FPU regs can hold any FP mode */
  #define CLASS_MAX_NREGS(CLASS, MODE)  \
!   ((CLASS) == FPU_REGS ? 1 : ARM_NUM_REGS (MODE))
  
  /* Moves between FPU_REGS and GENERAL_REGS are two memory insns.  */
  #define REGISTER_MOVE_COST(MODE, FROM, TO)		\
    (TARGET_ARM ?						\
     ((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 :	\
      (FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2)	\
     :							\
     ((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2)
--- 1356,1379 ----
     needed to represent mode MODE in a register of class CLASS.
     ARM regs are UNITS_PER_WORD bits while FPU regs can hold any FP mode */
  #define CLASS_MAX_NREGS(CLASS, MODE)  \
!   ((CLASS) == FPU_REGS || (CLASS) == MAVERICK_REGS ? 1 : ARM_NUM_REGS (MODE))
! 
! /* If defined, gives a class of registers that cannot be used as the
!    operand of a SUBREG that changes the mode of the object illegally.  */
! 
! #define CLASS_CANNOT_CHANGE_MODE	MAVERICK_REGS
! 
! /* Define illegal mode changes for CLASS_CANNOT_CHANGE_MODE.  */
! 
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM, TO) \
!   (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
  
  /* Moves between FPU_REGS and GENERAL_REGS are two memory insns.  */
  #define REGISTER_MOVE_COST(MODE, FROM, TO)		\
    (TARGET_ARM ?						\
     ((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 :	\
+     (FROM) == MAVERICK_REGS && (TO) != MAVERICK_REGS ? 20 :	\
+     (FROM) != MAVERICK_REGS && (TO) == MAVERICK_REGS ? 20 :	\
      (FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2)	\
     :							\
     ((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2)
*************** enum reg_class
*** 1346,1351 ****
--- 1426,1433 ----
  #define LIBCALL_VALUE(MODE)  \
    (TARGET_ARM && TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT \
     ? gen_rtx_REG (MODE, FIRST_ARM_FP_REGNUM) \
+    : TARGET_ARM && TARGET_MAVERICK && GET_MODE_CLASS (MODE) == MODE_FLOAT \
+    ? gen_rtx_REG (MODE, FIRST_MAVERICK_FP_REGNUM) 			\
     : gen_rtx_REG (MODE, ARG_REGISTER (1)))
  
  /* Define how to find the value returned by a function.
*************** enum reg_class
*** 1355,1364 ****
  #define FUNCTION_VALUE(VALTYPE, FUNC) \
    LIBCALL_VALUE (TYPE_MODE (VALTYPE))
  
! /* 1 if N is a possible register number for a function value.
!    On the ARM, only r0 and f0 can return results.  */
  #define FUNCTION_VALUE_REGNO_P(REGNO)  \
    ((REGNO) == ARG_REGISTER (1) \
     || (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT))
  
  /* How large values are returned */
--- 1437,1448 ----
  #define FUNCTION_VALUE(VALTYPE, FUNC) \
    LIBCALL_VALUE (TYPE_MODE (VALTYPE))
  
! /* 1 if N is a possible register number for a function value.  On the
!    ARM, only r0 and f0 can return results.  On a Maverick chip, mvf0 can
!    return results.  */
  #define FUNCTION_VALUE_REGNO_P(REGNO)  \
    ((REGNO) == ARG_REGISTER (1) \
+    || (TARGET_ARM && ((REGNO) == FIRST_MAVERICK_FP_REGNUM) && TARGET_MAVERICK)\
     || (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT))
  
  /* How large values are returned */
*************** typedef struct
*** 1947,1952 ****
--- 2031,2044 ----
  	      && (INTVAL (INDEX) & 3) == 0)				\
  	    goto LABEL;							\
  	}								\
+       else if (TARGET_MAVERICK						\
+ 	       && (GET_MODE_CLASS (MODE) == MODE_FLOAT			\
+ 		   || (MODE) == DImode))				\
+         {								\
+           if (code == CONST_INT && INTVAL (INDEX) < 255			\
+               && INTVAL (INDEX) > -255)					\
+             goto LABEL;							\
+         }								\
        else								\
  	{								\
  	  if (ARM_INDEX_REGISTER_RTX_P (INDEX)				\
*************** extern int making_const_table;
*** 2777,2782 ****
--- 2869,2877 ----
    {"multi_register_push", {PARALLEL}},					\
    {"cc_register", {REG}},						\
    {"logical_binary_operator", {AND, IOR, XOR}},				\
+   {"maverick_register_operand", {REG}},					\
+   {"maverick_fp_register", {REG}},					\
+   {"maverick_shift_const", {CONST_INT}},					\
    {"dominant_cc_register", {REG}},
  
  /* Define this if you have special predicates that know special things
Index: config/arm/arm.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/arm.md,v
retrieving revision 1.104
diff -c -p -r1.104 arm.md
*** config/arm/arm.md	29 Jul 2002 12:41:46 -0000	1.104
--- config/arm/arm.md	14 Aug 2002 15:36:32 -0000
***************
*** 123,128 ****
--- 123,154 ----
  ; performance we should try and group them together).
  (define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr")))
  
+ (define_attr "maverick_fpu" "fpa,fpe2,fpe3,yes" (const (symbol_ref "arm_fpu_attr")))
+ 
+ ; Classification of each insn
+ ; farith	Floating point arithmetic (4 cycle)
+ ; dmult		Double multiplies (7 cycle)
+ (define_attr "maverick_type" "normal,farith,dmult" (const_string "normal"))
+ 
+ ; Maverick types for invalid insn combinations
+ ; no		Not a maverick insn
+ ; yes		Maverick insn
+ ; double	cfldrd, cfldr64, cfstrd, cfstr64
+ ; compare	cfcmps, cfcmpd, cfcmp32, cfcmp64
+ ; move		cfmvdlr, cfmvdhr, cfmvsr, cfmv64lr, cfmv64hr
+ (define_attr "maverick" "no,yes,double,compare,move" (const_string "no"))
+ 
+ (define_function_unit "maverick_fpa" 1 0
+   (and (eq_attr "maverick_fpu" "yes")
+        (eq_attr "maverick_type" "farith")) 4 1)
+ 
+ (define_function_unit "maverick_fpa" 1 0
+   (and (eq_attr "maverick_fpu" "yes")
+        (eq_attr "maverick_type" "dmult")) 7 4)
+ 
+ (define_function_unit "maverick_fpa" 1 0
+   (and (eq_attr "maverick_fpu" "yes")
+        (eq_attr "maverick_type" "normal")) 1 1)
  ; LENGTH of an instruction (in bytes)
  (define_attr "length" "" (const_int 4))
  
***************
*** 400,405 ****
--- 426,433 ----
  ;; Note: For DImode insns, there is normally no reason why operands should
  ;; not be in the same register, what we don't want is for something being
  ;; written to partially overlap something that is an input.
+ ;; Maverick 64bit additions should not be split because we have a native
+ ;; 64bit addition instructions.
  
  (define_expand "adddi3"
   [(parallel
***************
*** 409,414 ****
--- 437,455 ----
      (clobber (reg:CC CC_REGNUM))])]
    "TARGET_EITHER"
    "
+ {
+   extern int maverick_fp_register (rtx, enum machine_mode);
+ 
+   if (TARGET_MAVERICK)
+     {
+       if (!maverick_fp_register (operands[0], DImode))
+         operands[0] = force_reg (DImode, operands[0]);
+       if (!maverick_fp_register (operands[1], DImode))
+         operands[1] = force_reg (DImode, operands[1]);
+       emit_insn (gen_maverick_adddi3 (operands[0], operands[1], operands[2]));
+       DONE;
+     }
+ }
    if (TARGET_THUMB)
      {
        if (GET_CODE (operands[1]) != REG)
***************
*** 419,424 ****
--- 460,475 ----
    "
  )
  
+ (define_insn "maverick_adddi3"
+   [(set (match_operand:DI          0 "maverick_fp_register" "=v")
+ 	(plus:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		 (match_operand:DI 2 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfadd64%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*thumb_adddi3"
    [(set (match_operand:DI          0 "register_operand" "=l")
  	(plus:DI (match_operand:DI 1 "register_operand" "%0")
***************
*** 435,441 ****
  	(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
  		 (match_operand:DI 2 "s_register_operand" "r,  0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
--- 486,492 ----
  	(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
  		 (match_operand:DI 2 "s_register_operand" "r,  0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM && !TARGET_MAVERICK"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
***************
*** 463,469 ****
  		  (match_operand:SI 2 "s_register_operand" "r,r"))
  		 (match_operand:DI 1 "s_register_operand" "r,0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
--- 514,520 ----
  		  (match_operand:SI 2 "s_register_operand" "r,r"))
  		 (match_operand:DI 1 "s_register_operand" "r,0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM && !TARGET_MAVERICK"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
***************
*** 492,498 ****
  		  (match_operand:SI 2 "s_register_operand" "r,r"))
  		 (match_operand:DI 1 "s_register_operand" "r,0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
--- 543,549 ----
  		  (match_operand:SI 2 "s_register_operand" "r,r"))
  		 (match_operand:DI 1 "s_register_operand" "r,0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM && !TARGET_MAVERICK"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
***************
*** 568,573 ****
--- 619,634 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_addsi3"
+   [(set (match_operand:SI          0 "maverick_fp_register" "=v")
+ 	(plus:SI (match_operand:SI 1 "maverick_fp_register" "v")
+ 		 (match_operand:SI 2 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfadd32%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  ;; Register group 'k' is a single register group containing only the stack
  ;; register.  Trying to reload it will always fail catastrophically,
  ;; so never allow those alternatives to match if reloading is needed.
***************
*** 795,801 ****
     (set_attr "length" "4,8")]
  )
  
! (define_insn "addsf3"
    [(set (match_operand:SF          0 "s_register_operand" "=f,f")
  	(plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
  		 (match_operand:SF 2 "fpu_add_operand"    "fG,H")))]
--- 856,874 ----
     (set_attr "length" "4,8")]
  )
  
! ;; define_insn replaced by define_expand and define_insn
! (define_expand "addsf3"
!   [(set (match_operand:SF          0 "s_register_operand" "")
! 	(plus:SF (match_operand:SF 1 "s_register_operand" "")
! 		 (match_operand:SF 2 "fpu_add_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK
!       && !maverick_fp_register (operands[2], SFmode))
!     operands[2] = force_reg (SFmode, operands[2]);
! ")
! 
! (define_insn "*arm_addsf3"
    [(set (match_operand:SF          0 "s_register_operand" "=f,f")
  	(plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
  		 (match_operand:SF 2 "fpu_add_operand"    "fG,H")))]
***************
*** 807,813 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "adddf3"
    [(set (match_operand:DF          0 "s_register_operand" "=f,f")
  	(plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
  		 (match_operand:DF 2 "fpu_add_operand"    "fG,H")))]
--- 880,908 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "*maverick_addsf3"
!   [(set (match_operand:SF          0 "maverick_fp_register" "=v")
! 	(plus:SF (match_operand:SF 1 "maverick_fp_register" "v")
! 		 (match_operand:SF 2 "maverick_fp_register" "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfadds%?\\t%V0, %V1, %V2"
!   [(set_attr "maverick_type" "farith")
!    (set_attr "maverick" "yes")]
! )
! 
! ;; define_insn replaced by define_expand and define_insn
! (define_expand "adddf3"
!   [(set (match_operand:DF          0 "s_register_operand" "")
! 	(plus:DF (match_operand:DF 1 "s_register_operand" "")
! 		 (match_operand:DF 2 "fpu_add_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK
!       && !maverick_fp_register (operands[2], DFmode))
!     operands[2] = force_reg (DFmode, operands[2]);
! ")
! 
! (define_insn "*arm_adddf3"
    [(set (match_operand:DF          0 "s_register_operand" "=f,f")
  	(plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
  		 (match_operand:DF 2 "fpu_add_operand"    "fG,H")))]
***************
*** 819,824 ****
--- 914,929 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_adddf3"
+   [(set (match_operand:DF          0 "maverick_fp_register" "=v")
+ 	(plus:DF (match_operand:DF 1 "maverick_fp_register" "v")
+ 		 (match_operand:DF 2 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfaddd%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*adddf_esfdf_df"
    [(set (match_operand:DF           0 "s_register_operand" "=f,f")
  	(plus:DF (float_extend:DF
***************
*** 875,880 ****
--- 980,997 ----
      (clobber (reg:CC CC_REGNUM))])]
    "TARGET_EITHER"
    "
+   {
+     extern int maverick_fp_register (rtx, enum machine_mode);
+ 
+     if (TARGET_MAVERICK
+         && TARGET_ARM
+ 	&& maverick_fp_register (operands[0], DImode)
+         && maverick_fp_register (operands[1], DImode))
+       {
+         emit_insn (gen_maverick_subdi3 (operands[0], operands[1], operands[2]));
+         DONE;
+       }
+   }
    if (TARGET_THUMB)
      {
        if (GET_CODE (operands[1]) != REG)
***************
*** 885,890 ****
--- 1002,1017 ----
    "
  )
  
+ (define_insn "maverick_subdi3"
+   [(set (match_operand:DI           0 "maverick_fp_register" "=v")
+ 	(minus:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		  (match_operand:DI 2 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsub64%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*arm_subdi3"
    [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
  	(minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
***************
*** 1019,1024 ****
--- 1146,1160 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_subsi3_insn"
+   [(set (match_operand:SI           0 "maverick_fp_register" "=v")
+ 	(minus:SI (match_operand:SI 1 "maverick_fp_register" "v")
+ 		  (match_operand:SI 2 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsub32%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
  (define_peephole2
    [(match_scratch:SI 3 "r")
     (set (match_operand:SI           0 "s_register_operand" "")
***************
*** 1060,1066 ****
     (set_attr "length" "*,8")]
  )
  
! (define_insn "subsf3"
    [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  	(minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  		  (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
--- 1196,1217 ----
     (set_attr "length" "*,8")]
  )
  
! (define_expand "subsf3"
!   [(set (match_operand:SF           0 "s_register_operand" "")
! 	(minus:SF (match_operand:SF 1 "fpu_rhs_operand" "")
! 		  (match_operand:SF 2 "fpu_rhs_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       if (!maverick_fp_register (operands[1], SFmode))
!         operands[1] = force_reg (SFmode, operands[1]);
!       if (!maverick_fp_register (operands[2], SFmode))
!         operands[2] = force_reg (SFmode, operands[2]);
!     }
! ")
! 
! (define_insn "*arm_subsf3"
    [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  	(minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  		  (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
***************
*** 1071,1077 ****
    [(set_attr "type" "farith")]
  )
  
! (define_insn "subdf3"
    [(set (match_operand:DF           0 "s_register_operand" "=f,f")
  	(minus:DF (match_operand:DF 1 "fpu_rhs_operand"     "f,G")
  		  (match_operand:DF 2 "fpu_rhs_operand"    "fG,f")))]
--- 1222,1253 ----
    [(set_attr "type" "farith")]
  )
  
! (define_insn "*maverick_subsf3"
!   [(set (match_operand:SF           0 "maverick_fp_register" "=v")
! 	(minus:SF (match_operand:SF 1 "maverick_fp_register"  "v")
! 		  (match_operand:SF 2 "maverick_fp_register"  "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfsubs%?\\t%V0, %V1, %V2"
!   [(set_attr "maverick_type" "farith")
!    (set_attr "maverick" "yes")]
! )
! 
! (define_expand "subdf3"
!   [(set (match_operand:DF           0 "s_register_operand" "")
! 	(minus:DF (match_operand:DF 1 "fpu_rhs_operand"     "")
! 		  (match_operand:DF 2 "fpu_rhs_operand"    "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!        if (!maverick_fp_register (operands[1], DFmode))
!          operands[1] = force_reg (DFmode, operands[1]);
!        if (!maverick_fp_register (operands[2], DFmode))
!          operands[2] = force_reg (DFmode, operands[2]);
!     }
! ")
! 
! (define_insn "*arm_subdf3"
    [(set (match_operand:DF           0 "s_register_operand" "=f,f")
  	(minus:DF (match_operand:DF 1 "fpu_rhs_operand"     "f,G")
  		  (match_operand:DF 2 "fpu_rhs_operand"    "fG,f")))]
***************
*** 1083,1088 ****
--- 1259,1274 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_subdf3"
+   [(set (match_operand:DF           0 "maverick_fp_register" "=v")
+ 	(minus:DF (match_operand:DF 1 "maverick_fp_register" "v")
+ 		  (match_operand:DF 2 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsubd%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*subdf_esfdf_df"
    [(set (match_operand:DF            0 "s_register_operand" "=f")
  	(minus:DF (float_extend:DF
***************
*** 1152,1157 ****
--- 1338,1353 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_mulsi3"
+   [(set (match_operand:SI          0 "maverick_fp_register" "=v")
+ 	(mult:SI (match_operand:SI 2 "maverick_fp_register"  "v")
+ 		 (match_operand:SI 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfmul32%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands 
  ; 1 and 2; are the same, because reload will make operand 0 match 
  ; operand 1 without realizing that this conflicts with operand 2.  We fix 
***************
*** 1199,1204 ****
--- 1395,1410 ----
     (set_attr "type" "mult")]
  )
  
+ (define_insn "muldi3"
+   [(set (match_operand:DI          0 "maverick_fp_register" "=v")
+ 	(mult:DI (match_operand:DI 2 "maverick_fp_register"  "v")
+ 		 (match_operand:DI 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfmul64%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "dmult")
+    (set_attr "maverick" "yes")]
+ )
+ 
  ;; Unnamed templates to match MLA instruction.
  
  (define_insn "*mulsi3addsi"
***************
*** 1245,1250 ****
--- 1451,1481 ----
     (set_attr "type" "mult")]
  )
  
+ (define_insn "*maverick_mulsi3addsi"
+   [(set (match_operand:SI            0 "maverick_fp_register" "=v")
+ 	(plus:SI
+ 	  (mult:SI (match_operand:SI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "maverick_fp_register"  "v"))
+ 	  (match_operand:SI          3 "maverick_fp_register"  "0")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfmac32%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
+ ;; Maverick SI multiply-subtract
+ (define_insn "*maverick_mulsi3subsi"
+   [(set (match_operand:SI            0 "maverick_fp_register" "=v")
+ 	(minus:SI
+ 	  (match_operand:SI          1 "maverick_fp_register"  "0")
+ 	  (mult:SI (match_operand:SI 2 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 3 "maverick_fp_register"  "v"))))]
+   "0 && TARGET_ARM && TARGET_MAVERICK"
+   "cfmsc32%?\\t%V0, %V2, %V3"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  ;; Unnamed template to match long long multiply-accumlate (smlal)
  
  (define_insn "*mulsidi3adddi"
***************
*** 1362,1368 ****
    "smlalbb%?\\t%Q0, %R0, %2, %3"
  [(set_attr "type" "mult")])
  
! (define_insn "mulsf3"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(mult:SF (match_operand:SF 1 "s_register_operand" "f")
  		 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
--- 1593,1610 ----
    "smlalbb%?\\t%Q0, %R0, %2, %3"
  [(set_attr "type" "mult")])
  
! (define_expand "mulsf3"
!   [(set (match_operand:SF          0 "s_register_operand" "")
! 	(mult:SF (match_operand:SF 1 "s_register_operand" "")
! 		 (match_operand:SF 2 "fpu_rhs_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK
!       && !maverick_fp_register (operands[2], SFmode))
!     operands[2] = force_reg (SFmode, operands[2]);
! ")
! 
! (define_insn "*arm_mulsf3"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(mult:SF (match_operand:SF 1 "s_register_operand" "f")
  		 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
***************
*** 1372,1378 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "muldf3"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(mult:DF (match_operand:DF 1 "s_register_operand" "f")
  		 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
--- 1614,1641 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "*maverick_mulsf3"
!   [(set (match_operand:SF          0 "maverick_fp_register" "=v")
! 	(mult:SF (match_operand:SF 1 "maverick_fp_register"  "v")
! 		 (match_operand:SF 2 "maverick_fp_register"  "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfmuls%?\\t%V0, %V1, %V2"
!   [(set_attr "maverick_type" "farith")
!    (set_attr "maverick" "yes")]
! )
! 
! (define_expand "muldf3"
!   [(set (match_operand:DF          0 "s_register_operand" "")
! 	(mult:DF (match_operand:DF 1 "s_register_operand" "")
! 		 (match_operand:DF 2 "fpu_rhs_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK
!       && !maverick_fp_register (operands[2], DFmode))
!     operands[2] = force_reg (DFmode, operands[2]);
! ")
! 
! (define_insn "*arm_muldf3"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(mult:DF (match_operand:DF 1 "s_register_operand" "f")
  		 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
***************
*** 1382,1387 ****
--- 1645,1660 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_muldf3"
+   [(set (match_operand:DF          0 "maverick_fp_register" "=v")
+ 	(mult:DF (match_operand:DF 1 "maverick_fp_register"  "v")
+ 		 (match_operand:DF 2 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfmuld%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "dmult")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*muldf_esfdf_df"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(mult:DF (float_extend:DF
***************
*** 2590,2595 ****
--- 2863,2935 ----
    [(set_attr "length" "2")]
  )
  
+ (define_expand "ashldi3"
+   [(set (match_operand:DI            0 "s_register_operand" "")
+ 	(ashift:DI (match_operand:DI 1 "general_operand" "")
+ 		   (match_operand:SI 2 "general_operand" "")))]
+   "TARGET_ARM && (0 || TARGET_MAVERICK)"
+   "
+   if (! s_register_operand (operands[1], DImode))
+     operands[1] = copy_to_mode_reg (DImode, operands[1]);
+   if (! s_register_operand (operands[2], SImode))
+     operands[2] = copy_to_mode_reg (SImode, operands[2]);
+   "
+ )
+ 
+ (define_insn "maverick_ashl_const"
+   [(set (match_operand:SI            0 "maverick_fp_register" "=v")
+ 	(ashift:SI (match_operand:SI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "maverick_shift_const"  "")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsh32%?\\t%V0, %V1, #%s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "maverick_ashiftrt_const"
+   [(set (match_operand:SI	       0 "maverick_fp_register" "=v")
+ 	(ashiftrt:SI (match_operand:SI 1 "maverick_fp_register"  "v")
+ 		     (match_operand:SI 2 "maverick_shift_const"  "")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsh32%?\\t%V0, %V1, #-%s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "maverick_ashlsi3"
+   [(set (match_operand:SI            0 "maverick_fp_register" "=v")
+ 	(ashift:SI (match_operand:SI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "register_operand"    "r")))]
+   "TARGET_ARM && TARGET_MAVERICK "
+   "cfrshl32%?\\t%V1, %V0, %s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "ashldi3_maverick"
+   [(set (match_operand:DI            0 "maverick_fp_register" "=v")
+ 	(ashift:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "register_operand"    "r")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfrshl64%?\\t%V1, %V0, %s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "maverick_ashldi_const"
+   [(set (match_operand:DI            0 "maverick_fp_register" "=v")
+ 	(ashift:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "maverick_shift_const"  "")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsh64%?\\t%V0, %V1, #%s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "maverick_ashiftrtdi_const"
+   [(set (match_operand:DI            0 "maverick_fp_register" "=v")
+ 	(ashiftrt:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		     (match_operand:SI 2 "maverick_shift_const"  "")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsh64%?\\t%V0, %V1, #-%s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*arm_shiftsi3"
    [(set (match_operand:SI   0 "s_register_operand" "=r")
  	(match_operator:SI  3 "shift_operator"
***************
*** 2704,2709 ****
--- 3044,3057 ----
  \f
  ;; Unary arithmetic insns
  
+ (define_insn "*maverick_absdi2"
+   [(set (match_operand:DI         0 "maverick_fp_register" "=v")
+ 	(abs:DI (match_operand:DI 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfabs64%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_expand "negdi2"
   [(parallel
     [(set (match_operand:DI          0 "s_register_operand" "")
***************
*** 2719,2724 ****
--- 3067,3081 ----
    "
  )
  
+ (define_insn "*maverick_negdi2"
+   [(set (match_operand:DI         0 "maverick_fp_register" "=v")
+ 	(neg:DI (match_operand:DI 1 "maverick_fp_register"  "v")))
+    (clobber (reg:CC 24))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfneg64%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
  ;; The second alternative is to allow the common case of a *full* overlap.
  (define_insn "*arm_negdi2"
***************
*** 2755,2760 ****
--- 3112,3125 ----
    [(set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_negsi2"
+   [(set (match_operand:SI         0 "maverick_fp_register" "=v")
+ 	(neg:SI (match_operand:SI 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK "
+   "cfneg32%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*thumb_negsi2"
    [(set (match_operand:SI         0 "register_operand" "=l")
  	(neg:SI (match_operand:SI 1 "register_operand" "l")))]
***************
*** 2763,2769 ****
    [(set_attr "length" "2")]
  )
  
! (define_insn "negsf2"
    [(set (match_operand:SF         0 "s_register_operand" "=f")
  	(neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3128,3141 ----
    [(set_attr "length" "2")]
  )
  
! (define_expand "negsf2"
!   [(set (match_operand:SF         0 "s_register_operand" "")
! 	(neg:SF (match_operand:SF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   ""
! )
! 
! (define_insn "*arm_negsf2"
    [(set (match_operand:SF         0 "s_register_operand" "=f")
  	(neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
***************
*** 2772,2778 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "negdf2"
    [(set (match_operand:DF         0 "s_register_operand" "=f")
  	(neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3144,3164 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "*maverick_negsf2"
!   [(set (match_operand:SF         0 "maverick_fp_register" "=v")
! 	(neg:SF (match_operand:SF 1 "maverick_fp_register"  "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfnegs%?\\t%V0, %V1"
!   [(set_attr "maverick" "yes")]
! )
! 
! (define_expand "negdf2"
!   [(set (match_operand:DF         0 "s_register_operand" "")
! 	(neg:DF (match_operand:DF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "")
! 
! (define_insn "*arm_negdf2"
    [(set (match_operand:DF         0 "s_register_operand" "=f")
  	(neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
***************
*** 2781,2786 ****
--- 3167,3180 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_negdf2"
+   [(set (match_operand:DF         0 "maverick_fp_register" "=v")
+ 	(neg:DF (match_operand:DF 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfnegd%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*negdf_esfdf"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(neg:DF (float_extend:DF
***************
*** 2805,2811 ****
  ;; it does, but tell the final scan operator the truth.  Similarly for
  ;; (neg (abs...))
  
! (define_insn "abssi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r,&r")
  	(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
     (clobber (reg:CC CC_REGNUM))]
--- 3199,3213 ----
  ;; it does, but tell the final scan operator the truth.  Similarly for
  ;; (neg (abs...))
  
! (define_expand "abssi2"
!   [(parallel
!     [(set (match_operand:SI         0 "s_register_operand" "")
! 	  (abs:SI (match_operand:SI 1 "s_register_operand" "")))
!      (clobber (reg:CC 24))])]
!   "TARGET_ARM"
!   "")
! 
! (define_insn "*arm_abssi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r,&r")
  	(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
     (clobber (reg:CC CC_REGNUM))]
***************
*** 2819,2824 ****
--- 3221,3235 ----
     (set_attr "length" "8")]
  )
  
+ (define_insn "*maverick_abssi2"
+   [(set (match_operand:SI         0 "maverick_fp_register" "=v")
+         (abs:SI (match_operand:SI 1 "maverick_fp_register"  "v")))
+    (clobber (reg:CC 24))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfabs32%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*neg_abssi2"
    [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
  	(neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
***************
*** 2833,2839 ****
     (set_attr "length" "8")]
  )
  
! (define_insn "abssf2"
    [(set (match_operand:SF          0 "s_register_operand" "=f")
  	 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3244,3256 ----
     (set_attr "length" "8")]
  )
  
! (define_expand "abssf2"
!   [(set (match_operand:SF         0 "s_register_operand" "")
! 	(abs:SF (match_operand:SF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "")
! 
! (define_insn "*arm_abssf2"
    [(set (match_operand:SF          0 "s_register_operand" "=f")
  	 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
***************
*** 2842,2848 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "absdf2"
    [(set (match_operand:DF         0 "s_register_operand" "=f")
  	(abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3259,3279 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "*maverick_abssf2"
!   [(set (match_operand:SF         0 "maverick_fp_register" "=v")
!         (abs:SF (match_operand:SF 1 "maverick_fp_register"  "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfabss%?\\t%V0, %V1"
!   [(set_attr "maverick" "yes")]
! )
! 
! (define_expand "absdf2"
!   [(set (match_operand:DF         0 "s_register_operand" "")
! 	(abs:DF (match_operand:DF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "")
! 
! (define_insn "*arm_absdf2"
    [(set (match_operand:DF         0 "s_register_operand" "=f")
  	(abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
***************
*** 2851,2856 ****
--- 3282,3295 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_absdf2"
+   [(set (match_operand:DF         0 "maverick_fp_register" "=v")
+         (abs:DF (match_operand:DF 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfabsd%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*absdf_esfdf"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(abs:DF (float_extend:DF
***************
*** 3040,3046 ****
  \f
  ;; Fixed <--> Floating conversion insns
  
! (define_insn "floatsisf2"
    [(set (match_operand:SF           0 "s_register_operand" "=f")
  	(float:SF (match_operand:SI 1 "s_register_operand" "r")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3479,3497 ----
  \f
  ;; Fixed <--> Floating conversion insns
  
! (define_expand "floatsisf2"
!   [(set (match_operand:SF           0 "s_register_operand" "")
! 	(float:SF (match_operand:SI 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       emit_insn (gen_maverick_floatsisf2 (operands[0], operands[1]));
!       DONE;
!     }
! ")
! 
! (define_insn "*arm_floatsisf2"
    [(set (match_operand:SF           0 "s_register_operand" "=f")
  	(float:SF (match_operand:SI 1 "s_register_operand" "r")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
***************
*** 3049,3055 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "floatsidf2"
    [(set (match_operand:DF           0 "s_register_operand" "=f")
  	(float:DF (match_operand:SI 1 "s_register_operand" "r")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3500,3553 ----
     (set_attr "predicable" "yes")]
  )
  
! ;; Convert Maverick-SI to Maverick-SF
! (define_insn "maverick_floatsisf2"
!   [(set (match_operand:SF           0 "maverick_fp_register" "=v")
!  	(float:SF (match_operand:SI 1 "s_register_operand"  "r")))
!    (clobber (match_scratch:DF 2 "=v"))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfmv64lr%?\\t%Z2, %1\;cfcvt32s%?\\t%V0, %Y2"
!   [(set_attr "length" "8")
!    (set_attr "maverick" "move")]
! )
! 
! (define_expand "floatsidf2"
!   [(set (match_operand:DF           0 "s_register_operand" "")
! 	(float:DF (match_operand:SI 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       emit_insn (gen_maverick_floatsidf2 (operands[0], operands[1]));
!       DONE;
!     }
! ")
! 
! (define_insn "maverick_floatsidf2"
!   [(set (match_operand:DF           0 "maverick_fp_register" "=v")
! 	(float:DF (match_operand:SI 1 "s_register_operand" "r")))
!    (clobber (match_scratch:DF 2 "=v"))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfmv64lr%?\\t%Z2, %1\;cfcvt32d%?\\t%V0, %Y2"
!   [(set_attr "length" "8")
!    (set_attr "maverick" "move")]
! )
! 
! (define_insn "floatdisf2"
!   [(set (match_operand:SF           0 "maverick_fp_register" "=v")
! 	(float:SF (match_operand:DI 1 "maverick_fp_register" "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfcvt64s%?\\t%V0, %V1"
!   [(set_attr "maverick" "yes")])
! 
! (define_insn "floatdidf2"
!   [(set (match_operand:DF 0 "maverick_fp_register" "=v")
! 	(float:DF (match_operand:DI 1 "maverick_fp_register" "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfcvt64d%?\\t%V0, %V1"
!   [(set_attr "maverick" "yes")])
! 
! (define_insn "*arm_floatsidf2"
    [(set (match_operand:DF           0 "s_register_operand" "=f")
  	(float:DF (match_operand:SI 1 "s_register_operand" "r")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
***************
*** 3067,3073 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "fix_truncsfsi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r")
  	(fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3565,3597 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_expand "fix_truncsfsi2"
!   [(set (match_operand:SI         0 "s_register_operand" "")
! 	(fix:SI (match_operand:SF 1 "s_register_operand"  "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       if (!maverick_fp_register (operands[0], SImode))
!         operands[0] = force_reg (SImode, operands[0]);
!       if (!maverick_fp_register (operands[1], SFmode))
!         operands[1] = force_reg (SFmode, operands[0]);
!       emit_insn (gen_maverick_truncsfsi2 (operands[0], operands[1]));
!       DONE;
!     }
! ")
! 
! (define_insn "maverick_truncsfsi2"
!   [(set (match_operand:SI         0 "s_register_operand" "=r")
! 	(fix:SI (match_operand:SF 1 "maverick_fp_register"  "v")))
!    (clobber (match_scratch:DF     2                      "=v"))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cftruncs32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
!   [(set_attr "length" "8")
!    (set_attr "maverick" "yes")]
! )
! 
! (define_insn "*arm_fix_truncsfsi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r")
  	(fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
***************
*** 3076,3082 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "fix_truncdfsi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r")
  	(fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3600,3629 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_expand "fix_truncdfsi2"
!   [(set (match_operand:SI         0 "s_register_operand" "")
! 	(fix:SI (match_operand:DF 1 "s_register_operand"  "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       if (!maverick_fp_register (operands[1], DFmode))
!         operands[1] = force_reg (DFmode, operands[0]);
!       emit_insn (gen_maverick_truncdfsi2 (operands[0], operands[1]));
!       DONE;
!     }
! ")
! 
! (define_insn "maverick_truncdfsi2"
!   [(set (match_operand:SI         0 "s_register_operand" "=r")
! 	(fix:SI (match_operand:DF 1 "maverick_fp_register"  "v")))
!    (clobber (match_scratch:DF     2                      "=v"))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cftruncd32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
!   [(set_attr "length" "8")]
! )
! 
! (define_insn "*arm_fix_truncdfsi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r")
  	(fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
***************
*** 3096,3102 ****
  
  ;; Truncation insns
  
! (define_insn "truncdfsf2"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(float_truncate:SF
  	 (match_operand:DF 1 "s_register_operand" "f")))]
--- 3643,3657 ----
  
  ;; Truncation insns
  
! (define_expand "truncdfsf2"
!   [(set (match_operand:SF  0 "s_register_operand" "")
! 	(float_truncate:SF
!  	 (match_operand:DF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   ""
! )
! 
! (define_insn "*arm_truncdfsf2"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(float_truncate:SF
  	 (match_operand:DF 1 "s_register_operand" "f")))]
***************
*** 3106,3111 ****
--- 3661,3675 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_truncdfsf2"
+   [(set (match_operand:SF  0 "maverick_fp_register" "=v")
+         (float_truncate:SF
+          (match_operand:DF 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcvtds%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "truncxfsf2"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(float_truncate:SF
***************
*** 3848,3854 ****
     (set_attr "pool_range" "32,32")]
  )
  
! (define_insn "extendsfdf2"
    [(set (match_operand:DF                  0 "s_register_operand" "=f")
  	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 4412,4425 ----
     (set_attr "pool_range" "32,32")]
  )
  
! (define_expand "extendsfdf2"
!   [(set (match_operand:DF                  0 "s_register_operand" "")
! 	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   ""
! )
! 
! (define_insn "*arm_extendsfdf2"
    [(set (match_operand:DF                  0 "s_register_operand" "=f")
  	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
***************
*** 3857,3862 ****
--- 4428,4441 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_extendsfdf2"
+   [(set (match_operand:DF                  0 "maverick_fp_register" "=v")
+         (float_extend:DF (match_operand:SF 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcvtsd%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "extendsfxf2"
    [(set (match_operand:XF 0 "s_register_operand" "=f")
  	(float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
***************
*** 3953,3962 ****
    "
  )
  
  (define_insn "*arm_movdi"
    [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
  	(match_operand:DI 1 "di_operand"              "rIK,mi,r"))]
!   "TARGET_ARM"
    "*
    return (output_move_double (operands));
    "
--- 4532,4573 ----
    "
  )
  
+ (define_insn "*maverick_arm_movdi"
+   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,o<>,v,r,v,m,v")
+ 	(match_operand:DI 1 "di_operand"              "rIK,mi,r,r,v,m,v,v"))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "*
+   {
+   switch (which_alternative)
+     {
+     case 0:
+     case 1:
+     case 2:
+       return (output_move_double (operands));
+ 
+     case 3: return \"cfmv64lr%?\\t%V0, %Q1\;cfmv64hr%?\\t%V0, %R1\";
+     case 4: return \"cfmvr64l%?\\t%Q0, %V1\;cfmvr64h%?\\t%R0, %V1\";
+ 
+     case 5: return \"cfldr64%?\\t%V0, %1\";
+     case 6: return \"cfstr64%?\\t%V1, %0\";
+ 
+     /* Shifting by 0 will just copy %1 into %0.  */
+     case 7: return \"cfsh64%?\\t%V0, %V1, #0\";
+ 
+     default: abort ();
+     }
+   }"
+   [(set_attr "length" "8,8,8,8,8,4,4,4")
+    (set_attr "type" "*,load,store2,*,*,load,store2,*")
+    (set_attr "pool_range" "*,1020,*,*,*,*,*,*")
+    (set_attr "neg_pool_range" "*,1012,*,*,*,*,*,*")
+    (set_attr "maverick" "no,no,no,move,yes,double,double,yes")]
+ )
+ 
  (define_insn "*arm_movdi"
    [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
  	(match_operand:DI 1 "di_operand"              "rIK,mi,r"))]
!   "TARGET_ARM && !TARGET_MAVERICK"
    "*
    return (output_move_double (operands));
    "
***************
*** 3974,3979 ****
--- 4585,4591 ----
    [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
  	(match_operand:DI 1 "general_operand"      "l, I,J,>,l,mi,l,*r"))]
    "TARGET_THUMB
+    && !TARGET_MAVERICK
     && (   register_operand (operands[0], DImode)
         || register_operand (operands[1], DImode))"
    "*
***************
*** 4051,4056 ****
--- 4663,4693 ----
    "
  )
  
+ ;; Maverick SI values have been outlawed.  Look in arm.h for the comment
+ ;; on HARD_REGNO_MODE_OK.
+ 
+ (define_insn "*maverick_arm_movsi_insn"
+   [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,*v,r,*v,T,*v")
+         (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,*v,T,*v,*v"))]
+   "TARGET_ARM && TARGET_MAVERICK 
+    && (register_operand (operands[0], SImode)
+        || register_operand (operands[1], SImode))"
+   "@
+    mov%?\\t%0, %1
+    mvn%?\\t%0, #%B1
+    ldr%?\\t%0, %1
+    str%?\\t%1, %0
+    cfmv64lr%?\\t%Z0, %1
+    cfmvr64l%?\\t%0, %Z1
+    cfldr32%?\\t%V0, %1
+    cfstr32%?\\t%V1, %0
+    cfsh32%?\\t%V0, %V1, #0"
+   [(set_attr "type" "*,*,load,store1,*,*,load,store1,*")
+    (set_attr "pool_range" "*,*,4096,*,*,*,1024,*,*")
+    (set_attr "neg_pool_range" "*,*,4084,*,*,*,1012,*,*")
+    (set_attr "maverick" "no,no,no,no,move,yes,yes,yes,yes")]
+ )
+ 
  (define_insn "*arm_movsi_insn"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
  	(match_operand:SI 1 "general_operand"      "rI,K,mi,r"))]
***************
*** 4417,4430 ****
  	      emit_insn (gen_movsi (reg, GEN_INT (val)));
  	      operands[1] = gen_lowpart (HImode, reg);
  	    }
! 	  else if (arm_arch4 && !no_new_pseudos && optimize > 0
! 		   && GET_CODE (operands[1]) == MEM)
! 	    {
! 	      rtx reg = gen_reg_rtx (SImode);
  
! 	      emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
! 	      operands[1] = gen_lowpart (HImode, reg);
! 	    }
            else if (!arm_arch4)
  	    {
  	     /* Note: We do not have to worry about TARGET_MMU_TRAPS
--- 5054,5067 ----
  	      emit_insn (gen_movsi (reg, GEN_INT (val)));
  	      operands[1] = gen_lowpart (HImode, reg);
  	    }
!         else if (arm_arch4 && !no_new_pseudos && optimize > 0
!                  && GET_CODE (operands[1]) == MEM)
!           {
!             rtx reg = gen_reg_rtx (SImode);
  
!             emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
!             operands[1] = gen_lowpart (HImode, reg);
!           }
            else if (!arm_arch4)
  	    {
  	     /* Note: We do not have to worry about TARGET_MMU_TRAPS
***************
*** 4974,4979 ****
--- 5611,5638 ----
     (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
  )
  
+ (define_insn "*maverick_movsf_hard_insn"
+   [(set (match_operand:SF 0 "nonimmediate_operand" "=v,v,v,r,m,r,r,m")
+         (match_operand:SF 1 "general_operand"       "v,m,r,v,v,r,mE,r"))]
+   "TARGET_ARM && TARGET_MAVERICK
+    && (GET_CODE (operands[0]) != MEM
+        || register_operand (operands[1], SFmode))"
+   "@
+    cfcpys%?\\t%V0, %V1
+    cfldrs%?\\t%V0, %1
+    cfmvsr%?\\t%V0, %1
+    cfmvrs%?\\t%0, %V1
+    cfstrs%?\\t%V1, %0
+    mov%?\\t%0, %1
+    ldr%?\\t%0, %1\\t%@ float
+    str%?\\t%1, %0\\t%@ float"
+   [(set_attr "length" "*,*,*,*,*,4,4,4")
+    (set_attr "type" "*,load,*,*,store1,*,load,store1")
+    (set_attr "pool_range" "*,*,*,*,*,*,4096,*")
+    (set_attr "neg_pool_range" "*,*,*,*,*,*,4084,*")
+    (set_attr "maverick" "yes,yes,move,yes,yes,no,no,no")]
+ )
+ 
  ;; Exactly the same as above, except that all `f' cases are deleted.
  ;; This is necessary to prevent reload from ever trying to use a `f' reg
  ;; when -msoft-float.
***************
*** 4982,4987 ****
--- 5641,5647 ----
    [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
  	(match_operand:SF 1 "general_operand"  "r,mE,r"))]
    "TARGET_ARM
+    && !TARGET_MAVERICK
     && TARGET_SOFT_FLOAT
     && (GET_CODE (operands[0]) != MEM
         || register_operand (operands[1], SFmode))"
***************
*** 5080,5085 ****
--- 5740,5773 ----
    }"
  )
  
+ (define_insn "*maverick_movdf_hard_insn"
+   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Q,r,m,r,v,v,v,r,m")
+ 	(match_operand:DF 1 "general_operand"       "Q,r,r,r,mF,v,m,r,v,v"))]
+   "TARGET_ARM
+    && TARGET_MAVERICK
+    && (GET_CODE (operands[0]) != MEM
+        || register_operand (operands[1], DFmode))"
+   "*
+   {
+   switch (which_alternative)
+     {
+     case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
+     case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
+     case 2: case 3: case 4: return output_move_double (operands);
+     case 5: return \"cfcpyd%?\\t%V0, %V1\";
+     case 6: return \"cfldrd%?\\t%V0, %1\";
+     case 7: return \"cfmvdlr\\t%V0, %Q1\;cfmvdhr%?\\t%V0, %R1\";
+     case 8: return \"cfmvrdl%?\\t%Q0, %V1\;cfmvrdh%?\\t%R0, %V1\";
+     case 9: return \"cfstrd%?\\t%V1, %0\";
+     default: abort ();
+     }
+   }"
+   [(set_attr "type" "load,store2,*,store2,load,*,load,*,*,store2")
+    (set_attr "length" "4,4,8,8,8,4,4,8,8,4")
+    (set_attr "pool_range" "*,*,*,*,252,*,*,*,*,*")
+    (set_attr "neg_pool_range" "*,*,*,*,244,*,*,*,*,*")
+    (set_attr "maverick" "no,no,no,no,no,yes,double,move,yes,double")]
+ )
  (define_insn "*movdf_hard_insn"
    [(set (match_operand:DF 0 "nonimmediate_operand"
  						"=r,Q,r,m,r, f, f,f, m,!f,!r")
***************
*** 5122,5127 ****
--- 5810,5816 ----
    [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
  	(match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
    "TARGET_ARM && TARGET_SOFT_FLOAT
+    && !TARGET_MAVERICK
    "
    "* return output_move_double (operands);"
    [(set_attr "length" "8,8,8")
***************
*** 5631,5638 ****
  (define_expand "cmpsf"
    [(match_operand:SF 0 "s_register_operand" "")
     (match_operand:SF 1 "fpu_rhs_operand" "")]
!   "TARGET_ARM && TARGET_HARD_FLOAT"
    "
    arm_compare_op0 = operands[0];
    arm_compare_op1 = operands[1];
    DONE;
--- 6320,6330 ----
  (define_expand "cmpsf"
    [(match_operand:SF 0 "s_register_operand" "")
     (match_operand:SF 1 "fpu_rhs_operand" "")]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
    "
+   if (TARGET_MAVERICK && !maverick_fp_register (operands[1], SFmode))
+     operands[1] = force_reg (SFmode, operands[1]);
+ 
    arm_compare_op0 = operands[0];
    arm_compare_op1 = operands[1];
    DONE;
***************
*** 5642,5649 ****
  (define_expand "cmpdf"
    [(match_operand:DF 0 "s_register_operand" "")
     (match_operand:DF 1 "fpu_rhs_operand" "")]
!   "TARGET_ARM && TARGET_HARD_FLOAT"
    "
    arm_compare_op0 = operands[0];
    arm_compare_op1 = operands[1];
    DONE;
--- 6334,6344 ----
  (define_expand "cmpdf"
    [(match_operand:DF 0 "s_register_operand" "")
     (match_operand:DF 1 "fpu_rhs_operand" "")]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
    "
+   if (TARGET_MAVERICK && !maverick_fp_register (operands[1], DFmode))
+     operands[1] = force_reg (DFmode, operands[1]);
+ 
    arm_compare_op0 = operands[0];
    arm_compare_op1 = operands[1];
    DONE;
***************
*** 5771,5776 ****
--- 6466,6530 ----
     (set_attr "type" "f_2_r")]
  )
  
+ ;; There is no CCFPE or CCFP modes in the code below so we can have
+ ;; one pattern to match either one.  Besides, we're pretty sure we
+ ;; have either CCFPE or CCFP because we made the patterns
+ ;; (arm_gen_compare_reg).
+ 
+ ;; Maverick SF compare instruction
+ (define_insn "*maverick_cmpsf"
+   [(set (reg:CCFP 24)
+ 	(compare:CCFP (match_operand:SF 0 "maverick_fp_register" "v")
+ 		      (match_operand:SF 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcmps%?\\tr15, %V0, %V1"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "compare")]
+ )
+ 
+ ;; Maverick DF compare instruction
+ (define_insn "*maverick_cmpdf"
+   [(set (reg:CCFP 24)
+ 	(compare:CCFP (match_operand:DF 0 "maverick_fp_register" "v")
+ 		      (match_operand:DF 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcmpd%?\\tr15, %V0, %V1"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "compare")]
+ )
+ 
+ ;; Maverick DI compare instruction
+ (define_expand "cmpdi"
+   [(match_operand:DI 0 "maverick_fp_register" "")
+    (match_operand:DI 1 "maverick_fp_register" "")]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "{
+      arm_compare_op0 = operands[0];
+      arm_compare_op1 = operands[1];
+      DONE;
+    }")
+ 
+ (define_insn "*maverick_cmpdi"
+   [(set (reg:CC 24)
+ 	(compare:CC (match_operand:DI 0 "maverick_fp_register" "v")
+ 		    (match_operand:DI 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcmp64%?\\tr15, %V0, %V1"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "compare")]
+ )
+ 
+ ;; Maverick SI compare instruction
+ (define_insn "*maverick_cmpsi_1"
+   [(set (reg:CC 24)
+ 	(compare:CC (match_operand:SI 0 "maverick_fp_register" "v")
+ 		    (match_operand:SI 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcmp32%?\\tr15, %V0, %V1"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "compare")]
+ )
+ 
  (define_insn "*cmpsf_trap"
    [(set (reg:CCFPE CC_REGNUM)
  	(compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
***************
*** 6599,6606 ****
  )
  
  (define_insn "*call_value_reg"
!   [(set (match_operand 0 "" "=r,f")
!         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r,r"))
  	      (match_operand 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
--- 7353,7360 ----
  )
  
  (define_insn "*call_value_reg"
!   [(set (match_operand 0 "" "=r,f,v")
!         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r,r,r"))
  	      (match_operand 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
***************
*** 6613,6620 ****
  )
  
  (define_insn "*call_value_mem"
!   [(set (match_operand 0 "" "=r,f")
! 	(call (mem:SI (match_operand:SI 1 "memory_operand" "m,m"))
  	      (match_operand 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
--- 7367,7374 ----
  )
  
  (define_insn "*call_value_mem"
!   [(set (match_operand 0 "" "=r,f,v")
! 	(call (mem:SI (match_operand:SI 1 "memory_operand" "m,m,m"))
  	      (match_operand 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
***************
*** 6645,6652 ****
  )
  
  (define_insn "*call_value_symbol"
!   [(set (match_operand 0 "s_register_operand" "=r,f")
! 	(call (mem:SI (match_operand:SI 1 "" "X,X"))
  	(match_operand:SI 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
--- 7399,7406 ----
  )
  
  (define_insn "*call_value_symbol"
!   [(set (match_operand 0 "s_register_operand" "=r,f,v")
! 	(call (mem:SI (match_operand:SI 1 "" "X,X,X"))
  	(match_operand:SI 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
***************
*** 6728,6735 ****
  )
  
  (define_insn "*sibcall_value_insn"
!  [(set (match_operand 0 "s_register_operand" "=r,f")
!        (call (mem:SI (match_operand:SI 1 "" "X,X"))
  	     (match_operand 2 "" "")))
    (return)
    (use (match_operand 3 "" ""))]
--- 7482,7489 ----
  )
  
  (define_insn "*sibcall_value_insn"
!  [(set (match_operand 0 "s_register_operand" "=r,f,v")
!        (call (mem:SI (match_operand:SI 1 "" "X,X,X"))
  	     (match_operand 2 "" "")))
    (return)
    (use (match_operand 3 "" ""))]
***************
*** 8499,8504 ****
--- 9253,9261 ----
     (set (reg:CC CC_REGNUM)
  	(compare:CC (match_dup 1) (const_int 0)))]
    "TARGET_ARM
+    && (!TARGET_MAVERICK
+        || (!maverick_fp_register (operands[0], SImode)
+            && !maverick_fp_register (operands[1], SImode)))
    "
    [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
  	      (set (match_dup 0) (match_dup 1))])]
Index: config/arm/arm-protos.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/arm-protos.h,v
retrieving revision 1.29
diff -c -p -r1.29 arm-protos.h
*** config/arm/arm-protos.h	3 Mar 2002 04:23:02 -0000	1.29
--- config/arm/arm-protos.h	14 Aug 2002 15:36:32 -0000
*************** extern void arm_pr_no_long_calls	PARAMS 
*** 204,207 ****
--- 204,215 ----
  extern void arm_pr_long_calls_off	PARAMS ((cpp_reader *));
  #endif
  
+ #if defined (RTX_CODE)
+ extern int maverick_fp_register		PARAMS ((rtx, enum machine_mode));
+ extern int maverick_general_operand	PARAMS ((rtx, enum machine_mode));
+ extern int maverick_register_operand	PARAMS ((rtx, enum machine_mode));
+ extern int maverick_shift_const		PARAMS ((rtx, enum machine_mode));
+ extern int maverick_memory_offset		PARAMS ((rtx));
+ #endif
+ 
  #endif /* ! GCC_ARM_PROTOS_H */
Index: config/arm/aout.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/aout.h,v
retrieving revision 1.26
diff -c -p -r1.26 aout.h
*** config/arm/aout.h	31 Jul 2002 02:13:28 -0000	1.26
--- config/arm/aout.h	14 Aug 2002 15:36:33 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 73,79 ****
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",  \
    "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc",  \
    "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",  \
!   "cc", "sfp", "afp"		   		   \
  }
  #endif
  
--- 73,82 ----
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",  \
    "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc",  \
    "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",  \
!   "cc", "sfp", "afp",		   		   \
!   "mv0", "mv1", "mv2", "mv3", "mv4", "mv5", "mv6", \
!   "mv7", "mv8", "mv9", "mv10", "mv11", "mv12",     \
!   "mv13", "mv14", "mv15"			   \
  }
  #endif
  
*************** Boston, MA 02111-1307, USA.  */
*** 98,104 ****
    {"r12", 12},	/* ip */			\
    {"r13", 13},	/* sp */			\
    {"r14", 14},	/* lr */			\
!   {"r15", 15}	/* pc */			\
  }
  #endif
  
--- 101,171 ----
    {"r12", 12},	/* ip */			\
    {"r13", 13},	/* sp */			\
    {"r14", 14},	/* lr */			\
!   {"r15", 15},	/* pc */			\
!   {"mvf0", 27},					\
!   {"mvf1", 28},					\
!   {"mvf2", 29},					\
!   {"mvf3", 30},					\
!   {"mvf4", 31},					\
!   {"mvf5", 32},					\
!   {"mvf6", 33},					\
!   {"mvf7", 34},					\
!   {"mvf8", 35},					\
!   {"mvf9", 36},					\
!   {"mvf10", 37},				\
!   {"mvf11", 38},				\
!   {"mvf12", 39},				\
!   {"mvf13", 40},				\
!   {"mvf14", 41},				\
!   {"mvf15", 42},				\
!   {"mvd0", 27},					\
!   {"mvd1", 28},					\
!   {"mvd2", 29},					\
!   {"mvd3", 30},					\
!   {"mvd4", 31},					\
!   {"mvd5", 32},					\
!   {"mvd6", 33},					\
!   {"mvd7", 34},					\
!   {"mvd8", 35},					\
!   {"mvd9", 36},					\
!   {"mvd10", 37},				\
!   {"mvd11", 38},				\
!   {"mvd12", 39},				\
!   {"mvd13", 40},				\
!   {"mvd14", 41},				\
!   {"mvd15", 42},				\
!   {"mvfx0", 27},				\
!   {"mvfx1", 28},				\
!   {"mvfx2", 29},				\
!   {"mvfx3", 30},				\
!   {"mvfx4", 31},				\
!   {"mvfx5", 32},				\
!   {"mvfx6", 33},				\
!   {"mvfx7", 34},				\
!   {"mvfx8", 35},				\
!   {"mvfx9", 36},				\
!   {"mvfx10", 37},				\
!   {"mvfx11", 38},				\
!   {"mvfx12", 39},				\
!   {"mvfx13", 40},				\
!   {"mvfx14", 41},				\
!   {"mvfx15", 42},				\
!   {"mvdx0", 27},				\
!   {"mvdx1", 28},				\
!   {"mvdx2", 29},				\
!   {"mvdx3", 30},				\
!   {"mvdx4", 31},				\
!   {"mvdx5", 32},				\
!   {"mvdx6", 33},				\
!   {"mvdx7", 34},				\
!   {"mvdx8", 35},				\
!   {"mvdx9", 36},				\
!   {"mvdx10", 37},				\
!   {"mvdx11", 38},				\
!   {"mvdx12", 39},				\
!   {"mvdx13", 40},				\
!   {"mvdx14", 41},				\
!   {"mvdx15", 42}				\
  }
  #endif
  
Index: config/arm/t-maverick-elf
===================================================================
RCS file: config/arm/t-maverick-elf
diff -N config/arm/t-maverick-elf
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- config/arm/t-maverick-elf	14 Aug 2002 15:36:33 -0000
***************
*** 0 ****
--- 1,41 ----
+ CROSS_LIBGCC1 = libgcc1-asm.a
+ LIB1ASMSRC = arm/lib1funcs.asm
+ LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func _call_via_rX _interwork_call_via_rX
+ 
+ # We want fine grained libraries, so use the new code to build the
+ # floating point emulation libraries.
+ FPBIT = fp-bit.c
+ DPBIT = dp-bit.c
+ 
+ fp-bit.c: $(srcdir)/config/fp-bit.c
+ 	echo '#define FLOAT' > fp-bit.c
+ 	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+ 
+ dp-bit.c: $(srcdir)/config/fp-bit.c
+ 	cat $(srcdir)/config/fp-bit.c > dp-bit.c
+ 
+ MULTILIB_OPTIONS     = mlittle-endian/mbig-endian
+ MULTILIB_DIRNAMES    = le be
+ MULTILIB_EXCEPTIONS  = 
+ MULTILIB_MATCHES     = mbig-endian=mbe mlittle-endian=mle
+ EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
+ 
+ # If EXTRA_MULTILIB_PARTS is not defined above then define EXTRA_PARTS here
+ # EXTRA_PARTS = crtbegin.o crtend.o crti.o crtn.o
+ # 
+ LIBGCC = stmp-multilib
+ INSTALL_LIBGCC = install-multilib
+ 
+ # Currently there is a bug somewhere in GCC's alias analysis
+ # or scheduling code that is breaking _fpmul_parts in libgcc1.c.
+ # Disabling function inlining is a workaround for this problem.
+ TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc -fno-inline
+ 
+ # Assemble startup files.
+ $(T)crti.o: $(srcdir)/config/arm/crti.asm $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+ 	-c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/arm/crti.asm
+ 
+ $(T)crtn.o: $(srcdir)/config/arm/crtn.asm $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+ 	-c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/arm/crtn.asm
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/invoke.texi,v
retrieving revision 1.170
diff -c -p -r1.170 invoke.texi
*** doc/invoke.texi	11 Aug 2002 09:47:47 -0000	1.170
--- doc/invoke.texi	14 Aug 2002 15:37:11 -0000
*************** in the following sections.
*** 395,400 ****
--- 395,401 ----
  -msingle-pic-base  -mno-single-pic-base @gol
  -mpic-register=@var{reg} @gol
  -mnop-fun-dllimport @gol
+ -mmaverick-fix-invalid-insns -mno-maverick-fix-invalid-insns @gol
  -mpoke-function-name @gol
  -mthumb  -marm @gol
  -mtpcs-frame  -mtpcs-leaf-frame @gol
*************** Allows calls via function pointers (incl
*** 5994,5999 ****
--- 5995,6008 ----
  execute correctly regardless of whether the target code has been
  compiled for interworking or not.  There is a small overhead in the cost
  of executing a function pointer if this option is enabled.
+ 
+ @item -mmaverick-fix-invalid-insns
+ @opindex mmaverick-fix-invalid-insns
+ Insert nops to fix invalid Maverick instruction combinations.
+ 
+ @item -mno-maverick-fix-invalid-insns
+ @opindex mno-maverick-fix-invalid-insns
+ Do not insert nops to fix invalid Maverick instruction combinations.
  
  @end table
  
Index: config.gcc
===================================================================
RCS file: /cvs/uberbaum/gcc/config.gcc,v
retrieving revision 1.238
diff -c -p -r1.238 config.gcc
*** config.gcc	12 Aug 2002 03:40:15 -0000	1.238
--- config.gcc	14 Aug 2002 15:37:17 -0000
*************** alpha*-*-*)
*** 2838,2843 ****
--- 2838,2847 ----
  		fi
  	fi
  	;;
+ armmaverick-*-elf)
+ 	tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/ecos-elf.h"
+ 	tmake_file=arm/t-maverick-elf
+ 	;;
  arm*-*-*)
  	case "x$with_cpu" in
  		x)
*************** arm*-*-*)
*** 2854,2860 ****
  		| xstrongarm | xstrongarm110 | xstrongarm1100)
  			target_cpu_default2="TARGET_CPU_$with_cpu"
  			;;
! 
  		xyes | xno)
  			echo "--with-cpu must be passed a value" 1>&2
  			exit 1
--- 2858,2866 ----
  		| xstrongarm | xstrongarm110 | xstrongarm1100)
  			target_cpu_default2="TARGET_CPU_$with_cpu"
  			;;
! 		xarmmaverick)
! 			target_cpu_default2="TARGET_CPU_$with_cpu"
! 			;;
  		xyes | xno)
  			echo "--with-cpu must be passed a value" 1>&2
  			exit 1
*************** arm*-*-*)
*** 2866,2871 ****
--- 2872,2882 ----
  				echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2
  				exit 1
  			fi
+ 			;;
+ 	esac
+ 	case $machine in
+ 		armmaverick-*-*)
+ 			target_cpu_default2="TARGET_CPU_armmaverick"
  			;;
  	esac
  	;;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-14  8:50 [patch] new portlet: cirrus-maverick Aldy Hernandez
@ 2002-08-14  9:22 ` Aldy Hernandez
  2002-08-14  9:43 ` Phil Edwards
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Aldy Hernandez @ 2002-08-14  9:22 UTC (permalink / raw)
  To: rearnsha; +Cc: nickc, gcc-patches, rsandifo, law

Oh yeah, I guess I should give a little background.

The Cirrus/Maverick is an ARM9 with a DSP.  It has SF and DF
instructions, MACs, and the usual DSP stuff.  It also has 64-bit
integer operations, all overlayed on the same set of co-processor
registers.

As a bonus it has 32-bit integer operations which caused Jeff Law and
myself all sorts of grief while trying to get them to work, so they are
not implemented.  I can't remember the details, but it had something
to do with subregs:

        A) upper and lower halves of float values were in the exact
        opposite halves of their integer values, so calculating
        (subreg:SI (reg:SF)) would get the wrong half of the
        register.

        B) splitting the coprocessor registers into pairs and
        allocating them that way would also confuse things because
        32-bit integer loads are sign extended automatically and there
        is no way to disable this.

I don't remember all the details, and frankly I don't care.  It was a
pain.  Anyone who really wants SI operations on Maverick can implement
it ;-).

Finally, there is some machine dependent reorg magic in place because
there are some Maverick instruction combination that are invalid (x
can't follow y within z cycles).  This is rumored to be in the
to-be-fixed-for-next-revision pipeline.

Cheers.
Aldy

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-14  8:50 [patch] new portlet: cirrus-maverick Aldy Hernandez
  2002-08-14  9:22 ` Aldy Hernandez
@ 2002-08-14  9:43 ` Phil Edwards
  2002-08-14  9:54   ` Aldy Hernandez
  2002-08-14 10:42 ` Mark Mitchell
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Phil Edwards @ 2002-08-14  9:43 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: rearnsha, nickc, gcc-patches, rsandifo

On Wed, Aug 14, 2002 at 08:57:52AM -0700, Aldy Hernandez wrote:
>   -mnop-fun-dllimport @gol
> + -mmaverick-fix-invalid-insns -mno-maverick-fix-invalid-insns @gol
>   -mtpcs-frame  -mtpcs-leaf-frame @gol
> *************** Allows calls via function pointers (incl
>   of executing a function pointer if this option is enabled.
> + 
> + @item -mmaverick-fix-invalid-insns
> + @opindex mmaverick-fix-invalid-insns
> + Insert nops to fix invalid Maverick instruction combinations.
> + 
> + @item -mno-maverick-fix-invalid-insns
> + @opindex mno-maverick-fix-invalid-insns
> + Do not insert nops to fix invalid Maverick instruction combinations.

I thought the convention was to only document the option that was /not/
the default?  Or at least to describe which of the flags was on by default.


Phil

-- 
I would therefore like to posit that computing's central challenge, viz. "How
not to make a mess of it," has /not/ been met.
                                                 - Edsger Dijkstra, 1930-2002

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-14  9:43 ` Phil Edwards
@ 2002-08-14  9:54   ` Aldy Hernandez
  2002-08-14 10:27     ` Phil Edwards
  0 siblings, 1 reply; 11+ messages in thread
From: Aldy Hernandez @ 2002-08-14  9:54 UTC (permalink / raw)
  To: Phil Edwards; +Cc: rearnsha, nickc, gcc-patches, rsandifo

On Wed, Aug 14, 2002 at 12:43:07PM -0400, Phil Edwards wrote:
> On Wed, Aug 14, 2002 at 08:57:52AM -0700, Aldy Hernandez wrote:
> >   -mnop-fun-dllimport @gol
> > + -mmaverick-fix-invalid-insns -mno-maverick-fix-invalid-insns @gol
> >   -mtpcs-frame  -mtpcs-leaf-frame @gol
> > *************** Allows calls via function pointers (incl
> >   of executing a function pointer if this option is enabled.
> > + 
> > + @item -mmaverick-fix-invalid-insns
> > + @opindex mmaverick-fix-invalid-insns
> > + Insert nops to fix invalid Maverick instruction combinations.
> > + 
> > + @item -mno-maverick-fix-invalid-insns
> > + @opindex mno-maverick-fix-invalid-insns
> > + Do not insert nops to fix invalid Maverick instruction combinations.
> 
> I thought the convention was to only document the option that was /not/
> the default?  Or at least to describe which of the flags was on by default.

News to me.  I can do either one.  Which is preferred?

Btw, the default is no-maverick-fix-invalid-insns.

Aldy

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-14  9:54   ` Aldy Hernandez
@ 2002-08-14 10:27     ` Phil Edwards
  2002-08-14 11:35       ` Aldy Hernandez
  0 siblings, 1 reply; 11+ messages in thread
From: Phil Edwards @ 2002-08-14 10:27 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: rearnsha, nickc, gcc-patches, rsandifo

On Wed, Aug 14, 2002 at 10:01:54AM -0700, Aldy Hernandez wrote:
> > I thought the convention was to only document the option that was /not/
> > the default?  Or at least to describe which of the flags was on by default.
> 
> News to me.  I can do either one.  Which is preferred?
> 
> Btw, the default is no-maverick-fix-invalid-insns.

Check out the opening description of the manual's warning options.
(Or maybe it's optimization options.)  Somewhere, when describing the
-f/-fno and -W/-Wno duality, it adds something to the effect of, "only
the non-default options are documented here, so you can figure out the
default behavior by inverting the listed option."

If It Were Me[tm], I'd only document maverick-fix-invalid-insns, with a
sentence or two about what the problem is and what the default behavior is.
I would give an example but I don't have a good understanding of the
default behavior here.  :-)


Phil

-- 
I would therefore like to posit that computing's central challenge, viz. "How
not to make a mess of it," has /not/ been met.
                                                 - Edsger Dijkstra, 1930-2002

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-14  8:50 [patch] new portlet: cirrus-maverick Aldy Hernandez
  2002-08-14  9:22 ` Aldy Hernandez
  2002-08-14  9:43 ` Phil Edwards
@ 2002-08-14 10:42 ` Mark Mitchell
  2002-08-15  2:47 ` Nick Clifton
  2002-08-15  4:50 ` Richard Earnshaw
  4 siblings, 0 replies; 11+ messages in thread
From: Mark Mitchell @ 2002-08-14 10:42 UTC (permalink / raw)
  To: Aldy Hernandez, rearnsha, nickc, gcc-patches; +Cc: rsandifo



--On Wednesday, August 14, 2002 08:57:52 AM -0700 Aldy Hernandez 
<aldyh@redhat.com> wrote:

> Hi Richard (Earnshaw and Sandiford).  Hi Nick.  Hi guys.
>

ARM maintainers, please note that I told Aldy that this was OK at this
point (Stage 2/Stage 3) if it was OK with you.  To me, it looks like the
changes are pretty well out of the way, so if y'all are happy with the
code, then please accept it.

Thanks,

-- 
Mark Mitchell                mark@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-14 10:27     ` Phil Edwards
@ 2002-08-14 11:35       ` Aldy Hernandez
  0 siblings, 0 replies; 11+ messages in thread
From: Aldy Hernandez @ 2002-08-14 11:35 UTC (permalink / raw)
  To: Phil Edwards; +Cc: rearnsha, nickc, gcc-patches, rsandifo

On Wed, Aug 14, 2002 at 01:26:54PM -0400, Phil Edwards wrote:
> On Wed, Aug 14, 2002 at 10:01:54AM -0700, Aldy Hernandez wrote:
> > > I thought the convention was to only document the option that was /not/
> > > the default?  Or at least to describe which of the flags was on by default.
> > 
> > News to me.  I can do either one.  Which is preferred?
> > 
> > Btw, the default is no-maverick-fix-invalid-insns.
> 
> Check out the opening description of the manual's warning options.
> (Or maybe it's optimization options.)  Somewhere, when describing the
> -f/-fno and -W/-Wno duality, it adds something to the effect of, "only
> the non-default options are documented here, so you can figure out the
> default behavior by inverting the listed option."
> 
> If It Were Me[tm], I'd only document maverick-fix-invalid-insns, with a
> sentence or two about what the problem is and what the default behavior is.
> I would give an example but I don't have a good understanding of the
> default behavior here.  :-)

Fair enough.  Fixed thusly:

@item -mmaverick-fix-invalid-insns
@opindex mmaverick-fix-invalid-insns
Some combinations of Maverick instructions are invalid if they occur
in sequence.  If you use this option, GCC will insert nops in the
relevant places to avoid generating these sequences.  This option is
turned off by default and is only needed for revisions of Maverick
chips for which certain combinations are invalid.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-14  8:50 [patch] new portlet: cirrus-maverick Aldy Hernandez
                   ` (2 preceding siblings ...)
  2002-08-14 10:42 ` Mark Mitchell
@ 2002-08-15  2:47 ` Nick Clifton
  2002-08-15  4:50 ` Richard Earnshaw
  4 siblings, 0 replies; 11+ messages in thread
From: Nick Clifton @ 2002-08-15  2:47 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: rearnsha, gcc-patches, rsandifo

Hi Aldy,

> 2002-08-13  Aldy Hernandez  <aldyh@redhat.com>
> 
> 	* config/arm/arm.h (TARGET_CPU_armmaverick): New.
> 	Check TARGET_CPU_DEFAULT for maverick.
> 	(CPP_CPU_ARCH_SPEC): Add support for maverick.
> 	(MAVERICK_FIX_INVALID_INSNS): New macro.
> 	(TARGET_ANY_HARD_FLOAT): Same.
> 	(TARGET_MAVERICK): Same.
> 	(TARGET_MAVERICK_FIX_INVALID_INSNS): Same.
> 	(TARGET_SWITCHES): Add maverick-fix-invalid-insns,
> 	no-maverick-fix-invalid-insns.
> 	(floating_point_type): Add FP_MAVERICK.
> 	(FLOAT_WORDS_BIG_ENDIAN): Adjust for maverick.
> 	(CONDITIONAL_REGISTER_USAGE): Same.
> 	(FIRST_MAVERICK_FP_REGNUM): New.
> 	(LAST_MAVERICK_FP_REGNUM): New.
> 	(IS_MAVERICK_REGNUM): New.
> 	(FIRST_PSEUDO_REGISTER): Change to 43.
> 	(reg_class): Add MAVERICK_REGS.
> 	(REG_CLASS_NAMES): Same.
> 	(REG_CLASS_CONTENTS): Same.
> 	(REG_CLASS_FROM_LETTER): Add 'v'.
> 	(EXTRA_CONSTRAINT_ARM): Add 'T'.
> 	(SECONDARY_INPUT_RELOAD_CLASS): Disallow constants in Maverick
> 	registers.
> 	(ARM_LEGITIMIZE_RELOAD_ADDRESS): Adjust for maverick.
> 	(CLASS_MAX_NREGS): Same.
> 	(REGISTER_MOVE_COST): Same.
> 	(LIBCALL_VALUE): Same.
> 	(FUNCTION_VALUE_REGNO_P): Same.
> 	(ARM_GO_IF_LEGITIMATE_INDEX): Same.
> 	(CLASS_CANNOT_CHANGE_MODE): New.
> 	(CLASS_CANNOT_CHANGE_MODE_P): New.
> 	(PREDICATE_CODES): Add maverick_fp_register, maverick_shift_const,
> 	maverick_register_operand.
> 
> 	* config/arm/arm.c (FL_MAVERICK): New.
> 	New global arm_is_maverick.
> 	(all_cores): Change arm9e to armmaverick.
> 	(all_architectures): Add armmaverick.
> 	(arm_override_options): Adjust for maverick.
> 	(arm_select_cc_mode): Same.
> 	(maverick_memory_offset): New.
> 	(maverick_register_operand): New.
> 	(maverick_fp_register): New.
> 	(maverick_shift_const): New.
> 	(is_load_address): New.
> 	(is_maverick_insn): New.
> 	(maverick_reorg): New.
> 	(arm_reorg): Reorg maverick insns.
> 	(arm_print_operand): Add 's'.
> 
> 	* config/arm/arm.md: New function units maverick_fpa.
> 	New attribute maverick.
> 	(adddi3): Adjust for maverick.
> 
> 	Disallow all DI patterns for maverick.
> 
> 	Change float SF patterns to expanders.  Rename patterns to
> 	*arm_blah.  Add a corresponding maverick pattern.
> 	
> 	New patterns: maverick_adddi3, *maverick_addsi3, *maverick_addsf3,
> 	*maverick_adddf3, maverick_subdi3, *maverick_subsi3_insn,
> 	*maverick_subsf3, *maverick_subdf3, *maverick_mulsi3, muldi3,
> 	*maverick_mulsi3addsi, *maverick_mulsi3subsi, *maverick_mulsf3,
> 	*maverick_muldf3, *maverick_ashl_const, *maverick_ashiftrt_const,
> 	*maverick_ashlsi3, *maverick_ashldi3, *maverick_ashldi_const,
> 	*maverick_ashiftrtdi_const, *maverick_ashldi3, *maverick_ashldi_const,
> 	*maverick_ashiftrtdi_const, *maverick_negdi2, *maverick_negsi2,
> 	"*maverick_negsf2, *arm_negdf2, *maverick_negdf2, *maverick_abssi2,
> 	*maverick_abssf2, *maverick_absdf2, *maverick_floatsisf2,
> 	*maverick_floatsidf2, floatdisf2, floatdidf2, *maverick_truncdfsi2,
> 	*maverick_truncdfsf2, *maverick_extendsfdf2, *maverick_arm_movdi,
> 	*maverick_arm_movsi_insn, *maverick_movsf_hard_insn,
> 	*maverick_movdf_hard_insn, *maverick_cmpsf, *maverick_cmpdf, cmpdi,
> 	*maverick_cmpdi, *maverick_cmpsi_1.
> 
> 	Add v constraint to call_value_reg, call_value_mem,
> 	call_value_symbol, *sibcall_value_insn.
> 
> 	* config/arm/arm-protos.h: Add prototypes for maverick_fp_register,
> 	maverick_general_operand, maverick_register_operand,
> 	maverick_shift_const, maverick_memory_offset.
> 
> 	* gcc/doc/invoke.texi (ARM Options): Document
> 	maverick-fix-invalid-insns and no-maverick-fix-invalid-insns.
> 
> 	* config/arm/aout.h (ADDITIONAL_REGISTER_NAMES): Add maverick
> 	registers.
> 	(REGISTER_NAMES): Same.
> 
> 	* config/arm/t-maverick-elf: New.
> 
> 	* config.gcc: Add support for armmaverick.

Approved by me as well - please apply.

Cheers
        Nick

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-14  8:50 [patch] new portlet: cirrus-maverick Aldy Hernandez
                   ` (3 preceding siblings ...)
  2002-08-15  2:47 ` Nick Clifton
@ 2002-08-15  4:50 ` Richard Earnshaw
  2002-08-15 11:16   ` Aldy Hernandez
  4 siblings, 1 reply; 11+ messages in thread
From: Richard Earnshaw @ 2002-08-15  4:50 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: rearnsha, nickc, gcc-patches, rsandifo

Aldy,

I've a number of (hopefully) small niggles with this which I'd like to see 
sorted out before it goes in.  I'm a little pressed for time at the 
moment, but here's a couple for starters.

+ static int       is_maverick_insn                 PARAMS ((rtx));

Please use something like maverick_insn_p() so that
	1) it fits in with the convention for predicates.
	2) it starts with 'maverick'

+ /* Nonzero if this chip is a Cirrus/DSP.  */
+ int arm_is_maverick = 0;

There's much confusion in the ARM backend because these arm_is_xxx 
variables are sometimes used to indicate that we are generating code for 
the architecture xxx and sometimes that we are trying to tune to processor 
xxx.  Please can you use arm_tune_maveric or arm_arch_maverick as 
appropriate -- we'll try to fix up the other (ab)uses later, but please 
let's not propagate the issue further.

-   {"arm9e",	       	      		 FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |       
     FL_LDSCHED },
+   {"armmaverick",      	      		 FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |   
         FL_LDSCHED |             FL_MAVERICK },

No!  the arm9e is a valid ARM processor.  Why have you removed it?

+ static int
+ is_load_address (insn)
+      rtx insn;
+ {
+   rtx body, lhs, rhs;;
+ 
+   if (!insn)
+     return 0;
+ 
+   if (GET_CODE (insn) != INSN)
+     return 0;
+ 
+   body = PATTERN (insn);
+ 
+   if (GET_CODE (body) != SET)
+     return 0;
+ 
+   lhs = XEXP (body, 0);
+   rhs = XEXP (body, 1);
+ 
+   return (GET_CODE (lhs) == REG
+ 	  && REGNO_REG_CLASS (REGNO (lhs)) == GENERAL_REGS
+ 	  && (GET_CODE (rhs) == MEM
+ 	      || GET_CODE (rhs) == SYMBOL_REF));
+ }

What is this used for, and why isn't it using the general 
constant-reloading code in ARM_MACHINE_DEPENDENT_REORG?  I'm worried that 
this is going to break somehow.

Also, use single_set(), SET_SRC() and SET_DEST() in this code if you must 
keep it.

You should also be using note_invalid_constants(), which will detect moves 
of constants into a register that are about to be converted into minipool 
loads.

+ is_maverick_insn (insn)
+      rtx insn;
+ {
+   enum attr_maverick attr;
+ 
+   /* get_attr aborts on USE and CLOBBER.  */
+   if (!insn
+       || GET_CODE (insn) != INSN
+       || GET_CODE (PATTERN (insn)) == USE
+       || GET_CODE (PATTERN (insn)) == CLOBBER)
+     return 0;
+ 

Use active_insn_p(); also use it in maverick_reorg.


    for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn 
(insn))
      {
+       if (TARGET_MAVERICK_FIX_INVALID_INSNS
+           && (is_maverick_insn (insn)
+ 	      || GET_CODE (insn) == JUMP_INSN
+ 	      || is_load_address (insn)))
+ 	maverick_reorg (insn);
+ 

 You should also be using note_invalid_constants(), which will detect 
moves of constants into a register that are about to be converted into 
minipool loads.  Rather than using is_load_address it might be better to 
look for insns whose attribue "type" is load etc.

+ %{march=armmaverick:-D__ARM_ARCH_4T__} \
+ %{march=armmaverick:-D__MAVERICK__} \

Exactly which version of the ARM9 is the Maverick based on?  The ARM9E 
core is a v5TE device.

+ /* Fix invalid Maverick instruction combinations by inserting NOPs.  */
+ #define MAVERICK_FIX_INVALID_INSNS	(1 << 24)
+ 
  /* Nonzero if the function prologue (and epilogue) should obey
     the ARM Procedure Call Standard.  */
  #define ARM_FLAG_APCS_FRAME	(1 << 0)

Please keep these 'bit' assignments in numeric order (so we can easily 
tell which have been used).

I think most of the arm.md file changes are OK, but it's sometimes hard to 
tell which pattern you are changing.  Can you regenerate the diff for that 
file with

	diff -p -F "^("

R.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-15  4:50 ` Richard Earnshaw
@ 2002-08-15 11:16   ` Aldy Hernandez
  2002-08-16  3:28     ` Richard Earnshaw
  0 siblings, 1 reply; 11+ messages in thread
From: Aldy Hernandez @ 2002-08-15 11:16 UTC (permalink / raw)
  To: Richard.Earnshaw; +Cc: rearnsha, nickc, gcc-patches, rsandifo

On Thu, Aug 15, 2002 at 12:49:58PM +0100, Richard Earnshaw wrote:

Hi Richard.

Thanks for taking the time to review the patch.

> + static int       is_maverick_insn                 PARAMS ((rtx));
> 
> Please use something like maverick_insn_p() so that

done.

> + /* Nonzero if this chip is a Cirrus/DSP.  */
> + int arm_is_maverick = 0;
> 
> There's much confusion in the ARM backend because these arm_is_xxx 
> variables are sometimes used to indicate that we are generating code for 
> the architecture xxx and sometimes that we are trying to tune to processor 
> xxx.  Please can you use arm_tune_maveric or arm_arch_maverick as 

done.

> No!  the arm9e is a valid ARM processor.  Why have you removed it?

My bad.  The initial implementation had it as arm9e (erroneously) and
I assumed this was fallback from it.

> + static int
> + is_load_address (insn)
> +      rtx insn;
> + {
> + }
> 
> What is this used for, and why isn't it using the general 
> constant-reloading code in ARM_MACHINE_DEPENDENT_REORG?  I'm worried that 
> this is going to break somehow.

This is used in maverick_reorg() to match certain load operations and
insert a nop inbetween the load and a Maverick instruction.  Like
this:

ldr r0, blah
--> insert nop here
cfmvsr mvf0, r0

This is needed because Cirrus realized too late that they weren't
handling this in hardware, so they asked for a fixup-phase to clean up
their mess.  Rumor has it the next revision won't need this.

> Also, use single_set(), SET_SRC() and SET_DEST() in this code if you must 
> keep it.

Done.

> +       || GET_CODE (PATTERN (insn)) == CLOBBER)
> +     return 0;
> + 
> 
> Use active_insn_p(); also use it in maverick_reorg.

Done.

>     for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn 
> (insn))
>       {
> +       if (TARGET_MAVERICK_FIX_INVALID_INSNS
> +           && (is_maverick_insn (insn)
> + 	      || GET_CODE (insn) == JUMP_INSN
> + 	      || is_load_address (insn)))
> + 	maverick_reorg (insn);
> + 
> 
>  You should also be using note_invalid_constants(), which will detect 
> moves of constants into a register that are about to be converted into 
> minipool loads.  Rather than using is_load_address it might be better to 
> look for insns whose attribue "type" is load etc.

I don't understand.  All I need is to fix these few instances.  I
don't care about the rest.  Perhaps I'm missing something.

> + %{march=armmaverick:-D__ARM_ARCH_4T__} \
> + %{march=armmaverick:-D__MAVERICK__} \
> 
> Exactly which version of the ARM9 is the Maverick based on?  The ARM9E 
> core is a v5TE device.

Arm920T.

> + /* Fix invalid Maverick instruction combinations by inserting NOPs.  */
> + #define MAVERICK_FIX_INVALID_INSNS	(1 << 24)
> + 
>   /* Nonzero if the function prologue (and epilogue) should obey
>      the ARM Procedure Call Standard.  */
>   #define ARM_FLAG_APCS_FRAME	(1 << 0)
> 
> Please keep these 'bit' assignments in numeric order (so we can easily 
> tell which have been used).

Done.

> I think most of the arm.md file changes are OK, but it's sometimes hard to 
> tell which pattern you are changing.  Can you regenerate the diff for that 
> file with
> 
> 	diff -p -F "^("

Sweet.  This is incredibly cool.  Thanks.

Ok.  How does this patch look?

2002-08-13  Aldy Hernandez  <aldyh@redhat.com>

	* config/arm/arm.h (TARGET_CPU_armmaverick): New.
	Check TARGET_CPU_DEFAULT for maverick.
	(CPP_CPU_ARCH_SPEC): Add support for maverick.
	(MAVERICK_FIX_INVALID_INSNS): New macro.
	(TARGET_ANY_HARD_FLOAT): Same.
	(TARGET_MAVERICK): Same.
	(TARGET_MAVERICK_FIX_INVALID_INSNS): Same.
	(TARGET_SWITCHES): Add maverick-fix-invalid-insns,
	no-maverick-fix-invalid-insns.
	(floating_point_type): Add FP_MAVERICK.
	(FLOAT_WORDS_BIG_ENDIAN): Adjust for maverick.
	(CONDITIONAL_REGISTER_USAGE): Same.
	(FIRST_MAVERICK_FP_REGNUM): New.
	(LAST_MAVERICK_FP_REGNUM): New.
	(IS_MAVERICK_REGNUM): New.
	(FIRST_PSEUDO_REGISTER): Change to 43.
	(reg_class): Add MAVERICK_REGS.
	(REG_CLASS_NAMES): Same.
	(REG_CLASS_CONTENTS): Same.
	(REG_CLASS_FROM_LETTER): Add 'v'.
	(EXTRA_CONSTRAINT_ARM): Add 'T'.
	(SECONDARY_INPUT_RELOAD_CLASS): Disallow constants in Maverick
	registers.
	(ARM_LEGITIMIZE_RELOAD_ADDRESS): Adjust for maverick.
	(CLASS_MAX_NREGS): Same.
	(REGISTER_MOVE_COST): Same.
	(LIBCALL_VALUE): Same.
	(FUNCTION_VALUE_REGNO_P): Same.
	(ARM_GO_IF_LEGITIMATE_INDEX): Same.
	(CLASS_CANNOT_CHANGE_MODE): New.
	(CLASS_CANNOT_CHANGE_MODE_P): New.
	(PREDICATE_CODES): Add maverick_fp_register, maverick_shift_const,
	maverick_register_operand.

	* config/arm/arm.c (FL_MAVERICK): New.
	New global arm_arch_maverick.
	(all_cores): Add armmaverick.
	(all_architectures): Add armmaverick.
	(arm_override_options): Adjust for maverick.
	(arm_select_cc_mode): Same.
	(maverick_memory_offset): New.
	(maverick_register_operand): New.
	(maverick_fp_register): New.
	(maverick_shift_const): New.
	(is_load_address): New.
	(maverick_insn_p): New.
	(maverick_reorg): New.
	(arm_reorg): Reorg maverick insns.
	(arm_print_operand): Add 's'.

	* config/arm/arm.md: New function units maverick_fpa.
	New attribute maverick.
	(adddi3): Adjust for maverick.

	Disallow all DI patterns for maverick.

	Change float SF patterns to expanders.  Rename patterns to
	*arm_blah.  Add a corresponding maverick pattern.
	
	New patterns: maverick_adddi3, *maverick_addsi3, *maverick_addsf3,
	*maverick_adddf3, maverick_subdi3, *maverick_subsi3_insn,
	*maverick_subsf3, *maverick_subdf3, *maverick_mulsi3, muldi3,
	*maverick_mulsi3addsi, *maverick_mulsi3subsi, *maverick_mulsf3,
	*maverick_muldf3, *maverick_ashl_const, *maverick_ashiftrt_const,
	*maverick_ashlsi3, *maverick_ashldi3, *maverick_ashldi_const,
	*maverick_ashiftrtdi_const, *maverick_ashldi3, *maverick_ashldi_const,
	*maverick_ashiftrtdi_const, *maverick_negdi2, *maverick_negsi2,
	"*maverick_negsf2, *arm_negdf2, *maverick_negdf2, *maverick_abssi2,
	*maverick_abssf2, *maverick_absdf2, *maverick_floatsisf2,
	*maverick_floatsidf2, floatdisf2, floatdidf2, *maverick_truncdfsi2,
	*maverick_truncdfsf2, *maverick_extendsfdf2, *maverick_arm_movdi,
	*maverick_arm_movsi_insn, *maverick_movsf_hard_insn,
	*maverick_movdf_hard_insn, *maverick_cmpsf, *maverick_cmpdf, cmpdi,
	*maverick_cmpdi, *maverick_cmpsi_1.

	Add v constraint to call_value_reg, call_value_mem,
	call_value_symbol, *sibcall_value_insn.

	* config/arm/arm-protos.h: Add prototypes for maverick_fp_register,
	maverick_general_operand, maverick_register_operand,
	maverick_shift_const, maverick_memory_offset.

	* gcc/doc/invoke.texi (ARM Options): Document
	maverick-fix-invalid-insns and no-maverick-fix-invalid-insns.

	* config/arm/aout.h (ADDITIONAL_REGISTER_NAMES): Add maverick
	registers.
	(REGISTER_NAMES): Same.

	* config/arm/t-maverick-elf: New.

	* config.gcc: Add support for armmaverick.


Index: config/arm/arm.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/arm.c,v
retrieving revision 1.221
diff -c -p -r1.221 arm.c
*** config/arm/arm.c	11 Aug 2002 18:48:50 -0000	1.221
--- config/arm/arm.c	15 Aug 2002 18:07:31 -0000
*************** static void	 arm_elf_asm_named_section	P
*** 123,128 ****
--- 123,131 ----
  #ifndef ARM_PE
  static void	 arm_encode_section_info	PARAMS ((tree, int));
  #endif
+ static int 	 is_load_address                PARAMS ((rtx));
+ static int       maverick_insn_p                 PARAMS ((rtx));
+ static void      maverick_reorg                   PARAMS ((rtx));
  
  #undef Hint
  #undef Mmode
*************** int    arm_structure_size_boundary = DEF
*** 230,235 ****
--- 233,239 ----
  #define FL_STRONG     (1 << 8)	      /* StrongARM */
  #define FL_ARCH5E     (1 << 9)        /* DSP extenstions to v5 */
  #define FL_XSCALE     (1 << 10)	      /* XScale */
+ #define FL_MAVERICK   (1 << 30)     /* Cirrus/DSP.  */
  
  /* The bits in this mask specify which
     instructions we are allowed to generate.  */
*************** int arm_ld_sched = 0;
*** 262,267 ****
--- 266,274 ----
  /* Nonzero if this chip is a StrongARM.  */
  int arm_is_strong = 0;
  
+ /* Nonzero if this chip is a Cirrus/DSP.  */
+ int arm_arch_maverick = 0;
+ 
  /* Nonzero if this chip is an XScale.  */
  int arm_is_xscale = 0;
  
*************** static const struct processors all_cores
*** 358,363 ****
--- 365,371 ----
    {"arm940t",	                         FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
    {"arm9tdmi",	                         FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
    {"arm9e",	       	      		 FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED },
+   {"armmaverick",      	      		 FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED |             FL_MAVERICK },
    {"strongarm",	             FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
    {"strongarm110",           FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
    {"strongarm1100",          FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
*************** arm_override_options ()
*** 481,486 ****
--- 489,495 ----
  	{ TARGET_CPU_arm9,      "arm9" },
  	{ TARGET_CPU_strongarm, "strongarm" },
  	{ TARGET_CPU_xscale,    "xscale" },
+ 	{ TARGET_CPU_armmaverick, "armmaverick" },
  	{ TARGET_CPU_generic,   "arm" },
  	{ 0, 0 }
        };
*************** arm_override_options ()
*** 679,684 ****
--- 688,707 ----
    thumb_code	    = (TARGET_ARM == 0);
    arm_is_6_or_7     = (((tune_flags & (FL_MODE26 | FL_MODE32))
  		       && !(tune_flags & FL_ARCH4))) != 0;
+   arm_arch_maverick = (insn_flags & FL_MAVERICK) != 0;
+ 
+   if (arm_arch_maverick)
+     {
+       arm_fpu = FP_MAVERICK;
+ 
+       if (TARGET_SOFT_FLOAT)
+ 	warning ("-msoft-float option ignored because armmaverick chip selected");
+ 
+       /* Ignore -mhard-float if -mcpu=armmaverick.  */
+       if (TARGET_HARD_FLOAT)
+ 	target_flags ^= ARM_FLAG_SOFT_FLOAT;
+     }
+   else
  
    /* Default value for floating point code... if no co-processor
       bus, then schedule for emulated floating point.  Otherwise,
*************** arm_override_options ()
*** 700,705 ****
--- 723,736 ----
    else
      arm_fpu_arch = FP_DEFAULT;
    
+   if (TARGET_FPE)
+     {
+       if (arm_fpu == FP_SOFT3)
+ 	arm_fpu = FP_SOFT2;
+       else if (arm_fpu == FP_MAVERICK)
+ 	warning ("-mpfpe switch not supported by armmaverick target cpu - ignored.");
+     }
+   else
    if (TARGET_FPE && arm_fpu != FP_HARD)
      arm_fpu = FP_SOFT2;
    
*************** fpu_add_operand (op, mode)
*** 3280,3285 ****
--- 3311,3568 ----
    return FALSE;
  }
  
+ /* Return nonzero if OP is a valid Maverick memory address pattern.  */
+ 
+ int
+ maverick_memory_offset (op)
+      rtx op;
+ {
+ 
+   /* Reject eliminable registers.  */
+   if (! (reload_in_progress || reload_completed)
+       && (   reg_mentioned_p (frame_pointer_rtx, op)
+ 	  || reg_mentioned_p (arg_pointer_rtx, op)
+ 	  || reg_mentioned_p (virtual_incoming_args_rtx, op)
+ 	  || reg_mentioned_p (virtual_outgoing_args_rtx, op)
+ 	  || reg_mentioned_p (virtual_stack_dynamic_rtx, op)
+ 	  || reg_mentioned_p (virtual_stack_vars_rtx, op)))
+     return 0;
+ 
+   if (GET_CODE (op) == MEM)
+     {
+       rtx ind;
+ 
+       ind = XEXP (op, 0);
+ 
+       /* Match: (mem (reg)).  */
+       if (GET_CODE (ind) == REG)
+ 	return 1;
+ 
+       /* Match:
+ 	 (mem (plus (reg)
+ 	            (const))).  */
+       if (GET_CODE (ind) == PLUS
+ 	  && GET_CODE (XEXP (ind, 0)) == REG
+ 	  && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
+ 	  && GET_CODE (XEXP (ind, 1)) == CONST_INT)
+ 	return 1;
+     }
+ 
+   return 0;
+ }
+ 
+ /* Return nonzero if OP is a Maverick or general register.  */
+ 
+ int
+ maverick_register_operand (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   if (GET_MODE (op) != mode && mode != VOIDmode)
+     return FALSE;
+ 
+   if (GET_CODE (op) == SUBREG)
+     op = SUBREG_REG (op);
+ 
+   return (GET_CODE (op) == REG
+ 	  && (REGNO_REG_CLASS (REGNO (op)) == MAVERICK_REGS
+ 	      || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
+ }
+ 
+ /* Return nonzero if OP is a maverick FP register.  */
+ 
+ int
+ maverick_fp_register (op, mode)
+      rtx op;
+      enum machine_mode mode;
+ {
+   if (GET_MODE (op) != mode && mode != VOIDmode)
+     return FALSE;
+ 
+   if (GET_CODE (op) == SUBREG)
+     op = SUBREG_REG (op);
+ 
+   return (GET_CODE (op) == REG
+ 	  && (REGNO (op) >= FIRST_PSEUDO_REGISTER
+ 	      || REGNO_REG_CLASS (REGNO (op)) == MAVERICK_REGS));
+ }
+ 
+ /* Return nonzero if OP is a 6bit constant (0..63).  */
+ 
+ int
+ maverick_shift_const (op, mode)
+      rtx op;
+      enum machine_mode mode ATTRIBUTE_UNUSED;
+ {
+   return (GET_CODE (op) == CONST_INT
+ 	  && INTVAL (op) >= 0
+ 	  && INTVAL (op) < 64);
+ }
+ 
+ /* Return nonzero if INSN is an LDR R0,ADDR instruction.  */
+ 
+ static int
+ is_load_address (insn)
+      rtx insn;
+ {
+   rtx body, lhs, rhs;;
+ 
+   if (!insn)
+     return 0;
+ 
+   if (GET_CODE (insn) != INSN)
+     return 0;
+ 
+   body = PATTERN (insn);
+ 
+   if (GET_CODE (body) != SET)
+     return 0;
+ 
+   lhs = SET_DEST (body);
+   rhs = SET_SRC (body);
+ 
+   return (GET_CODE (lhs) == REG
+ 	  && REGNO_REG_CLASS (REGNO (lhs)) == GENERAL_REGS
+ 	  && (GET_CODE (rhs) == MEM
+ 	      || GET_CODE (rhs) == SYMBOL_REF));
+ }
+ 
+ /* Return nonzero if INSN is a Maverick instruction.  */
+ 
+ static int
+ maverick_insn_p (insn)
+      rtx insn;
+ {
+   enum attr_maverick attr;
+ 
+   if (!active_insn_p (insn))
+     return 0;
+ 
+   attr = get_attr_maverick (insn);
+ 
+   return attr != MAVERICK_NO;
+ }
+ 
+ /* Maverick reorg for invalid instruction combinations.  */
+ 
+ static void
+ maverick_reorg (first)
+      rtx first;
+ {
+   enum attr_maverick attr;
+   rtx body = PATTERN (first);
+   rtx t;
+   int nops;
+ 
+   /* Any branch must be followed by 2 non Maverick instructions.  */
+   if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN)
+     {
+       nops = 0;
+       t = next_nonnote_insn (first);
+ 
+       if (maverick_insn_p (t))
+ 	++ nops;
+ 
+       if (maverick_insn_p (next_nonnote_insn (t)))
+ 	++ nops;
+ 
+       while (nops --)
+ 	emit_insn_after (gen_nop (), first);
+ 
+       return;
+     }
+ 
+   /* (float (blah)) is in parallel with a clobber.  */
+   if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
+     body = XVECEXP (body, 0, 0);
+ 
+   if (GET_CODE (body) == SET)
+     {
+       rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1);
+ 
+       /* cfldrd, cfldr64, cfstrd, cfstr64 must
+ 	 be followed by a non Maverick insn.  */
+       if (get_attr_maverick (first) == MAVERICK_DOUBLE)
+ 	{
+ 	  if (maverick_insn_p (next_nonnote_insn (first)))
+ 	    emit_insn_after (gen_nop (), first);
+ 
+ 	  return;
+ 	}
+       else if (is_load_address (first))
+ 	{
+ 	  unsigned int arm_regno;
+ 
+ 	  /* Any ldr/cfmvdlr, ldr/cfmvdhr, ldr/cfmvsr, ldr/cfmv64lr,
+ 	     ldr/cfmv64hr combination where the Rd field is the same
+ 	     in both instructions must be split with a non Maverick
+ 	     insn.  Example:
+ 
+ 	     ldr r0, blah
+ 	     nop
+ 	     cfmvsr mvf0, r0.  */
+ 
+ 	  /* Get Arm register number for ldr insn.  */
+ 	  if (GET_CODE (lhs) == REG)
+ 	    arm_regno = REGNO (lhs);
+ 	  else if (GET_CODE (rhs) == REG)
+ 	    arm_regno = REGNO (rhs);
+ 	  else
+ 	    abort ();
+ 
+ 	  /* Next insn.  */
+ 	  first = next_nonnote_insn (first);
+ 
+ 	  if (!maverick_insn_p (first))
+ 	    return;
+ 
+ 	  body = PATTERN (first);
+ 
+           /* (float (blah)) is in parallel with a clobber.  */
+           if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0))
+ 	    body = XVECEXP (body, 0, 0);
+ 
+ 	  if (GET_CODE (body) == FLOAT)
+ 	    body = XEXP (body, 0);
+ 
+ 	  if (get_attr_maverick (first) == MAVERICK_MOVE
+ 	      && GET_CODE (XEXP (body, 1)) == REG
+ 	      && arm_regno == REGNO (XEXP (body, 1)))
+ 	    emit_insn_after (gen_nop (), first);
+ 
+ 	  return;
+ 	}
+     }
+ 
+   /* get_attr aborts on USE and CLOBBER.  */
+   if (!first
+       || GET_CODE (first) != INSN
+       || GET_CODE (PATTERN (first)) == USE
+       || GET_CODE (PATTERN (first)) == CLOBBER)
+     return;
+ 
+   attr = get_attr_maverick (first);
+ 
+   /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...)
+      must be followed by a non-coprocessor instruction.  */
+   if (attr == MAVERICK_COMPARE)
+     {
+       nops = 0;
+ 
+       t = next_nonnote_insn (first);
+ 
+       if (maverick_insn_p (t))
+ 	++ nops;
+ 
+       if (maverick_insn_p (next_nonnote_insn (t)))
+ 	++ nops;
+ 
+       while (nops --)
+ 	emit_insn_after (gen_nop (), first);
+ 
+       return;
+     }
+ }
  /* Return nonzero if OP is a constant power of two.  */
  
  int
*************** arm_select_cc_mode (op, x, y)
*** 4779,4784 ****
--- 5062,5069 ----
  	case LE:
  	case GT:
  	case GE:
+ 	  if (TARGET_MAVERICK)
+ 	    return CCFPmode;
  	  return CCFPEmode;
  
  	default:
*************** arm_reorg (first)
*** 6089,6094 ****
--- 6374,6385 ----
    /* Scan all the insns and record the operands that will need fixing.  */
    for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn (insn))
      {
+       if (TARGET_MAVERICK_FIX_INVALID_INSNS
+           && (maverick_insn_p (insn)
+ 	      || GET_CODE (insn) == JUMP_INSN
+ 	      || is_load_address (insn)))
+ 	maverick_reorg (insn);
+ 
        if (GET_CODE (insn) == BARRIER)
  	push_minipool_barrier (insn, address);
        else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
*************** arm_print_operand (stream, x, code)
*** 8487,8492 ****
--- 8778,8793 ----
        fprintf (stream, "%s", arithmetic_instr (x, 1));
        return;
  
+     /* Truncate Maverick shift counts.  */
+     case 's':
+       if (GET_CODE (x) == CONST_INT)
+ 	{
+ 	  fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x3f);
+ 	  return;
+ 	}
+       arm_print_operand (stream, x, 0);
+       return;
+ 
      case 'I':
        fprintf (stream, "%s", arithmetic_instr (x, 0));
        return;
*************** arm_print_operand (stream, x, code)
*** 8593,8598 ****
--- 8894,8936 ----
  	fputs (thumb_condition_code (x, 1), stream);
        return;
  
+     /* Maverick registers can be accessed in a variety of ways:
+          single floating point (f)
+ 	 double floating point (d)
+ 	 32bit integer         (fx)
+ 	 64bit integer         (dx).  */
+     case 'W':			/* Maverick register in F mode.  */
+     case 'X':			/* Maverick register in D mode.  */
+     case 'Y':			/* Maverick register in FX mode.  */
+     case 'Z':			/* Maverick register in DX mode.  */
+       if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != MAVERICK_REGS)
+ 	abort ();
+ 
+       fprintf (stream, "mv%s%s",
+ 	       code == 'W' ? "f"
+ 	       : code == 'X' ? "d"
+ 	       : code == 'Y' ? "fx" : "dx", reg_names[REGNO (x)] + 2);
+ 
+       return;
+ 
+     /* Print maverick register in the mode specified by the register's
+        mode.  */
+     case 'V':
+       {
+ 	int mode = GET_MODE (x);
+ 
+ 	if (GET_CODE (x) != REG
+ 	    || REGNO_REG_CLASS (REGNO (x)) != MAVERICK_REGS)
+ 	  abort ();
+ 
+ 	fprintf (stream, "mv%s%s",
+ 		 mode == DFmode ? "d"
+ 		 : mode == SImode ? "fx"
+ 		 : mode == DImode ? "dx"
+ 		 : "f", reg_names[REGNO (x)] + 2);
+ 
+ 	return;
+       }
      default:
        if (x == 0)
  	abort ();
*************** arm_final_prescan_insn (insn)
*** 9084,9089 ****
--- 9422,9438 ----
  		    || GET_CODE (scanbody) == PARALLEL)
  		  || get_attr_conds (this_insn) != CONDS_NOCOND)
  		fail = TRUE;
+ 	      /* A conditional maverick instruction must be followed by
+ 		 a non Maverick instruction.  However, since we
+ 		 conditionalize instructions in this function and by
+ 		 the time we get here we can't add instructions
+ 		 (nops), because shorten_branches() has already been
+ 		 called, we will disable conditionalizing Maverick
+ 		 instructions to be safe.  */
+ 	      if (GET_CODE (scanbody) != USE
+ 		  && GET_CODE (scanbody) != CLOBBER
+ 		  && get_attr_maverick (this_insn) != MAVERICK_NO)
+ 		fail = TRUE;
  	      break;
  
  	    default:
*************** arm_hard_regno_mode_ok (regno, mode)
*** 9167,9172 ****
--- 9516,9529 ----
         start of an even numbered register pair.  */
      return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
  
+   if (IS_MAVERICK_REGNUM (regno))
+     /* We have outlawed SI values in Maverick registers because they
+        reside in the lower 32 bits, but SF values reside in the
+        upper 32 bits.  This causes gcc all sorts of grief.  We can't
+        even split the registers into pairs because Maverick SI values
+        get sign extended to 64bits.  */
+     return (GET_MODE_CLASS (mode) == MODE_FLOAT) || (mode == DImode);
+ 
    if (regno <= LAST_ARM_REGNUM)
      /* We allow any value to be stored in the general regisetrs.  */
      return 1;
*************** arm_regno_class (regno)
*** 9206,9211 ****
--- 9563,9570 ----
    if (regno == CC_REGNUM)
      return NO_REGS;
  
+   if (IS_MAVERICK_REGNUM (regno))
+     return MAVERICK_REGS;
    return FPU_REGS;
  }
  
Index: config/arm/arm.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/arm.h,v
retrieving revision 1.155
diff -c -p -r1.155 arm.h
*** config/arm/arm.h	8 Aug 2002 11:08:34 -0000	1.155
--- config/arm/arm.h	15 Aug 2002 18:07:41 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 91,96 ****
--- 91,97 ----
  #define TARGET_CPU_arm9		0x0080
  #define TARGET_CPU_arm9tdmi	0x0080
  #define TARGET_CPU_xscale       0x0100
+ #define TARGET_CPU_armmaverick	0x0200
  /* Configure didn't specify.  */
  #define TARGET_CPU_generic	0x8000
  
*************** extern GTY(()) rtx aof_pic_label;
*** 159,164 ****
--- 160,173 ----
  #if TARGET_CPU_DEFAULT == TARGET_CPU_xscale
  #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__"
  #else
+ #if TARGET_CPU_DEFAULT == TARGET_CPU_armmaverick
+ #define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__ -D__MAVERICK__"
+ /* Set TARGET_DEFAULT to the default, but without soft-float.  */
+ #ifdef TARGET_DEFAULT
+ #undef TARGET_DEFAULT
+ #define TARGET_DEFAULT	(ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+ #endif /* TARGET_CPU_DEFAULT */
+ #else
  Unrecognized value in TARGET_CPU_DEFAULT.
  #endif
  #endif
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 166,171 ****
--- 175,181 ----
  #endif
  #endif
  #endif
+ #endif
  
  #undef  CPP_SPEC
  #define CPP_SPEC "%(cpp_cpu_arch) %(subtarget_cpp_spec)			\
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 207,212 ****
--- 217,224 ----
  %{march=strongarm1100:-D__ARM_ARCH_4__} \
  %{march=xscale:-D__ARM_ARCH_5TE__} \
  %{march=xscale:-D__XSCALE__} \
+ %{march=armmaverick:-D__ARM_ARCH_4T__} \
+ %{march=armmaverick:-D__MAVERICK__} \
  %{march=armv2:-D__ARM_ARCH_2__} \
  %{march=armv2a:-D__ARM_ARCH_2__} \
  %{march=armv3:-D__ARM_ARCH_3__} \
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 246,251 ****
--- 258,265 ----
   %{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
   %{mcpu=xscale:-D__ARM_ARCH_5TE__} \
   %{mcpu=xscale:-D__XSCALE__} \
+  %{mcpu=armmaverick:-D__ARM_ARCH_4T__} \
+  %{mcpu=armmaverick:-D__MAVERICK__} \
   %{!mcpu*:%(cpp_cpu_arch_default)}} \
  "
  
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 365,370 ****
--- 379,387 ----
     destination is non-Thumb aware.  */
  #define THUMB_FLAG_CALLER_SUPER_INTERWORKING	(1 << 20)
  
+ /* Fix invalid Maverick instruction combinations by inserting NOPs.  */
+ #define MAVERICK_FIX_INVALID_INSNS	(1 << 21)
+ 
  #define TARGET_APCS_FRAME		(target_flags & ARM_FLAG_APCS_FRAME)
  #define TARGET_POKE_FUNCTION_NAME	(target_flags & ARM_FLAG_POKE)
  #define TARGET_FPE			(target_flags & ARM_FLAG_FPE)
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 375,380 ****
--- 392,399 ----
  #define TARGET_MMU_TRAPS		(target_flags & ARM_FLAG_MMU_TRAPS)
  #define TARGET_SOFT_FLOAT		(target_flags & ARM_FLAG_SOFT_FLOAT)
  #define TARGET_HARD_FLOAT		(! TARGET_SOFT_FLOAT)
+ #define TARGET_MAVERICK			(arm_is_maverick)
+ #define TARGET_ANY_HARD_FLOAT		(TARGET_HARD_FLOAT || TARGET_MAVERICK)
  #define TARGET_BIG_END			(target_flags & ARM_FLAG_BIG_END)
  #define TARGET_INTERWORK		(target_flags & ARM_FLAG_INTERWORK)
  #define TARGET_LITTLE_WORDS		(target_flags & ARM_FLAG_LITTLE_WORDS)
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 390,395 ****
--- 409,415 ----
  #define TARGET_BACKTRACE	        (leaf_function_p ()	      			\
  				         ? (target_flags & THUMB_FLAG_LEAF_BACKTRACE)	\
  				         : (target_flags & THUMB_FLAG_BACKTRACE))
+ #define TARGET_MAVERICK_FIX_INVALID_INSNS	(target_flags & MAVERICK_FIX_INVALID_INSNS)
  
  /* SUBTARGET_SWITCHES is used to add flags on a per-config basis.  */
  #ifndef SUBTARGET_SWITCHES
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 468,473 ****
--- 488,497 ----
     N_("Thumb: Assume function pointers may go to non-Thumb aware code") }, \
    {"no-caller-super-interworking", -THUMB_FLAG_CALLER_SUPER_INTERWORKING,  \
     "" },								   \
+   {"maverick-fix-invalid-insns", MAVERICK_FIX_INVALID_INSNS,		   \
+    N_("Maverick: Place NOPs to avoid invalid instruction combinations") },   \
+   {"no-maverick-fix-invalid-insns", -MAVERICK_FIX_INVALID_INSNS,		   \
+    N_("Maverick: Not place NOPs to avoid invalid instruction combinations") }, \
    SUBTARGET_SWITCHES							   \
    {"",				TARGET_DEFAULT, "" }			   \
  }
*************** enum floating_point_type
*** 517,523 ****
  {
    FP_HARD,
    FP_SOFT2,
!   FP_SOFT3
  };
  
  /* Recast the floating point class to be the floating point attribute.  */
--- 541,548 ----
  {
    FP_HARD,
    FP_SOFT2,
!   FP_SOFT3,
!   FP_MAVERICK
  };
  
  /* Recast the floating point class to be the floating point attribute.  */
*************** extern enum floating_point_type arm_fpu_
*** 535,540 ****
--- 560,570 ----
  #define FP_DEFAULT FP_SOFT2
  #endif
  
+ #if TARGET_CPU_DEFAULT == TARGET_CPU_armmaverick
+ #undef FP_DEFAULT
+ #define FP_DEFAULT FP_MAVERICK
+ #endif
+ 
  /* Nonzero if the processor has a fast multiply insn, and one that does
     a 64-bit multiply of two 32-bit values.  */
  extern int arm_fast_multiply;
*************** extern int thumb_code;
*** 557,562 ****
--- 587,595 ----
  /* Nonzero if this chip is a StrongARM.  */
  extern int arm_is_strong;
  
+ /* Nonzero if this chip is a Maverick variant.  */
+ extern int arm_is_maverick;
+ 
  /* Nonzero if this chip is an XScale.  */
  extern int arm_is_xscale;
  
*************** extern int arm_is_6_or_7;
*** 667,673 ****
  
  /* Define this if most significant word of doubles is the lowest numbered.
     This is always true, even when in little-endian mode.  */
! #define FLOAT_WORDS_BIG_ENDIAN 1
  
  #define UNITS_PER_WORD	4
  
--- 700,706 ----
  
  /* Define this if most significant word of doubles is the lowest numbered.
     This is always true, even when in little-endian mode.  */
! #define FLOAT_WORDS_BIG_ENDIAN (!TARGET_MAVERICK || WORDS_BIG_ENDIAN)
  
  #define UNITS_PER_WORD	4
  
*************** extern const char * structure_size_strin
*** 755,760 ****
--- 788,797 ----
  			elimination code won't get rid of sfp.  It tracks
  			fp exactly at all times.
  
+   	mvf0		maverick floating point result
+ 	mvf1-mvf3	maverick floating point scratch
+ 	mvf4-mvf15   S	maverick floating point variable.
+ 
     *: See CONDITIONAL_REGISTER_USAGE  */
  
  /* The stack backtrace structure is as follows:
*************** extern const char * structure_size_strin
*** 819,824 ****
--- 856,873 ----
  	   regno <= LAST_ARM_FP_REGNUM; ++regno)		\
  	fixed_regs[regno] = call_used_regs[regno] = 1;		\
      }								\
+   if (TARGET_MAVERICK)						\
+     {								\
+       for (regno = FIRST_ARM_FP_REGNUM;				\
+ 	   regno <= LAST_ARM_FP_REGNUM; ++ regno)		\
+ 	fixed_regs[regno] = call_used_regs[regno] = 1;		\
+       for (regno = FIRST_MAVERICK_FP_REGNUM;			\
+ 	   regno <= LAST_MAVERICK_FP_REGNUM; ++ regno)		\
+ 	{							\
+ 	  fixed_regs[regno] = 0;				\
+ 	  call_used_regs[regno] = regno < FIRST_MAVERICK_FP_REGNUM + 4; \
+ 	}							\
+     }								\
    if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)		\
      {								\
        fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;			\
*************** extern const char * structure_size_strin
*** 936,941 ****
--- 985,995 ----
  #define FIRST_ARM_FP_REGNUM 	16
  #define LAST_ARM_FP_REGNUM  	23
  
+ #define FIRST_MAVERICK_FP_REGNUM	27
+ #define LAST_MAVERICK_FP_REGNUM	42
+ #define IS_MAVERICK_REGNUM(REGNUM) \
+   (((REGNUM) >= FIRST_MAVERICK_FP_REGNUM) && ((REGNUM) <= LAST_MAVERICK_FP_REGNUM))
+ 
  /* Base register for access to local variables of the function.  */
  #define FRAME_POINTER_REGNUM	25
  
*************** extern const char * structure_size_strin
*** 943,949 ****
  #define ARG_POINTER_REGNUM	26
  
  /* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP.  */
! #define FIRST_PSEUDO_REGISTER	27
  
  /* Value should be nonzero if functions must have frame pointers.
     Zero means the frame pointer need not be set up (and parms may be accessed
--- 997,1003 ----
  #define ARG_POINTER_REGNUM	26
  
  /* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP.  */
! #define FIRST_PSEUDO_REGISTER	43
  
  /* Value should be nonzero if functions must have frame pointers.
     Zero means the frame pointer need not be set up (and parms may be accessed
*************** enum reg_class
*** 1009,1014 ****
--- 1063,1069 ----
  {
    NO_REGS,
    FPU_REGS,
+   MAVERICK_REGS,
    LO_REGS,
    STACK_REG,
    BASE_REGS,
*************** enum reg_class
*** 1026,1031 ****
--- 1081,1087 ----
  {			\
    "NO_REGS",		\
    "FPU_REGS",		\
+   "MAVERICK_REGS",	\
    "LO_REGS",		\
    "STACK_REG",		\
    "BASE_REGS",		\
*************** enum reg_class
*** 1042,1047 ****
--- 1098,1104 ----
  {					\
    { 0x0000000 }, /* NO_REGS  */		\
    { 0x0FF0000 }, /* FPU_REGS */		\
+   { 0xf8000000, 0x000007FF }, /* MAVERICK_REGS */	\
    { 0x00000FF }, /* LO_REGS */		\
    { 0x0002000 }, /* STACK_REG */	\
    { 0x00020FF }, /* BASE_REGS */	\
*************** enum reg_class
*** 1079,1084 ****
--- 1136,1142 ----
     ARM, but several more letters for the Thumb.  */
  #define REG_CLASS_FROM_LETTER(C)  	\
    (  (C) == 'f' ? FPU_REGS		\
+    : (C) == 'v' ? MAVERICK_REGS		\
     : (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS)	\
     : TARGET_ARM ? NO_REGS		\
     : (C) == 'h' ? HI_REGS		\
*************** enum reg_class
*** 1139,1144 ****
--- 1197,1203 ----
  
  #define EXTRA_CONSTRAINT_ARM(OP, C)					    \
    ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG :    \
+    (C) == 'T' ? maverick_memory_offset (OP) : 		    		    \
     (C) == 'R' ? (GET_CODE (OP) == MEM					    \
  		 && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF		    \
  		 && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) :		    \
*************** enum reg_class
*** 1187,1199 ****
     
  /* If we need to load shorts byte-at-a-time, then we need a scratch. */
  #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)		\
    (TARGET_ARM ?							\
     (((MODE) == HImode && ! arm_arch4 && TARGET_MMU_TRAPS	\
       && (GET_CODE (X) == MEM					\
  	 || ((GET_CODE (X) == REG || GET_CODE (X) == SUBREG)	\
  	     && true_regnum (X) == -1)))			\
      ? GENERAL_REGS : NO_REGS)					\
!    : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X))
  
  /* Try a machine-dependent way of reloading an illegitimate address
     operand.  If we find one, push the reload and jump to WIN.  This
--- 1246,1264 ----
     
  /* If we need to load shorts byte-at-a-time, then we need a scratch. */
  #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X)		\
+   /* Cannot load constants into Maverick registers.  */		\
+   ((TARGET_MAVERICK						\
+      && (CLASS) == MAVERICK_REGS					\
+      && (CONSTANT_P (X)						\
+ 	 || GET_CODE (X) == SYMBOL_REF))			\
+     ? GENERAL_REGS :						\
    (TARGET_ARM ?							\
     (((MODE) == HImode && ! arm_arch4 && TARGET_MMU_TRAPS	\
       && (GET_CODE (X) == MEM					\
  	 || ((GET_CODE (X) == REG || GET_CODE (X) == SUBREG)	\
  	     && true_regnum (X) == -1)))			\
      ? GENERAL_REGS : NO_REGS)					\
!    : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X)))
  
  /* Try a machine-dependent way of reloading an illegitimate address
     operand.  If we find one, push the reload and jump to WIN.  This
*************** enum reg_class
*** 1216,1221 ****
--- 1281,1289 ----
  									   \
  	  if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode))	   \
  	    low = ((val & 0xf) ^ 0x8) - 0x8;				   \
+ 	  else if (TARGET_MAVERICK)					   \
+ 	    /* Need to be careful, -256 is not a valid offset.  */	   \
+ 	    low = val >= 0 ? (val & 0xff) : -((-val) & 0xff);		   \
  	  else if (MODE == SImode					   \
  		   || (MODE == SFmode && TARGET_SOFT_FLOAT)		   \
  		   || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
*************** enum reg_class
*** 1288,1299 ****
     needed to represent mode MODE in a register of class CLASS.
     ARM regs are UNITS_PER_WORD bits while FPU regs can hold any FP mode */
  #define CLASS_MAX_NREGS(CLASS, MODE)  \
!   ((CLASS) == FPU_REGS ? 1 : ARM_NUM_REGS (MODE))
  
  /* Moves between FPU_REGS and GENERAL_REGS are two memory insns.  */
  #define REGISTER_MOVE_COST(MODE, FROM, TO)		\
    (TARGET_ARM ?						\
     ((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 :	\
      (FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2)	\
     :							\
     ((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2)
--- 1356,1379 ----
     needed to represent mode MODE in a register of class CLASS.
     ARM regs are UNITS_PER_WORD bits while FPU regs can hold any FP mode */
  #define CLASS_MAX_NREGS(CLASS, MODE)  \
!   ((CLASS) == FPU_REGS || (CLASS) == MAVERICK_REGS ? 1 : ARM_NUM_REGS (MODE))
! 
! /* If defined, gives a class of registers that cannot be used as the
!    operand of a SUBREG that changes the mode of the object illegally.  */
! 
! #define CLASS_CANNOT_CHANGE_MODE	MAVERICK_REGS
! 
! /* Define illegal mode changes for CLASS_CANNOT_CHANGE_MODE.  */
! 
! #define CLASS_CANNOT_CHANGE_MODE_P(FROM, TO) \
!   (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
  
  /* Moves between FPU_REGS and GENERAL_REGS are two memory insns.  */
  #define REGISTER_MOVE_COST(MODE, FROM, TO)		\
    (TARGET_ARM ?						\
     ((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 :	\
+     (FROM) == MAVERICK_REGS && (TO) != MAVERICK_REGS ? 20 :	\
+     (FROM) != MAVERICK_REGS && (TO) == MAVERICK_REGS ? 20 :	\
      (FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2)	\
     :							\
     ((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2)
*************** enum reg_class
*** 1346,1351 ****
--- 1426,1433 ----
  #define LIBCALL_VALUE(MODE)  \
    (TARGET_ARM && TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT \
     ? gen_rtx_REG (MODE, FIRST_ARM_FP_REGNUM) \
+    : TARGET_ARM && TARGET_MAVERICK && GET_MODE_CLASS (MODE) == MODE_FLOAT \
+    ? gen_rtx_REG (MODE, FIRST_MAVERICK_FP_REGNUM) 			\
     : gen_rtx_REG (MODE, ARG_REGISTER (1)))
  
  /* Define how to find the value returned by a function.
*************** enum reg_class
*** 1355,1364 ****
  #define FUNCTION_VALUE(VALTYPE, FUNC) \
    LIBCALL_VALUE (TYPE_MODE (VALTYPE))
  
! /* 1 if N is a possible register number for a function value.
!    On the ARM, only r0 and f0 can return results.  */
  #define FUNCTION_VALUE_REGNO_P(REGNO)  \
    ((REGNO) == ARG_REGISTER (1) \
     || (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT))
  
  /* How large values are returned */
--- 1437,1448 ----
  #define FUNCTION_VALUE(VALTYPE, FUNC) \
    LIBCALL_VALUE (TYPE_MODE (VALTYPE))
  
! /* 1 if N is a possible register number for a function value.  On the
!    ARM, only r0 and f0 can return results.  On a Maverick chip, mvf0 can
!    return results.  */
  #define FUNCTION_VALUE_REGNO_P(REGNO)  \
    ((REGNO) == ARG_REGISTER (1) \
+    || (TARGET_ARM && ((REGNO) == FIRST_MAVERICK_FP_REGNUM) && TARGET_MAVERICK)\
     || (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT))
  
  /* How large values are returned */
*************** typedef struct
*** 1947,1952 ****
--- 2031,2044 ----
  	      && (INTVAL (INDEX) & 3) == 0)				\
  	    goto LABEL;							\
  	}								\
+       else if (TARGET_MAVERICK						\
+ 	       && (GET_MODE_CLASS (MODE) == MODE_FLOAT			\
+ 		   || (MODE) == DImode))				\
+         {								\
+           if (code == CONST_INT && INTVAL (INDEX) < 255			\
+               && INTVAL (INDEX) > -255)					\
+             goto LABEL;							\
+         }								\
        else								\
  	{								\
  	  if (ARM_INDEX_REGISTER_RTX_P (INDEX)				\
*************** extern int making_const_table;
*** 2777,2782 ****
--- 2869,2877 ----
    {"multi_register_push", {PARALLEL}},					\
    {"cc_register", {REG}},						\
    {"logical_binary_operator", {AND, IOR, XOR}},				\
+   {"maverick_register_operand", {REG}},					\
+   {"maverick_fp_register", {REG}},					\
+   {"maverick_shift_const", {CONST_INT}},					\
    {"dominant_cc_register", {REG}},
  
  /* Define this if you have special predicates that know special things
Index: config/arm/arm-protos.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/arm-protos.h,v
retrieving revision 1.29
diff -c -p -r1.29 arm-protos.h
*** config/arm/arm-protos.h	3 Mar 2002 04:23:02 -0000	1.29
--- config/arm/arm-protos.h	15 Aug 2002 18:07:41 -0000
*************** extern void arm_pr_no_long_calls	PARAMS 
*** 204,207 ****
--- 204,215 ----
  extern void arm_pr_long_calls_off	PARAMS ((cpp_reader *));
  #endif
  
+ #if defined (RTX_CODE)
+ extern int maverick_fp_register		PARAMS ((rtx, enum machine_mode));
+ extern int maverick_general_operand	PARAMS ((rtx, enum machine_mode));
+ extern int maverick_register_operand	PARAMS ((rtx, enum machine_mode));
+ extern int maverick_shift_const		PARAMS ((rtx, enum machine_mode));
+ extern int maverick_memory_offset		PARAMS ((rtx));
+ #endif
+ 
  #endif /* ! GCC_ARM_PROTOS_H */
Index: config/arm/aout.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/aout.h,v
retrieving revision 1.26
diff -c -p -r1.26 aout.h
*** config/arm/aout.h	31 Jul 2002 02:13:28 -0000	1.26
--- config/arm/aout.h	15 Aug 2002 18:07:42 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 73,79 ****
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",  \
    "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc",  \
    "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",  \
!   "cc", "sfp", "afp"		   		   \
  }
  #endif
  
--- 73,82 ----
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",  \
    "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc",  \
    "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",  \
!   "cc", "sfp", "afp",		   		   \
!   "mv0", "mv1", "mv2", "mv3", "mv4", "mv5", "mv6", \
!   "mv7", "mv8", "mv9", "mv10", "mv11", "mv12",     \
!   "mv13", "mv14", "mv15"			   \
  }
  #endif
  
*************** Boston, MA 02111-1307, USA.  */
*** 98,104 ****
    {"r12", 12},	/* ip */			\
    {"r13", 13},	/* sp */			\
    {"r14", 14},	/* lr */			\
!   {"r15", 15}	/* pc */			\
  }
  #endif
  
--- 101,171 ----
    {"r12", 12},	/* ip */			\
    {"r13", 13},	/* sp */			\
    {"r14", 14},	/* lr */			\
!   {"r15", 15},	/* pc */			\
!   {"mvf0", 27},					\
!   {"mvf1", 28},					\
!   {"mvf2", 29},					\
!   {"mvf3", 30},					\
!   {"mvf4", 31},					\
!   {"mvf5", 32},					\
!   {"mvf6", 33},					\
!   {"mvf7", 34},					\
!   {"mvf8", 35},					\
!   {"mvf9", 36},					\
!   {"mvf10", 37},				\
!   {"mvf11", 38},				\
!   {"mvf12", 39},				\
!   {"mvf13", 40},				\
!   {"mvf14", 41},				\
!   {"mvf15", 42},				\
!   {"mvd0", 27},					\
!   {"mvd1", 28},					\
!   {"mvd2", 29},					\
!   {"mvd3", 30},					\
!   {"mvd4", 31},					\
!   {"mvd5", 32},					\
!   {"mvd6", 33},					\
!   {"mvd7", 34},					\
!   {"mvd8", 35},					\
!   {"mvd9", 36},					\
!   {"mvd10", 37},				\
!   {"mvd11", 38},				\
!   {"mvd12", 39},				\
!   {"mvd13", 40},				\
!   {"mvd14", 41},				\
!   {"mvd15", 42},				\
!   {"mvfx0", 27},				\
!   {"mvfx1", 28},				\
!   {"mvfx2", 29},				\
!   {"mvfx3", 30},				\
!   {"mvfx4", 31},				\
!   {"mvfx5", 32},				\
!   {"mvfx6", 33},				\
!   {"mvfx7", 34},				\
!   {"mvfx8", 35},				\
!   {"mvfx9", 36},				\
!   {"mvfx10", 37},				\
!   {"mvfx11", 38},				\
!   {"mvfx12", 39},				\
!   {"mvfx13", 40},				\
!   {"mvfx14", 41},				\
!   {"mvfx15", 42},				\
!   {"mvdx0", 27},				\
!   {"mvdx1", 28},				\
!   {"mvdx2", 29},				\
!   {"mvdx3", 30},				\
!   {"mvdx4", 31},				\
!   {"mvdx5", 32},				\
!   {"mvdx6", 33},				\
!   {"mvdx7", 34},				\
!   {"mvdx8", 35},				\
!   {"mvdx9", 36},				\
!   {"mvdx10", 37},				\
!   {"mvdx11", 38},				\
!   {"mvdx12", 39},				\
!   {"mvdx13", 40},				\
!   {"mvdx14", 41},				\
!   {"mvdx15", 42}				\
  }
  #endif
  
Index: config/arm/t-maverick-elf
===================================================================
RCS file: config/arm/t-maverick-elf
diff -N config/arm/t-maverick-elf
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- config/arm/t-maverick-elf	15 Aug 2002 18:07:42 -0000
***************
*** 0 ****
--- 1,41 ----
+ CROSS_LIBGCC1 = libgcc1-asm.a
+ LIB1ASMSRC = arm/lib1funcs.asm
+ LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func _call_via_rX _interwork_call_via_rX
+ 
+ # We want fine grained libraries, so use the new code to build the
+ # floating point emulation libraries.
+ FPBIT = fp-bit.c
+ DPBIT = dp-bit.c
+ 
+ fp-bit.c: $(srcdir)/config/fp-bit.c
+ 	echo '#define FLOAT' > fp-bit.c
+ 	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+ 
+ dp-bit.c: $(srcdir)/config/fp-bit.c
+ 	cat $(srcdir)/config/fp-bit.c > dp-bit.c
+ 
+ MULTILIB_OPTIONS     = mlittle-endian/mbig-endian
+ MULTILIB_DIRNAMES    = le be
+ MULTILIB_EXCEPTIONS  = 
+ MULTILIB_MATCHES     = mbig-endian=mbe mlittle-endian=mle
+ EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
+ 
+ # If EXTRA_MULTILIB_PARTS is not defined above then define EXTRA_PARTS here
+ # EXTRA_PARTS = crtbegin.o crtend.o crti.o crtn.o
+ # 
+ LIBGCC = stmp-multilib
+ INSTALL_LIBGCC = install-multilib
+ 
+ # Currently there is a bug somewhere in GCC's alias analysis
+ # or scheduling code that is breaking _fpmul_parts in libgcc1.c.
+ # Disabling function inlining is a workaround for this problem.
+ TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc -fno-inline
+ 
+ # Assemble startup files.
+ $(T)crti.o: $(srcdir)/config/arm/crti.asm $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+ 	-c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/arm/crti.asm
+ 
+ $(T)crtn.o: $(srcdir)/config/arm/crtn.asm $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
+ 	-c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/arm/crtn.asm
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/uberbaum/gcc/doc/invoke.texi,v
retrieving revision 1.170
diff -c -p -r1.170 invoke.texi
*** doc/invoke.texi	11 Aug 2002 09:47:47 -0000	1.170
--- doc/invoke.texi	15 Aug 2002 18:08:17 -0000
*************** in the following sections.
*** 395,400 ****
--- 395,401 ----
  -msingle-pic-base  -mno-single-pic-base @gol
  -mpic-register=@var{reg} @gol
  -mnop-fun-dllimport @gol
+ -mmaverick-fix-invalid-insns -mno-maverick-fix-invalid-insns @gol
  -mpoke-function-name @gol
  -mthumb  -marm @gol
  -mtpcs-frame  -mtpcs-leaf-frame @gol
*************** Allows calls via function pointers (incl
*** 5994,5999 ****
--- 5995,6008 ----
  execute correctly regardless of whether the target code has been
  compiled for interworking or not.  There is a small overhead in the cost
  of executing a function pointer if this option is enabled.
+ 
+ @item -mmaverick-fix-invalid-insns
+ @opindex mmaverick-fix-invalid-insns
+ Some combinations of Maverick instructions are invalid if they occur
+ in sequence.  If you use this option, GCC will insert nops in the
+ relevant places to avoid generating these sequences.  This option is
+ turned off by default and is only needed for revisions of Maverick
+ chips for which certain combinations are invalid.
  
  @end table
  
Index: config.gcc
===================================================================
RCS file: /cvs/uberbaum/gcc/config.gcc,v
retrieving revision 1.238
diff -c -p -r1.238 config.gcc
*** config.gcc	12 Aug 2002 03:40:15 -0000	1.238
--- config.gcc	15 Aug 2002 18:08:22 -0000
*************** alpha*-*-*)
*** 2838,2843 ****
--- 2838,2847 ----
  		fi
  	fi
  	;;
+ armmaverick-*-elf)
+ 	tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/ecos-elf.h"
+ 	tmake_file=arm/t-maverick-elf
+ 	;;
  arm*-*-*)
  	case "x$with_cpu" in
  		x)
*************** arm*-*-*)
*** 2854,2860 ****
  		| xstrongarm | xstrongarm110 | xstrongarm1100)
  			target_cpu_default2="TARGET_CPU_$with_cpu"
  			;;
! 
  		xyes | xno)
  			echo "--with-cpu must be passed a value" 1>&2
  			exit 1
--- 2858,2866 ----
  		| xstrongarm | xstrongarm110 | xstrongarm1100)
  			target_cpu_default2="TARGET_CPU_$with_cpu"
  			;;
! 		xarmmaverick)
! 			target_cpu_default2="TARGET_CPU_$with_cpu"
! 			;;
  		xyes | xno)
  			echo "--with-cpu must be passed a value" 1>&2
  			exit 1
*************** arm*-*-*)
*** 2866,2871 ****
--- 2872,2882 ----
  				echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2
  				exit 1
  			fi
+ 			;;
+ 	esac
+ 	case $machine in
+ 		armmaverick-*-*)
+ 			target_cpu_default2="TARGET_CPU_armmaverick"
  			;;
  	esac
  	;;

Index: config/arm/arm.md
===================================================================
RCS file: /cvs/uberbaum/gcc/config/arm/arm.md,v
retrieving revision 1.104
diff -p -F^( -r1.104 arm.md
*** config/arm/arm.md	29 Jul 2002 12:41:46 -0000	1.104
--- config/arm/arm.md	15 Aug 2002 18:09:30 -0000
*************** (define_attr "shift" "" (const_int 0))
*** 123,128 ****
--- 123,154 ----
  ; performance we should try and group them together).
  (define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr")))
  
+ (define_attr "maverick_fpu" "fpa,fpe2,fpe3,yes" (const (symbol_ref "arm_fpu_attr")))
+ 
+ ; Classification of each insn
+ ; farith	Floating point arithmetic (4 cycle)
+ ; dmult		Double multiplies (7 cycle)
+ (define_attr "maverick_type" "normal,farith,dmult" (const_string "normal"))
+ 
+ ; Maverick types for invalid insn combinations
+ ; no		Not a maverick insn
+ ; yes		Maverick insn
+ ; double	cfldrd, cfldr64, cfstrd, cfstr64
+ ; compare	cfcmps, cfcmpd, cfcmp32, cfcmp64
+ ; move		cfmvdlr, cfmvdhr, cfmvsr, cfmv64lr, cfmv64hr
+ (define_attr "maverick" "no,yes,double,compare,move" (const_string "no"))
+ 
+ (define_function_unit "maverick_fpa" 1 0
+   (and (eq_attr "maverick_fpu" "yes")
+        (eq_attr "maverick_type" "farith")) 4 1)
+ 
+ (define_function_unit "maverick_fpa" 1 0
+   (and (eq_attr "maverick_fpu" "yes")
+        (eq_attr "maverick_type" "dmult")) 7 4)
+ 
+ (define_function_unit "maverick_fpa" 1 0
+   (and (eq_attr "maverick_fpu" "yes")
+        (eq_attr "maverick_type" "normal")) 1 1)
  ; LENGTH of an instruction (in bytes)
  (define_attr "length" "" (const_int 4))
  
*************** (define_function_unit "core" 1 0
*** 400,405 ****
--- 426,433 ----
  ;; Note: For DImode insns, there is normally no reason why operands should
  ;; not be in the same register, what we don't want is for something being
  ;; written to partially overlap something that is an input.
+ ;; Maverick 64bit additions should not be split because we have a native
+ ;; 64bit addition instructions.
  
  (define_expand "adddi3"
   [(parallel
*************** (define_expand "adddi3"
*** 409,414 ****
--- 437,455 ----
      (clobber (reg:CC CC_REGNUM))])]
    "TARGET_EITHER"
    "
+ {
+   extern int maverick_fp_register (rtx, enum machine_mode);
+ 
+   if (TARGET_MAVERICK)
+     {
+       if (!maverick_fp_register (operands[0], DImode))
+         operands[0] = force_reg (DImode, operands[0]);
+       if (!maverick_fp_register (operands[1], DImode))
+         operands[1] = force_reg (DImode, operands[1]);
+       emit_insn (gen_maverick_adddi3 (operands[0], operands[1], operands[2]));
+       DONE;
+     }
+ }
    if (TARGET_THUMB)
      {
        if (GET_CODE (operands[1]) != REG)
*************** (define_expand "adddi3"
*** 419,424 ****
--- 460,475 ----
    "
  )
  
+ (define_insn "maverick_adddi3"
+   [(set (match_operand:DI          0 "maverick_fp_register" "=v")
+ 	(plus:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		 (match_operand:DI 2 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfadd64%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*thumb_adddi3"
    [(set (match_operand:DI          0 "register_operand" "=l")
  	(plus:DI (match_operand:DI 1 "register_operand" "%0")
*************** (define_insn_and_split "*arm_adddi3"
*** 435,441 ****
  	(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
  		 (match_operand:DI 2 "s_register_operand" "r,  0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
--- 486,492 ----
  	(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
  		 (match_operand:DI 2 "s_register_operand" "r,  0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM && !TARGET_MAVERICK"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
*************** (define_insn_and_split "*adddi_sesidi_di
*** 463,469 ****
  		  (match_operand:SI 2 "s_register_operand" "r,r"))
  		 (match_operand:DI 1 "s_register_operand" "r,0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
--- 514,520 ----
  		  (match_operand:SI 2 "s_register_operand" "r,r"))
  		 (match_operand:DI 1 "s_register_operand" "r,0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM && !TARGET_MAVERICK"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
*************** (define_insn_and_split "*adddi_zesidi_di
*** 492,498 ****
  		  (match_operand:SI 2 "s_register_operand" "r,r"))
  		 (match_operand:DI 1 "s_register_operand" "r,0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
--- 543,549 ----
  		  (match_operand:SI 2 "s_register_operand" "r,r"))
  		 (match_operand:DI 1 "s_register_operand" "r,0")))
     (clobber (reg:CC CC_REGNUM))]
!   "TARGET_ARM && !TARGET_MAVERICK"
    "#"
    "TARGET_ARM && reload_completed"
    [(parallel [(set (reg:CC_C CC_REGNUM)
*************** (define_insn_and_split "*arm_addsi3"
*** 568,573 ****
--- 619,634 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_addsi3"
+   [(set (match_operand:SI          0 "maverick_fp_register" "=v")
+ 	(plus:SI (match_operand:SI 1 "maverick_fp_register" "v")
+ 		 (match_operand:SI 2 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfadd32%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  ;; Register group 'k' is a single register group containing only the stack
  ;; register.  Trying to reload it will always fail catastrophically,
  ;; so never allow those alternatives to match if reloading is needed.
*************** (define_insn "incscc"
*** 795,801 ****
     (set_attr "length" "4,8")]
  )
  
! (define_insn "addsf3"
    [(set (match_operand:SF          0 "s_register_operand" "=f,f")
  	(plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
  		 (match_operand:SF 2 "fpu_add_operand"    "fG,H")))]
--- 856,874 ----
     (set_attr "length" "4,8")]
  )
  
! ;; define_insn replaced by define_expand and define_insn
! (define_expand "addsf3"
!   [(set (match_operand:SF          0 "s_register_operand" "")
! 	(plus:SF (match_operand:SF 1 "s_register_operand" "")
! 		 (match_operand:SF 2 "fpu_add_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK
!       && !maverick_fp_register (operands[2], SFmode))
!     operands[2] = force_reg (SFmode, operands[2]);
! ")
! 
! (define_insn "*arm_addsf3"
    [(set (match_operand:SF          0 "s_register_operand" "=f,f")
  	(plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
  		 (match_operand:SF 2 "fpu_add_operand"    "fG,H")))]
*************** (define_insn "addsf3"
*** 807,813 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "adddf3"
    [(set (match_operand:DF          0 "s_register_operand" "=f,f")
  	(plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
  		 (match_operand:DF 2 "fpu_add_operand"    "fG,H")))]
--- 880,908 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "*maverick_addsf3"
!   [(set (match_operand:SF          0 "maverick_fp_register" "=v")
! 	(plus:SF (match_operand:SF 1 "maverick_fp_register" "v")
! 		 (match_operand:SF 2 "maverick_fp_register" "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfadds%?\\t%V0, %V1, %V2"
!   [(set_attr "maverick_type" "farith")
!    (set_attr "maverick" "yes")]
! )
! 
! ;; define_insn replaced by define_expand and define_insn
! (define_expand "adddf3"
!   [(set (match_operand:DF          0 "s_register_operand" "")
! 	(plus:DF (match_operand:DF 1 "s_register_operand" "")
! 		 (match_operand:DF 2 "fpu_add_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK
!       && !maverick_fp_register (operands[2], DFmode))
!     operands[2] = force_reg (DFmode, operands[2]);
! ")
! 
! (define_insn "*arm_adddf3"
    [(set (match_operand:DF          0 "s_register_operand" "=f,f")
  	(plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
  		 (match_operand:DF 2 "fpu_add_operand"    "fG,H")))]
*************** (define_insn "adddf3"
*** 819,824 ****
--- 914,929 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_adddf3"
+   [(set (match_operand:DF          0 "maverick_fp_register" "=v")
+ 	(plus:DF (match_operand:DF 1 "maverick_fp_register" "v")
+ 		 (match_operand:DF 2 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfaddd%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*adddf_esfdf_df"
    [(set (match_operand:DF           0 "s_register_operand" "=f,f")
  	(plus:DF (float_extend:DF
*************** (define_expand "subdi3"
*** 875,880 ****
--- 980,997 ----
      (clobber (reg:CC CC_REGNUM))])]
    "TARGET_EITHER"
    "
+   {
+     extern int maverick_fp_register (rtx, enum machine_mode);
+ 
+     if (TARGET_MAVERICK
+         && TARGET_ARM
+ 	&& maverick_fp_register (operands[0], DImode)
+         && maverick_fp_register (operands[1], DImode))
+       {
+         emit_insn (gen_maverick_subdi3 (operands[0], operands[1], operands[2]));
+         DONE;
+       }
+   }
    if (TARGET_THUMB)
      {
        if (GET_CODE (operands[1]) != REG)
*************** (define_expand "subdi3"
*** 885,890 ****
--- 1002,1017 ----
    "
  )
  
+ (define_insn "maverick_subdi3"
+   [(set (match_operand:DI           0 "maverick_fp_register" "=v")
+ 	(minus:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		  (match_operand:DI 2 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsub64%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*arm_subdi3"
    [(set (match_operand:DI           0 "s_register_operand" "=&r,&r,&r")
  	(minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
*************** (define_insn_and_split "*arm_subsi3_insn
*** 1019,1024 ****
--- 1146,1160 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_subsi3_insn"
+   [(set (match_operand:SI           0 "maverick_fp_register" "=v")
+ 	(minus:SI (match_operand:SI 1 "maverick_fp_register" "v")
+ 		  (match_operand:SI 2 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsub32%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
  (define_peephole2
    [(match_scratch:SI 3 "r")
     (set (match_operand:SI           0 "s_register_operand" "")
*************** (define_insn "decscc"
*** 1060,1066 ****
     (set_attr "length" "*,8")]
  )
  
! (define_insn "subsf3"
    [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  	(minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  		  (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
--- 1196,1217 ----
     (set_attr "length" "*,8")]
  )
  
! (define_expand "subsf3"
!   [(set (match_operand:SF           0 "s_register_operand" "")
! 	(minus:SF (match_operand:SF 1 "fpu_rhs_operand" "")
! 		  (match_operand:SF 2 "fpu_rhs_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       if (!maverick_fp_register (operands[1], SFmode))
!         operands[1] = force_reg (SFmode, operands[1]);
!       if (!maverick_fp_register (operands[2], SFmode))
!         operands[2] = force_reg (SFmode, operands[2]);
!     }
! ")
! 
! (define_insn "*arm_subsf3"
    [(set (match_operand:SF 0 "s_register_operand" "=f,f")
  	(minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
  		  (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
*************** (define_insn "subsf3"
*** 1071,1077 ****
    [(set_attr "type" "farith")]
  )
  
! (define_insn "subdf3"
    [(set (match_operand:DF           0 "s_register_operand" "=f,f")
  	(minus:DF (match_operand:DF 1 "fpu_rhs_operand"     "f,G")
  		  (match_operand:DF 2 "fpu_rhs_operand"    "fG,f")))]
--- 1222,1253 ----
    [(set_attr "type" "farith")]
  )
  
! (define_insn "*maverick_subsf3"
!   [(set (match_operand:SF           0 "maverick_fp_register" "=v")
! 	(minus:SF (match_operand:SF 1 "maverick_fp_register"  "v")
! 		  (match_operand:SF 2 "maverick_fp_register"  "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfsubs%?\\t%V0, %V1, %V2"
!   [(set_attr "maverick_type" "farith")
!    (set_attr "maverick" "yes")]
! )
! 
! (define_expand "subdf3"
!   [(set (match_operand:DF           0 "s_register_operand" "")
! 	(minus:DF (match_operand:DF 1 "fpu_rhs_operand"     "")
! 		  (match_operand:DF 2 "fpu_rhs_operand"    "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!        if (!maverick_fp_register (operands[1], DFmode))
!          operands[1] = force_reg (DFmode, operands[1]);
!        if (!maverick_fp_register (operands[2], DFmode))
!          operands[2] = force_reg (DFmode, operands[2]);
!     }
! ")
! 
! (define_insn "*arm_subdf3"
    [(set (match_operand:DF           0 "s_register_operand" "=f,f")
  	(minus:DF (match_operand:DF 1 "fpu_rhs_operand"     "f,G")
  		  (match_operand:DF 2 "fpu_rhs_operand"    "fG,f")))]
*************** (define_insn "subdf3"
*** 1083,1088 ****
--- 1259,1274 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_subdf3"
+   [(set (match_operand:DF           0 "maverick_fp_register" "=v")
+ 	(minus:DF (match_operand:DF 1 "maverick_fp_register" "v")
+ 		  (match_operand:DF 2 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsubd%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*subdf_esfdf_df"
    [(set (match_operand:DF            0 "s_register_operand" "=f")
  	(minus:DF (float_extend:DF
*************** (define_insn "*arm_mulsi3"
*** 1152,1157 ****
--- 1338,1353 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_mulsi3"
+   [(set (match_operand:SI          0 "maverick_fp_register" "=v")
+ 	(mult:SI (match_operand:SI 2 "maverick_fp_register"  "v")
+ 		 (match_operand:SI 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfmul32%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  ; Unfortunately with the Thumb the '&'/'0' trick can fails when operands 
  ; 1 and 2; are the same, because reload will make operand 0 match 
  ; operand 1 without realizing that this conflicts with operand 2.  We fix 
*************** (define_insn "*mulsi_compare0_scratch"
*** 1199,1204 ****
--- 1395,1410 ----
     (set_attr "type" "mult")]
  )
  
+ (define_insn "muldi3"
+   [(set (match_operand:DI          0 "maverick_fp_register" "=v")
+ 	(mult:DI (match_operand:DI 2 "maverick_fp_register"  "v")
+ 		 (match_operand:DI 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfmul64%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "dmult")
+    (set_attr "maverick" "yes")]
+ )
+ 
  ;; Unnamed templates to match MLA instruction.
  
  (define_insn "*mulsi3addsi"
*************** (define_insn "*mulsi3addsi_compare0_scra
*** 1245,1250 ****
--- 1451,1481 ----
     (set_attr "type" "mult")]
  )
  
+ (define_insn "*maverick_mulsi3addsi"
+   [(set (match_operand:SI            0 "maverick_fp_register" "=v")
+ 	(plus:SI
+ 	  (mult:SI (match_operand:SI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "maverick_fp_register"  "v"))
+ 	  (match_operand:SI          3 "maverick_fp_register"  "0")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfmac32%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
+ ;; Maverick SI multiply-subtract
+ (define_insn "*maverick_mulsi3subsi"
+   [(set (match_operand:SI            0 "maverick_fp_register" "=v")
+ 	(minus:SI
+ 	  (match_operand:SI          1 "maverick_fp_register"  "0")
+ 	  (mult:SI (match_operand:SI 2 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 3 "maverick_fp_register"  "v"))))]
+   "0 && TARGET_ARM && TARGET_MAVERICK"
+   "cfmsc32%?\\t%V0, %V2, %V3"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "yes")]
+ )
+ 
  ;; Unnamed template to match long long multiply-accumlate (smlal)
  
  (define_insn "*mulsidi3adddi"
*************** (define_insn "*mulhidi3adddi"
*** 1362,1368 ****
    "smlalbb%?\\t%Q0, %R0, %2, %3"
  [(set_attr "type" "mult")])
  
! (define_insn "mulsf3"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(mult:SF (match_operand:SF 1 "s_register_operand" "f")
  		 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
--- 1593,1610 ----
    "smlalbb%?\\t%Q0, %R0, %2, %3"
  [(set_attr "type" "mult")])
  
! (define_expand "mulsf3"
!   [(set (match_operand:SF          0 "s_register_operand" "")
! 	(mult:SF (match_operand:SF 1 "s_register_operand" "")
! 		 (match_operand:SF 2 "fpu_rhs_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK
!       && !maverick_fp_register (operands[2], SFmode))
!     operands[2] = force_reg (SFmode, operands[2]);
! ")
! 
! (define_insn "*arm_mulsf3"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(mult:SF (match_operand:SF 1 "s_register_operand" "f")
  		 (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
*************** (define_insn "mulsf3"
*** 1372,1378 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "muldf3"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(mult:DF (match_operand:DF 1 "s_register_operand" "f")
  		 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
--- 1614,1641 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "*maverick_mulsf3"
!   [(set (match_operand:SF          0 "maverick_fp_register" "=v")
! 	(mult:SF (match_operand:SF 1 "maverick_fp_register"  "v")
! 		 (match_operand:SF 2 "maverick_fp_register"  "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfmuls%?\\t%V0, %V1, %V2"
!   [(set_attr "maverick_type" "farith")
!    (set_attr "maverick" "yes")]
! )
! 
! (define_expand "muldf3"
!   [(set (match_operand:DF          0 "s_register_operand" "")
! 	(mult:DF (match_operand:DF 1 "s_register_operand" "")
! 		 (match_operand:DF 2 "fpu_rhs_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK
!       && !maverick_fp_register (operands[2], DFmode))
!     operands[2] = force_reg (DFmode, operands[2]);
! ")
! 
! (define_insn "*arm_muldf3"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(mult:DF (match_operand:DF 1 "s_register_operand" "f")
  		 (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
*************** (define_insn "muldf3"
*** 1382,1387 ****
--- 1645,1660 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_muldf3"
+   [(set (match_operand:DF          0 "maverick_fp_register" "=v")
+ 	(mult:DF (match_operand:DF 1 "maverick_fp_register"  "v")
+ 		 (match_operand:DF 2 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfmuld%?\\t%V0, %V1, %V2"
+   [(set_attr "maverick_type" "dmult")
+    (set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*muldf_esfdf_df"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(mult:DF (float_extend:DF
*************** (define_insn "*thumb_rotrsi3"
*** 2590,2595 ****
--- 2863,2935 ----
    [(set_attr "length" "2")]
  )
  
+ (define_expand "ashldi3"
+   [(set (match_operand:DI            0 "s_register_operand" "")
+ 	(ashift:DI (match_operand:DI 1 "general_operand" "")
+ 		   (match_operand:SI 2 "general_operand" "")))]
+   "TARGET_ARM && (0 || TARGET_MAVERICK)"
+   "
+   if (! s_register_operand (operands[1], DImode))
+     operands[1] = copy_to_mode_reg (DImode, operands[1]);
+   if (! s_register_operand (operands[2], SImode))
+     operands[2] = copy_to_mode_reg (SImode, operands[2]);
+   "
+ )
+ 
+ (define_insn "maverick_ashl_const"
+   [(set (match_operand:SI            0 "maverick_fp_register" "=v")
+ 	(ashift:SI (match_operand:SI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "maverick_shift_const"  "")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsh32%?\\t%V0, %V1, #%s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "maverick_ashiftrt_const"
+   [(set (match_operand:SI	       0 "maverick_fp_register" "=v")
+ 	(ashiftrt:SI (match_operand:SI 1 "maverick_fp_register"  "v")
+ 		     (match_operand:SI 2 "maverick_shift_const"  "")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsh32%?\\t%V0, %V1, #-%s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "maverick_ashlsi3"
+   [(set (match_operand:SI            0 "maverick_fp_register" "=v")
+ 	(ashift:SI (match_operand:SI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "register_operand"    "r")))]
+   "TARGET_ARM && TARGET_MAVERICK "
+   "cfrshl32%?\\t%V1, %V0, %s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "ashldi3_maverick"
+   [(set (match_operand:DI            0 "maverick_fp_register" "=v")
+ 	(ashift:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "register_operand"    "r")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfrshl64%?\\t%V1, %V0, %s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "maverick_ashldi_const"
+   [(set (match_operand:DI            0 "maverick_fp_register" "=v")
+ 	(ashift:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		   (match_operand:SI 2 "maverick_shift_const"  "")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsh64%?\\t%V0, %V1, #%s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
+ (define_insn "maverick_ashiftrtdi_const"
+   [(set (match_operand:DI            0 "maverick_fp_register" "=v")
+ 	(ashiftrt:DI (match_operand:DI 1 "maverick_fp_register"  "v")
+ 		     (match_operand:SI 2 "maverick_shift_const"  "")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfsh64%?\\t%V0, %V1, #-%s2"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*arm_shiftsi3"
    [(set (match_operand:SI   0 "s_register_operand" "=r")
  	(match_operator:SI  3 "shift_operator"
*************** (define_expand "extzv"
*** 2704,2709 ****
--- 3044,3057 ----
  \f
  ;; Unary arithmetic insns
  
+ (define_insn "*maverick_absdi2"
+   [(set (match_operand:DI         0 "maverick_fp_register" "=v")
+ 	(abs:DI (match_operand:DI 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfabs64%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_expand "negdi2"
   [(parallel
     [(set (match_operand:DI          0 "s_register_operand" "")
*************** (define_expand "negdi2"
*** 2719,2724 ****
--- 3067,3081 ----
    "
  )
  
+ (define_insn "*maverick_negdi2"
+   [(set (match_operand:DI         0 "maverick_fp_register" "=v")
+ 	(neg:DI (match_operand:DI 1 "maverick_fp_register"  "v")))
+    (clobber (reg:CC 24))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfneg64%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
  ;; The second alternative is to allow the common case of a *full* overlap.
  (define_insn "*arm_negdi2"
*************** (define_insn "*arm_negsi2"
*** 2755,2760 ****
--- 3112,3125 ----
    [(set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_negsi2"
+   [(set (match_operand:SI         0 "maverick_fp_register" "=v")
+ 	(neg:SI (match_operand:SI 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK "
+   "cfneg32%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*thumb_negsi2"
    [(set (match_operand:SI         0 "register_operand" "=l")
  	(neg:SI (match_operand:SI 1 "register_operand" "l")))]
*************** (define_insn "*thumb_negsi2"
*** 2763,2769 ****
    [(set_attr "length" "2")]
  )
  
! (define_insn "negsf2"
    [(set (match_operand:SF         0 "s_register_operand" "=f")
  	(neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3128,3141 ----
    [(set_attr "length" "2")]
  )
  
! (define_expand "negsf2"
!   [(set (match_operand:SF         0 "s_register_operand" "")
! 	(neg:SF (match_operand:SF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   ""
! )
! 
! (define_insn "*arm_negsf2"
    [(set (match_operand:SF         0 "s_register_operand" "=f")
  	(neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
*************** (define_insn "negsf2"
*** 2772,2778 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "negdf2"
    [(set (match_operand:DF         0 "s_register_operand" "=f")
  	(neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3144,3164 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "*maverick_negsf2"
!   [(set (match_operand:SF         0 "maverick_fp_register" "=v")
! 	(neg:SF (match_operand:SF 1 "maverick_fp_register"  "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfnegs%?\\t%V0, %V1"
!   [(set_attr "maverick" "yes")]
! )
! 
! (define_expand "negdf2"
!   [(set (match_operand:DF         0 "s_register_operand" "")
! 	(neg:DF (match_operand:DF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "")
! 
! (define_insn "*arm_negdf2"
    [(set (match_operand:DF         0 "s_register_operand" "=f")
  	(neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
*************** (define_insn "negdf2"
*** 2781,2786 ****
--- 3167,3180 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_negdf2"
+   [(set (match_operand:DF         0 "maverick_fp_register" "=v")
+ 	(neg:DF (match_operand:DF 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfnegd%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*negdf_esfdf"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(neg:DF (float_extend:DF
*************** (define_insn "negxf2"
*** 2805,2811 ****
  ;; it does, but tell the final scan operator the truth.  Similarly for
  ;; (neg (abs...))
  
! (define_insn "abssi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r,&r")
  	(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
     (clobber (reg:CC CC_REGNUM))]
--- 3199,3213 ----
  ;; it does, but tell the final scan operator the truth.  Similarly for
  ;; (neg (abs...))
  
! (define_expand "abssi2"
!   [(parallel
!     [(set (match_operand:SI         0 "s_register_operand" "")
! 	  (abs:SI (match_operand:SI 1 "s_register_operand" "")))
!      (clobber (reg:CC 24))])]
!   "TARGET_ARM"
!   "")
! 
! (define_insn "*arm_abssi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r,&r")
  	(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
     (clobber (reg:CC CC_REGNUM))]
*************** (define_insn "abssi2"
*** 2819,2824 ****
--- 3221,3235 ----
     (set_attr "length" "8")]
  )
  
+ (define_insn "*maverick_abssi2"
+   [(set (match_operand:SI         0 "maverick_fp_register" "=v")
+         (abs:SI (match_operand:SI 1 "maverick_fp_register"  "v")))
+    (clobber (reg:CC 24))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfabs32%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*neg_abssi2"
    [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
  	(neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
*************** (define_insn "*neg_abssi2"
*** 2833,2839 ****
     (set_attr "length" "8")]
  )
  
! (define_insn "abssf2"
    [(set (match_operand:SF          0 "s_register_operand" "=f")
  	 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3244,3256 ----
     (set_attr "length" "8")]
  )
  
! (define_expand "abssf2"
!   [(set (match_operand:SF         0 "s_register_operand" "")
! 	(abs:SF (match_operand:SF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "")
! 
! (define_insn "*arm_abssf2"
    [(set (match_operand:SF          0 "s_register_operand" "=f")
  	 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
*************** (define_insn "abssf2"
*** 2842,2848 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "absdf2"
    [(set (match_operand:DF         0 "s_register_operand" "=f")
  	(abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3259,3279 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "*maverick_abssf2"
!   [(set (match_operand:SF         0 "maverick_fp_register" "=v")
!         (abs:SF (match_operand:SF 1 "maverick_fp_register"  "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfabss%?\\t%V0, %V1"
!   [(set_attr "maverick" "yes")]
! )
! 
! (define_expand "absdf2"
!   [(set (match_operand:DF         0 "s_register_operand" "")
! 	(abs:DF (match_operand:DF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "")
! 
! (define_insn "*arm_absdf2"
    [(set (match_operand:DF         0 "s_register_operand" "=f")
  	(abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
*************** (define_insn "absdf2"
*** 2851,2856 ****
--- 3282,3295 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_absdf2"
+   [(set (match_operand:DF         0 "maverick_fp_register" "=v")
+         (abs:DF (match_operand:DF 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfabsd%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "*absdf_esfdf"
    [(set (match_operand:DF 0 "s_register_operand" "=f")
  	(abs:DF (float_extend:DF
*************** (define_insn "*notsi_compare0_scratch"
*** 3040,3046 ****
  \f
  ;; Fixed <--> Floating conversion insns
  
! (define_insn "floatsisf2"
    [(set (match_operand:SF           0 "s_register_operand" "=f")
  	(float:SF (match_operand:SI 1 "s_register_operand" "r")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3479,3497 ----
  \f
  ;; Fixed <--> Floating conversion insns
  
! (define_expand "floatsisf2"
!   [(set (match_operand:SF           0 "s_register_operand" "")
! 	(float:SF (match_operand:SI 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       emit_insn (gen_maverick_floatsisf2 (operands[0], operands[1]));
!       DONE;
!     }
! ")
! 
! (define_insn "*arm_floatsisf2"
    [(set (match_operand:SF           0 "s_register_operand" "=f")
  	(float:SF (match_operand:SI 1 "s_register_operand" "r")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
*************** (define_insn "floatsisf2"
*** 3049,3055 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "floatsidf2"
    [(set (match_operand:DF           0 "s_register_operand" "=f")
  	(float:DF (match_operand:SI 1 "s_register_operand" "r")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3500,3553 ----
     (set_attr "predicable" "yes")]
  )
  
! ;; Convert Maverick-SI to Maverick-SF
! (define_insn "maverick_floatsisf2"
!   [(set (match_operand:SF           0 "maverick_fp_register" "=v")
!  	(float:SF (match_operand:SI 1 "s_register_operand"  "r")))
!    (clobber (match_scratch:DF 2 "=v"))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfmv64lr%?\\t%Z2, %1\;cfcvt32s%?\\t%V0, %Y2"
!   [(set_attr "length" "8")
!    (set_attr "maverick" "move")]
! )
! 
! (define_expand "floatsidf2"
!   [(set (match_operand:DF           0 "s_register_operand" "")
! 	(float:DF (match_operand:SI 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       emit_insn (gen_maverick_floatsidf2 (operands[0], operands[1]));
!       DONE;
!     }
! ")
! 
! (define_insn "maverick_floatsidf2"
!   [(set (match_operand:DF           0 "maverick_fp_register" "=v")
! 	(float:DF (match_operand:SI 1 "s_register_operand" "r")))
!    (clobber (match_scratch:DF 2 "=v"))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfmv64lr%?\\t%Z2, %1\;cfcvt32d%?\\t%V0, %Y2"
!   [(set_attr "length" "8")
!    (set_attr "maverick" "move")]
! )
! 
! (define_insn "floatdisf2"
!   [(set (match_operand:SF           0 "maverick_fp_register" "=v")
! 	(float:SF (match_operand:DI 1 "maverick_fp_register" "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfcvt64s%?\\t%V0, %V1"
!   [(set_attr "maverick" "yes")])
! 
! (define_insn "floatdidf2"
!   [(set (match_operand:DF 0 "maverick_fp_register" "=v")
! 	(float:DF (match_operand:DI 1 "maverick_fp_register" "v")))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cfcvt64d%?\\t%V0, %V1"
!   [(set_attr "maverick" "yes")])
! 
! (define_insn "*arm_floatsidf2"
    [(set (match_operand:DF           0 "s_register_operand" "=f")
  	(float:DF (match_operand:SI 1 "s_register_operand" "r")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
*************** (define_insn "floatsixf2"
*** 3067,3073 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "fix_truncsfsi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r")
  	(fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3565,3597 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_expand "fix_truncsfsi2"
!   [(set (match_operand:SI         0 "s_register_operand" "")
! 	(fix:SI (match_operand:SF 1 "s_register_operand"  "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       if (!maverick_fp_register (operands[0], SImode))
!         operands[0] = force_reg (SImode, operands[0]);
!       if (!maverick_fp_register (operands[1], SFmode))
!         operands[1] = force_reg (SFmode, operands[0]);
!       emit_insn (gen_maverick_truncsfsi2 (operands[0], operands[1]));
!       DONE;
!     }
! ")
! 
! (define_insn "maverick_truncsfsi2"
!   [(set (match_operand:SI         0 "s_register_operand" "=r")
! 	(fix:SI (match_operand:SF 1 "maverick_fp_register"  "v")))
!    (clobber (match_scratch:DF     2                      "=v"))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cftruncs32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
!   [(set_attr "length" "8")
!    (set_attr "maverick" "yes")]
! )
! 
! (define_insn "*arm_fix_truncsfsi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r")
  	(fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
*************** (define_insn "fix_truncsfsi2"
*** 3076,3082 ****
     (set_attr "predicable" "yes")]
  )
  
! (define_insn "fix_truncdfsi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r")
  	(fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 3600,3629 ----
     (set_attr "predicable" "yes")]
  )
  
! (define_expand "fix_truncdfsi2"
!   [(set (match_operand:SI         0 "s_register_operand" "")
! 	(fix:SI (match_operand:DF 1 "s_register_operand"  "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   "
!   if (TARGET_MAVERICK)
!     {
!       if (!maverick_fp_register (operands[1], DFmode))
!         operands[1] = force_reg (DFmode, operands[0]);
!       emit_insn (gen_maverick_truncdfsi2 (operands[0], operands[1]));
!       DONE;
!     }
! ")
! 
! (define_insn "maverick_truncdfsi2"
!   [(set (match_operand:SI         0 "s_register_operand" "=r")
! 	(fix:SI (match_operand:DF 1 "maverick_fp_register"  "v")))
!    (clobber (match_scratch:DF     2                      "=v"))]
!   "TARGET_ARM && TARGET_MAVERICK"
!   "cftruncd32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
!   [(set_attr "length" "8")]
! )
! 
! (define_insn "*arm_fix_truncdfsi2"
    [(set (match_operand:SI         0 "s_register_operand" "=r")
  	(fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
*************** (define_insn "fix_truncxfsi2"
*** 3096,3102 ****
  
  ;; Truncation insns
  
! (define_insn "truncdfsf2"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(float_truncate:SF
  	 (match_operand:DF 1 "s_register_operand" "f")))]
--- 3643,3657 ----
  
  ;; Truncation insns
  
! (define_expand "truncdfsf2"
!   [(set (match_operand:SF  0 "s_register_operand" "")
! 	(float_truncate:SF
!  	 (match_operand:DF 1 "s_register_operand" "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   ""
! )
! 
! (define_insn "*arm_truncdfsf2"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(float_truncate:SF
  	 (match_operand:DF 1 "s_register_operand" "f")))]
*************** (define_insn "truncdfsf2"
*** 3106,3111 ****
--- 3661,3675 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_truncdfsf2"
+   [(set (match_operand:SF  0 "maverick_fp_register" "=v")
+         (float_truncate:SF
+          (match_operand:DF 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcvtds%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "truncxfsf2"
    [(set (match_operand:SF 0 "s_register_operand" "=f")
  	(float_truncate:SF
*************** (define_insn "*thumb_extendqisi2_insn"
*** 3848,3854 ****
     (set_attr "pool_range" "32,32")]
  )
  
! (define_insn "extendsfdf2"
    [(set (match_operand:DF                  0 "s_register_operand" "=f")
  	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
--- 4412,4425 ----
     (set_attr "pool_range" "32,32")]
  )
  
! (define_expand "extendsfdf2"
!   [(set (match_operand:DF                  0 "s_register_operand" "")
! 	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "")))]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
!   ""
! )
! 
! (define_insn "*arm_extendsfdf2"
    [(set (match_operand:DF                  0 "s_register_operand" "=f")
  	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "f")))]
    "TARGET_ARM && TARGET_HARD_FLOAT"
*************** (define_insn "extendsfdf2"
*** 3857,3862 ****
--- 4428,4441 ----
     (set_attr "predicable" "yes")]
  )
  
+ (define_insn "*maverick_extendsfdf2"
+   [(set (match_operand:DF                  0 "maverick_fp_register" "=v")
+         (float_extend:DF (match_operand:SF 1 "maverick_fp_register"  "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcvtsd%?\\t%V0, %V1"
+   [(set_attr "maverick" "yes")]
+ )
+ 
  (define_insn "extendsfxf2"
    [(set (match_operand:XF 0 "s_register_operand" "=f")
  	(float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
*************** (define_expand "movdi"
*** 3953,3962 ****
    "
  )
  
  (define_insn "*arm_movdi"
    [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
  	(match_operand:DI 1 "di_operand"              "rIK,mi,r"))]
!   "TARGET_ARM"
    "*
    return (output_move_double (operands));
    "
--- 4532,4573 ----
    "
  )
  
+ (define_insn "*maverick_arm_movdi"
+   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,o<>,v,r,v,m,v")
+ 	(match_operand:DI 1 "di_operand"              "rIK,mi,r,r,v,m,v,v"))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "*
+   {
+   switch (which_alternative)
+     {
+     case 0:
+     case 1:
+     case 2:
+       return (output_move_double (operands));
+ 
+     case 3: return \"cfmv64lr%?\\t%V0, %Q1\;cfmv64hr%?\\t%V0, %R1\";
+     case 4: return \"cfmvr64l%?\\t%Q0, %V1\;cfmvr64h%?\\t%R0, %V1\";
+ 
+     case 5: return \"cfldr64%?\\t%V0, %1\";
+     case 6: return \"cfstr64%?\\t%V1, %0\";
+ 
+     /* Shifting by 0 will just copy %1 into %0.  */
+     case 7: return \"cfsh64%?\\t%V0, %V1, #0\";
+ 
+     default: abort ();
+     }
+   }"
+   [(set_attr "length" "8,8,8,8,8,4,4,4")
+    (set_attr "type" "*,load,store2,*,*,load,store2,*")
+    (set_attr "pool_range" "*,1020,*,*,*,*,*,*")
+    (set_attr "neg_pool_range" "*,1012,*,*,*,*,*,*")
+    (set_attr "maverick" "no,no,no,move,yes,double,double,yes")]
+ )
+ 
  (define_insn "*arm_movdi"
    [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
  	(match_operand:DI 1 "di_operand"              "rIK,mi,r"))]
!   "TARGET_ARM && !TARGET_MAVERICK"
    "*
    return (output_move_double (operands));
    "
*************** (define_insn "*thumb_movdi_insn"
*** 3974,3979 ****
--- 4585,4591 ----
    [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
  	(match_operand:DI 1 "general_operand"      "l, I,J,>,l,mi,l,*r"))]
    "TARGET_THUMB
+    && !TARGET_MAVERICK
     && (   register_operand (operands[0], DImode)
         || register_operand (operands[1], DImode))"
    "*
*************** (define_expand "movsi"
*** 4051,4056 ****
--- 4663,4693 ----
    "
  )
  
+ ;; Maverick SI values have been outlawed.  Look in arm.h for the comment
+ ;; on HARD_REGNO_MODE_OK.
+ 
+ (define_insn "*maverick_arm_movsi_insn"
+   [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,*v,r,*v,T,*v")
+         (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,*v,T,*v,*v"))]
+   "TARGET_ARM && TARGET_MAVERICK 
+    && (register_operand (operands[0], SImode)
+        || register_operand (operands[1], SImode))"
+   "@
+    mov%?\\t%0, %1
+    mvn%?\\t%0, #%B1
+    ldr%?\\t%0, %1
+    str%?\\t%1, %0
+    cfmv64lr%?\\t%Z0, %1
+    cfmvr64l%?\\t%0, %Z1
+    cfldr32%?\\t%V0, %1
+    cfstr32%?\\t%V1, %0
+    cfsh32%?\\t%V0, %V1, #0"
+   [(set_attr "type" "*,*,load,store1,*,*,load,store1,*")
+    (set_attr "pool_range" "*,*,4096,*,*,*,1024,*,*")
+    (set_attr "neg_pool_range" "*,*,4084,*,*,*,1012,*,*")
+    (set_attr "maverick" "no,no,no,no,move,yes,yes,yes,yes")]
+ )
+ 
  (define_insn "*arm_movsi_insn"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
  	(match_operand:SI 1 "general_operand"      "rI,K,mi,r"))]
*************** (define_expand "movhi"
*** 4417,4430 ****
  	      emit_insn (gen_movsi (reg, GEN_INT (val)));
  	      operands[1] = gen_lowpart (HImode, reg);
  	    }
! 	  else if (arm_arch4 && !no_new_pseudos && optimize > 0
! 		   && GET_CODE (operands[1]) == MEM)
! 	    {
! 	      rtx reg = gen_reg_rtx (SImode);
  
! 	      emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
! 	      operands[1] = gen_lowpart (HImode, reg);
! 	    }
            else if (!arm_arch4)
  	    {
  	     /* Note: We do not have to worry about TARGET_MMU_TRAPS
--- 5054,5067 ----
  	      emit_insn (gen_movsi (reg, GEN_INT (val)));
  	      operands[1] = gen_lowpart (HImode, reg);
  	    }
!         else if (arm_arch4 && !no_new_pseudos && optimize > 0
!                  && GET_CODE (operands[1]) == MEM)
!           {
!             rtx reg = gen_reg_rtx (SImode);
  
!             emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
!             operands[1] = gen_lowpart (HImode, reg);
!           }
            else if (!arm_arch4)
  	    {
  	     /* Note: We do not have to worry about TARGET_MMU_TRAPS
*************** (define_insn "*arm_movsf_hard_insn"
*** 4974,4979 ****
--- 5611,5638 ----
     (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
  )
  
+ (define_insn "*maverick_movsf_hard_insn"
+   [(set (match_operand:SF 0 "nonimmediate_operand" "=v,v,v,r,m,r,r,m")
+         (match_operand:SF 1 "general_operand"       "v,m,r,v,v,r,mE,r"))]
+   "TARGET_ARM && TARGET_MAVERICK
+    && (GET_CODE (operands[0]) != MEM
+        || register_operand (operands[1], SFmode))"
+   "@
+    cfcpys%?\\t%V0, %V1
+    cfldrs%?\\t%V0, %1
+    cfmvsr%?\\t%V0, %1
+    cfmvrs%?\\t%0, %V1
+    cfstrs%?\\t%V1, %0
+    mov%?\\t%0, %1
+    ldr%?\\t%0, %1\\t%@ float
+    str%?\\t%1, %0\\t%@ float"
+   [(set_attr "length" "*,*,*,*,*,4,4,4")
+    (set_attr "type" "*,load,*,*,store1,*,load,store1")
+    (set_attr "pool_range" "*,*,*,*,*,*,4096,*")
+    (set_attr "neg_pool_range" "*,*,*,*,*,*,4084,*")
+    (set_attr "maverick" "yes,yes,move,yes,yes,no,no,no")]
+ )
+ 
  ;; Exactly the same as above, except that all `f' cases are deleted.
  ;; This is necessary to prevent reload from ever trying to use a `f' reg
  ;; when -msoft-float.
*************** (define_insn "*arm_movsf_soft_insn"
*** 4982,4987 ****
--- 5641,5647 ----
    [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
  	(match_operand:SF 1 "general_operand"  "r,mE,r"))]
    "TARGET_ARM
+    && !TARGET_MAVERICK
     && TARGET_SOFT_FLOAT
     && (GET_CODE (operands[0]) != MEM
         || register_operand (operands[1], SFmode))"
*************** (define_expand "reload_outdf"
*** 5080,5085 ****
--- 5740,5773 ----
    }"
  )
  
+ (define_insn "*maverick_movdf_hard_insn"
+   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Q,r,m,r,v,v,v,r,m")
+ 	(match_operand:DF 1 "general_operand"       "Q,r,r,r,mF,v,m,r,v,v"))]
+   "TARGET_ARM
+    && TARGET_MAVERICK
+    && (GET_CODE (operands[0]) != MEM
+        || register_operand (operands[1], DFmode))"
+   "*
+   {
+   switch (which_alternative)
+     {
+     case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
+     case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
+     case 2: case 3: case 4: return output_move_double (operands);
+     case 5: return \"cfcpyd%?\\t%V0, %V1\";
+     case 6: return \"cfldrd%?\\t%V0, %1\";
+     case 7: return \"cfmvdlr\\t%V0, %Q1\;cfmvdhr%?\\t%V0, %R1\";
+     case 8: return \"cfmvrdl%?\\t%Q0, %V1\;cfmvrdh%?\\t%R0, %V1\";
+     case 9: return \"cfstrd%?\\t%V1, %0\";
+     default: abort ();
+     }
+   }"
+   [(set_attr "type" "load,store2,*,store2,load,*,load,*,*,store2")
+    (set_attr "length" "4,4,8,8,8,4,4,8,8,4")
+    (set_attr "pool_range" "*,*,*,*,252,*,*,*,*,*")
+    (set_attr "neg_pool_range" "*,*,*,*,244,*,*,*,*,*")
+    (set_attr "maverick" "no,no,no,no,no,yes,double,move,yes,double")]
+ )
  (define_insn "*movdf_hard_insn"
    [(set (match_operand:DF 0 "nonimmediate_operand"
  						"=r,Q,r,m,r, f, f,f, m,!f,!r")
*************** (define_insn "*movdf_soft_insn"
*** 5122,5127 ****
--- 5810,5816 ----
    [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
  	(match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
    "TARGET_ARM && TARGET_SOFT_FLOAT
+    && !TARGET_MAVERICK
    "
    "* return output_move_double (operands);"
    [(set_attr "length" "8,8,8")
*************** (define_expand "cmpsi"
*** 5631,5638 ****
  (define_expand "cmpsf"
    [(match_operand:SF 0 "s_register_operand" "")
     (match_operand:SF 1 "fpu_rhs_operand" "")]
!   "TARGET_ARM && TARGET_HARD_FLOAT"
    "
    arm_compare_op0 = operands[0];
    arm_compare_op1 = operands[1];
    DONE;
--- 6320,6330 ----
  (define_expand "cmpsf"
    [(match_operand:SF 0 "s_register_operand" "")
     (match_operand:SF 1 "fpu_rhs_operand" "")]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
    "
+   if (TARGET_MAVERICK && !maverick_fp_register (operands[1], SFmode))
+     operands[1] = force_reg (SFmode, operands[1]);
+ 
    arm_compare_op0 = operands[0];
    arm_compare_op1 = operands[1];
    DONE;
*************** (define_expand "cmpsf"
*** 5642,5649 ****
  (define_expand "cmpdf"
    [(match_operand:DF 0 "s_register_operand" "")
     (match_operand:DF 1 "fpu_rhs_operand" "")]
!   "TARGET_ARM && TARGET_HARD_FLOAT"
    "
    arm_compare_op0 = operands[0];
    arm_compare_op1 = operands[1];
    DONE;
--- 6334,6344 ----
  (define_expand "cmpdf"
    [(match_operand:DF 0 "s_register_operand" "")
     (match_operand:DF 1 "fpu_rhs_operand" "")]
!   "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
    "
+   if (TARGET_MAVERICK && !maverick_fp_register (operands[1], DFmode))
+     operands[1] = force_reg (DFmode, operands[1]);
+ 
    arm_compare_op0 = operands[0];
    arm_compare_op1 = operands[1];
    DONE;
*************** (define_insn "*cmpxf_insn"
*** 5771,5776 ****
--- 6466,6530 ----
     (set_attr "type" "f_2_r")]
  )
  
+ ;; There is no CCFPE or CCFP modes in the code below so we can have
+ ;; one pattern to match either one.  Besides, we're pretty sure we
+ ;; have either CCFPE or CCFP because we made the patterns
+ ;; (arm_gen_compare_reg).
+ 
+ ;; Maverick SF compare instruction
+ (define_insn "*maverick_cmpsf"
+   [(set (reg:CCFP 24)
+ 	(compare:CCFP (match_operand:SF 0 "maverick_fp_register" "v")
+ 		      (match_operand:SF 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcmps%?\\tr15, %V0, %V1"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "compare")]
+ )
+ 
+ ;; Maverick DF compare instruction
+ (define_insn "*maverick_cmpdf"
+   [(set (reg:CCFP 24)
+ 	(compare:CCFP (match_operand:DF 0 "maverick_fp_register" "v")
+ 		      (match_operand:DF 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcmpd%?\\tr15, %V0, %V1"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "compare")]
+ )
+ 
+ ;; Maverick DI compare instruction
+ (define_expand "cmpdi"
+   [(match_operand:DI 0 "maverick_fp_register" "")
+    (match_operand:DI 1 "maverick_fp_register" "")]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "{
+      arm_compare_op0 = operands[0];
+      arm_compare_op1 = operands[1];
+      DONE;
+    }")
+ 
+ (define_insn "*maverick_cmpdi"
+   [(set (reg:CC 24)
+ 	(compare:CC (match_operand:DI 0 "maverick_fp_register" "v")
+ 		    (match_operand:DI 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcmp64%?\\tr15, %V0, %V1"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "compare")]
+ )
+ 
+ ;; Maverick SI compare instruction
+ (define_insn "*maverick_cmpsi_1"
+   [(set (reg:CC 24)
+ 	(compare:CC (match_operand:SI 0 "maverick_fp_register" "v")
+ 		    (match_operand:SI 1 "maverick_fp_register" "v")))]
+   "TARGET_ARM && TARGET_MAVERICK"
+   "cfcmp32%?\\tr15, %V0, %V1"
+   [(set_attr "maverick_type" "farith")
+    (set_attr "maverick" "compare")]
+ )
+ 
  (define_insn "*cmpsf_trap"
    [(set (reg:CCFPE CC_REGNUM)
  	(compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
*************** (define_expand "call_value"
*** 6599,6606 ****
  )
  
  (define_insn "*call_value_reg"
!   [(set (match_operand 0 "" "=r,f")
!         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r,r"))
  	      (match_operand 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
--- 7353,7360 ----
  )
  
  (define_insn "*call_value_reg"
!   [(set (match_operand 0 "" "=r,f,v")
!         (call (mem:SI (match_operand:SI 1 "s_register_operand" "r,r,r"))
  	      (match_operand 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
*************** (define_insn "*call_value_reg"
*** 6613,6620 ****
  )
  
  (define_insn "*call_value_mem"
!   [(set (match_operand 0 "" "=r,f")
! 	(call (mem:SI (match_operand:SI 1 "memory_operand" "m,m"))
  	      (match_operand 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
--- 7367,7374 ----
  )
  
  (define_insn "*call_value_mem"
!   [(set (match_operand 0 "" "=r,f,v")
! 	(call (mem:SI (match_operand:SI 1 "memory_operand" "m,m,m"))
  	      (match_operand 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
*************** (define_insn "*call_symbol"
*** 6645,6652 ****
  )
  
  (define_insn "*call_value_symbol"
!   [(set (match_operand 0 "s_register_operand" "=r,f")
! 	(call (mem:SI (match_operand:SI 1 "" "X,X"))
  	(match_operand:SI 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
--- 7399,7406 ----
  )
  
  (define_insn "*call_value_symbol"
!   [(set (match_operand 0 "s_register_operand" "=r,f,v")
! 	(call (mem:SI (match_operand:SI 1 "" "X,X,X"))
  	(match_operand:SI 2 "" "")))
     (use (match_operand 3 "" ""))
     (clobber (reg:SI LR_REGNUM))]
*************** (define_insn "*sibcall_insn"
*** 6728,6735 ****
  )
  
  (define_insn "*sibcall_value_insn"
!  [(set (match_operand 0 "s_register_operand" "=r,f")
!        (call (mem:SI (match_operand:SI 1 "" "X,X"))
  	     (match_operand 2 "" "")))
    (return)
    (use (match_operand 3 "" ""))]
--- 7482,7489 ----
  )
  
  (define_insn "*sibcall_value_insn"
!  [(set (match_operand 0 "s_register_operand" "=r,f,v")
!        (call (mem:SI (match_operand:SI 1 "" "X,X,X"))
  	     (match_operand 2 "" "")))
    (return)
    (use (match_operand 3 "" ""))]
*************** (define_peephole2
*** 8499,8504 ****
--- 9253,9261 ----
     (set (reg:CC CC_REGNUM)
  	(compare:CC (match_dup 1) (const_int 0)))]
    "TARGET_ARM
+    && (!TARGET_MAVERICK
+        || (!maverick_fp_register (operands[0], SImode)
+            && !maverick_fp_register (operands[1], SImode)))
    "
    [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
  	      (set (match_dup 0) (match_dup 1))])]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [patch] new portlet: cirrus-maverick
  2002-08-15 11:16   ` Aldy Hernandez
@ 2002-08-16  3:28     ` Richard Earnshaw
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Earnshaw @ 2002-08-16  3:28 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Richard.Earnshaw, rearnsha, nickc, gcc-patches, rsandifo


> > + static int
> > + is_load_address (insn)
> > +      rtx insn;
> > + {
> > + }
> > 
> > What is this used for, and why isn't it using the general 
> > constant-reloading code in ARM_MACHINE_DEPENDENT_REORG?  I'm worried that 
> > this is going to break somehow.
> 
> This is used in maverick_reorg() to match certain load operations and
> insert a nop inbetween the load and a Maverick instruction.  Like
> this:
> 
> ldr r0, blah
> --> insert nop here
> cfmvsr mvf0, r0
> 

I realize this, but see below.

> This is needed because Cirrus realized too late that they weren't
> handling this in hardware, so they asked for a fixup-phase to clean up
> their mess. 

Blech!

> >     for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn 
> > (insn))
> >       {
> > +       if (TARGET_MAVERICK_FIX_INVALID_INSNS
> > +           && (is_maverick_insn (insn)
> > + 	      || GET_CODE (insn) == JUMP_INSN
> > + 	      || is_load_address (insn)))
> > + 	maverick_reorg (insn);
> > + 
> > 
> >  You should also be using note_invalid_constants(), which will detect 
> > moves of constants into a register that are about to be converted into 
> > minipool loads.  Rather than using is_load_address it might be better to 
> > look for insns whose attribue "type" is load etc.
> 
> I don't understand.  All I need is to fix these few instances.  I
> don't care about the rest.  Perhaps I'm missing something.

The point is that until arm_reorg has finished running an insn of the form

	(set (reg:SI ) (const_int NOT_VALID_FOR_MOV))

will exist (in fact, any constant expression); a symbol_ref is just a 
special case of this.  arm_reorg finds these and converts them into 
mini-pool slots, eg

	(set (reg:SI) (mem:SI(label_in_code)))

and these then get emitted as 
	ldr	Rd, LX+offset
	...
	b	somewhere
LX:
	.word
	.word
	...

You need to find and fix all these invalid-constant mov insns as well if 
your code is to be robust -- note_invalid_constants() will tell you if the 
insn contains such an expression.

> > Exactly which version of the ARM9 is the Maverick based on?  The ARM9E 
> > core is a v5TE device.
> 
> Arm920T.

OK, that's definitely a v4T device.

> + /* Return nonzero if INSN is an LDR R0,ADDR instruction.  */
> + 
> + static int
> + is_load_address (insn)
> +      rtx insn;
> + {
> +   rtx body, lhs, rhs;;
> + 
> +   if (!insn)
> +     return 0;
> + 
> +   if (GET_CODE (insn) != INSN)
> +     return 0;
> + 
> +   body = PATTERN (insn);
> + 
> +   if (GET_CODE (body) != SET)
> +     return 0;
> + 
> +   lhs = SET_DEST (body);
> +   rhs = SET_SRC (body);
> + 
> +   return (GET_CODE (lhs) == REG
> + 	  && REGNO_REG_CLASS (REGNO (lhs)) == GENERAL_REGS
> + 	  && (GET_CODE (rhs) == MEM
> + 	      || GET_CODE (rhs) == SYMBOL_REF));
> + }

I forget precisely when we blat SUBREG expressions.  You might need to 
handle that here as well.  Consider

	(set (subreg:SI (reg:SF 0 "r0") 0) (const_int 0x80000000))

Also, if we are keeping this, please rename it to arm_memory_load_p()


arm.h:   

> + /* Nonzero if this chip is a Maverick variant.  */
> + extern int arm_is_maverick;
> + 

You missed this in the cleanup!

   
> --- 700,706 ----
>   
>   /* Define this if most significant word of doubles is the lowest numbered.
>      This is always true, even when in little-endian mode.  */
> ! #define FLOAT_WORDS_BIG_ENDIAN (!TARGET_MAVERICK || WORDS_BIG_ENDIAN)
>   

Please update the comment.

> *************** enum reg_class
> *** 1042,1047 ****
> --- 1098,1104 ----
>   {					\
>     { 0x0000000 }, /* NO_REGS  */		\
>     { 0x0FF0000 }, /* FPU_REGS */		\
> +   { 0xf8000000, 0x000007FF }, /* MAVERICK_REGS */	\
>     { 0x00000FF }, /* LO_REGS */		\
>     { 0x0002000 }, /* STACK_REG */	\
>     { 0x00020FF }, /* BASE_REGS */	\
Can you pad this out so that all entries have 2 words.

> Index: doc/invoke.texi
> ===================================================================
> RCS file: /cvs/uberbaum/gcc/doc/invoke.texi,v
> retrieving revision 1.170
> diff -c -p -r1.170 invoke.texi
> *** doc/invoke.texi	11 Aug 2002 09:47:47 -0000	1.170
> --- doc/invoke.texi	15 Aug 2002 18:08:17 -0000
> *************** in the following sections.

Don't you need to add armmaverick to the list of supported -mcpu= types?

> Index: config/arm/arm.md
> ===================================================================
> RCS file: /cvs/uberbaum/gcc/config/arm/arm.md,v
> retrieving revision 1.104
> diff -p -F^( -r1.104 arm.md
> *** config/arm/arm.md	29 Jul 2002 12:41:46 -0000	1.104
> --- config/arm/arm.md	15 Aug 2002 18:09:30 -0000
> *************** (define_attr "shift" "" (const_int 0))
> *** 123,128 ****
> --- 123,154 ----
>   ; performance we should try and group them together).
>   (define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr")))
>   
> + (define_attr "maverick_fpu" "fpa,fpe2,fpe3,yes" (const (symbol_ref "arm_fpu_attr")))

Why have you created a macro which is a superset of "fpu"? In particular 
since it uses the same symbol as "fpu" this means that "fpu" can now hold 
an illegal value.  You should define "fpu" to be "fpa,fpe2,fpe3,maverick", 
and then if you really need a maverick_fpu attribute (I'm not sure you do) 
you can define it as
  (define_attr "maverick_fpu" "no,yes"
	(if_then_else (eq_attr "fpu" "maverick")
	 (const_string "yes")
	 (const_string "no")))

> + ; Classification of each insn
> + ; farith	Floating point arithmetic (4 cycle)
> + ; dmult		Double multiplies (7 cycle)
> + (define_attr "maverick_type" "normal,farith,dmult" (const_string "normal"))

Again, can you not just extend the existing "type" attribute with the 
additional maverick classes.

> + (define_attr "maverick" "no,yes,double,compare,move" (const_string "no"))

I don't like the idea of a 5-way decision that has both 'yes' and 'no' as 
two of the alternatives!

> + (define_function_unit "maverick_fpa" 1 0
> +   (and (eq_attr "maverick_fpu" "yes")
> +        (eq_attr "maverick_type" "farith")) 4 1)

Based on the above, I think these should be something like

(define_function_unit "maverick_fpu" 1 0
   (and (eq_attr "fpu" "maverick")
        (eq_attr "type" "mav_farith")) 4 1)
etc.


> + ;; There is no CCFPE or CCFP modes in the code below so we can have
> + ;; one pattern to match either one.  Besides, we're pretty sure we
> + ;; have either CCFPE or CCFP because we made the patterns
> + ;; (arm_gen_compare_reg).

??? This doesn't make sense to me, and it doesn't seem to match the code 
either.


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2002-08-16 10:28 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-14  8:50 [patch] new portlet: cirrus-maverick Aldy Hernandez
2002-08-14  9:22 ` Aldy Hernandez
2002-08-14  9:43 ` Phil Edwards
2002-08-14  9:54   ` Aldy Hernandez
2002-08-14 10:27     ` Phil Edwards
2002-08-14 11:35       ` Aldy Hernandez
2002-08-14 10:42 ` Mark Mitchell
2002-08-15  2:47 ` Nick Clifton
2002-08-15  4:50 ` Richard Earnshaw
2002-08-15 11:16   ` Aldy Hernandez
2002-08-16  3:28     ` Richard Earnshaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).