This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] new portlet: cirrus-maverick
- From: Aldy Hernandez <aldyh at redhat dot com>
- To: rearnsha at arm dot com, nickc at redhat dot com, gcc-patches at gcc dot gnu dot org
- Cc: rsandifo at redhat dot com
- Date: Wed, 14 Aug 2002 08:57:52 -0700
- Subject: [patch] new portlet: cirrus-maverick
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 ----
;; 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 ****
;; 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 ----
;; 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
;;