This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Contribution: Support for Cirrus Maverick EP9312 chip
- From: Nick Clifton <nickc at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 10 Feb 2003 11:40:39 +0000
- Subject: Contribution: Support for Cirrus Maverick EP9312 chip
Hi Guys,
I am applying the patch below to add support for Cirrus's EP9312
chip, an ARM variant which includes their Maverick floating point
co-processor. The port was written by Aldy Hernandez a while ago,
and I have now, finally, found time to submit it.
The port still has some problems with its floating point handling,
and it only really works with an ELF target, since I have not
arranged for a way to label COFF binaries as supporting the Maverick
co-processor. Also, although I have added code to t-arm-elf to
generate the multilibs to support the EP9312, they are currently
commented out, in order to save time and disk space for majority of
people using the arm-elf port.
I tried to keep most of the new instruction patterns in a new
cirrus.md file, but for some it was necessary to add them to the
arm.md file, in order for them to be in the correct place.
I have remembered to create an entry for the HTML documentation this
time, although the notes include a mention of the patch to the
t-arm-elf file. I am not sure if some special formatting tags are
needed for this path.
Cheers
Nick
gcc/ChangeLog
2003-02-10 Nick Clifton <nickc@redhat.com>
* Contributed support for the Cirrus EP9312 "Maverick"
floating point co-processor. Written by Aldy Hernandez
<aldyh@redhat.com>.
(config/arm/arm.c): Add Cirrus support.
(config/arm/arm.h): Likewise.
(config/arm/aout.h): Likewise.
(config/arm/arm.md): Likewise.
(config/arm/arm-protos.h): Likewise.
(config.gcc): Likewise.
(doc/invoke.texi): Describe new -mcpu value and new
-mcirrus-fix-invalid-insns switch,
(cirrus.md): New file.
Index: gcc/config.gcc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config.gcc,v
retrieving revision 1.282
diff -c -3 -p -w -r1.282 config.gcc
*** gcc/config.gcc 6 Feb 2003 21:17:12 -0000 1.282
--- gcc/config.gcc 10 Feb 2003 11:23:30 -0000
*************** strongarm*-*-*)
*** 259,264 ****
--- 259,267 ----
arm*-*-*)
cpu_type=arm
;;
+ ep9312*-*-*)
+ cpu_type=arm
+ ;;
xscale-*-*)
cpu_type=arm
;;
*************** arm*-*-rtems*)
*** 700,706 ****
thread_file='rtems'
fi
;;
! arm*-*-elf)
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
tmake_file=arm/t-arm-elf
;;
--- 703,709 ----
thread_file='rtems'
fi
;;
! arm*-*-elf | ep9312-*-elf)
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
tmake_file=arm/t-arm-elf
;;
*************** arm*-*-*)
*** 2789,2794 ****
--- 2792,2798 ----
| xarm7m | xarm7dm | xarm7dmi | xarm[79]tdmi \
| xarm7100 | xarm7500 | xarm7500fe | xarm810 \
| xxscale \
+ | xep9312 \
| xstrongarm | xstrongarm110 | xstrongarm1100)
target_cpu_default2="TARGET_CPU_$with_cpu"
;;
*************** arm*-*-*)
*** 2804,2809 ****
--- 2808,2818 ----
echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2
exit 1
fi
+ ;;
+ esac
+ case $machine in
+ 9ep9312-*-*)
+ target_cpu_default2="TARGET_CPU_9ep9312"
;;
esac
;;
Index: gcc/config/arm/aout.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/aout.h,v
retrieving revision 1.28
diff -c -3 -p -w -r1.28 aout.h
*** gcc/config/arm/aout.h 16 Dec 2002 18:20:54 -0000 1.28
--- gcc/config/arm/aout.h 10 Feb 2003 11:23:37 -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: gcc/config/arm/arm-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm-protos.h,v
retrieving revision 1.47
diff -c -3 -p -w -r1.47 arm-protos.h
*** gcc/config/arm/arm-protos.h 5 Feb 2003 22:37:53 -0000 1.47
--- gcc/config/arm/arm-protos.h 10 Feb 2003 11:23:37 -0000
*************** extern int logical_binary_operator PA
*** 94,99 ****
--- 94,104 ----
extern int multi_register_push PARAMS ((rtx, enum machine_mode));
extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
+ extern int cirrus_fp_register PARAMS ((rtx, enum machine_mode));
+ extern int cirrus_general_operand PARAMS ((rtx, enum machine_mode));
+ extern int cirrus_register_operand PARAMS ((rtx, enum machine_mode));
+ extern int cirrus_shift_const PARAMS ((rtx, enum machine_mode));
+ extern int cirrus_memory_offset PARAMS ((rtx));
extern int symbol_mentioned_p PARAMS ((rtx));
extern int label_mentioned_p PARAMS ((rtx));
*************** extern rtx arm_va_arg
*** 149,155 ****
extern int arm_function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
enum machine_mode,
tree, int));
-
#endif
#if defined AOF_ASSEMBLER
--- 154,159 ----
Index: gcc/config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.257
diff -c -3 -p -w -r1.257 arm.c
*** gcc/config/arm/arm.c 5 Feb 2003 22:37:53 -0000 1.257
--- gcc/config/arm/arm.c 10 Feb 2003 11:23:45 -0000
*************** typedef struct minipool_fixup Mfix;
*** 62,67 ****
--- 62,73 ----
#define Ulong unsigned long
#define Ccstar const char *
+ const char extra_reg_names1[][16] =
+ { "mv0", "mv1", "mv2", "mv3", "mv4", "mv5", "mv6", "mv7",
+ "mv8", "mv9", "mv10", "mv11", "mv12", "mv13", "mv14", "mv15"
+ };
+ #define extra_reg_names1 bogus1_regnames
+
const struct attribute_spec arm_attribute_table[];
/* Forward function declarations. */
*************** static int arm_rtx_costs_1 PARAMS ((rt
*** 144,149 ****
--- 150,158 ----
enum rtx_code));
static bool arm_rtx_costs PARAMS ((rtx, int, int, int*));
static int arm_address_cost PARAMS ((rtx));
+ static int is_load_address PARAMS ((rtx));
+ static int is_cirrus_insn PARAMS ((rtx));
+ static void cirrus_reorg PARAMS ((rtx));
#undef Hint
#undef Mmode
*************** int arm_structure_size_boundary = DEF
*** 263,268 ****
--- 272,278 ----
#define FL_STRONG (1 << 8) /* StrongARM */
#define FL_ARCH5E (1 << 9) /* DSP extensions to v5 */
#define FL_XSCALE (1 << 10) /* XScale */
+ #define FL_CIRRUS (1 << 11) /* Cirrus/DSP. */
/* The bits in this mask specify which
instructions we are allowed to generate. */
*************** int arm_is_xscale = 0;
*** 301,306 ****
--- 311,319 ----
/* Nonzero if this chip is an ARM6 or an ARM7. */
int arm_is_6_or_7 = 0;
+ /* Nonzero if this chip is a Cirrus/DSP. */
+ int arm_is_cirrus = 0;
+
/* Nonzero if generating Thumb instructions. */
int thumb_code = 0;
*************** static const struct processors all_cores
*** 391,396 ****
--- 404,410 ----
{"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 },
+ {"ep9312", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS },
{"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 },
*************** static const struct processors all_archi
*** 417,422 ****
--- 431,437 ----
{ "armv5", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
{ "armv5t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
{ "armv5te", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
+ { "ep9312", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS },
{ NULL, 0 }
};
*************** arm_override_options ()
*** 514,519 ****
--- 529,535 ----
{ TARGET_CPU_arm9, "arm9" },
{ TARGET_CPU_strongarm, "strongarm" },
{ TARGET_CPU_xscale, "xscale" },
+ { TARGET_CPU_ep9312, "ep9312" },
{ TARGET_CPU_generic, "arm" },
{ 0, 0 }
};
*************** arm_override_options ()
*** 712,718 ****
--- 728,744 ----
thumb_code = (TARGET_ARM == 0);
arm_is_6_or_7 = (((tune_flags & (FL_MODE26 | FL_MODE32))
&& !(tune_flags & FL_ARCH4))) != 0;
+ arm_is_cirrus = (tune_flags & FL_CIRRUS) != 0;
+ if (arm_is_cirrus)
+ {
+ arm_fpu = FP_CIRRUS;
+
+ /* Ignore -mhard-float if -mcpu=ep9312. */
+ 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,
assume the user has an FPA.
*************** arm_override_options ()
*** 733,740 ****
else
arm_fpu_arch = FP_DEFAULT;
! if (TARGET_FPE && arm_fpu != FP_HARD)
arm_fpu = FP_SOFT2;
/* For arm2/3 there is no need to do any scheduling if there is only
a floating point emulator, or we are doing software floating-point. */
--- 759,773 ----
else
arm_fpu_arch = FP_DEFAULT;
! if (TARGET_FPE)
! {
! if (arm_fpu == FP_SOFT3)
arm_fpu = FP_SOFT2;
+ else if (arm_fpu == FP_CIRRUS)
+ warning ("-mpfpe switch not supported by ep9312 target cpu - ignored.");
+ else if (arm_fpu != FP_HARD)
+ arm_fpu = FP_SOFT2;
+ }
/* For arm2/3 there is no need to do any scheduling if there is only
a floating point emulator, or we are doing software floating-point. */
*************** arm_return_in_memory (type)
*** 1902,1907 ****
--- 1935,1942 ----
int
arm_float_words_big_endian ()
{
+ if (TARGET_CIRRUS)
+ return 0;
/* For FPA, float words are always big-endian. For VFP, floats words
follow the memory system mode. */
*************** arm_legitimate_index_p (mode, index, str
*** 2688,2693 ****
--- 2723,2734 ----
&& INTVAL (index) > -1024
&& (INTVAL (index) & 3) == 0);
+ if (TARGET_CIRRUS
+ && (GET_MODE_CLASS (mode) == MODE_FLOAT || mode == DImode))
+ return (code == CONST_INT
+ && INTVAL (index) < 255
+ && INTVAL (index) > -255);
+
if (arm_address_register_rtx_p (index, strict_p)
&& GET_MODE_SIZE (mode) <= 4)
return 1;
*************** fpu_add_operand (op, mode)
*** 3856,3861 ****
--- 3897,4158 ----
return FALSE;
}
+ /* Return nonzero if OP is a valid Cirrus memory address pattern. */
+
+ int
+ cirrus_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 Cirrus or general register. */
+
+ int
+ cirrus_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)) == CIRRUS_REGS
+ || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
+ }
+
+ /* Return nonzero if OP is a cirrus FP register. */
+
+ int
+ cirrus_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)) == CIRRUS_REGS));
+ }
+
+ /* Return nonzero if OP is a 6bit constant (0..63). */
+
+ int
+ cirrus_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 Cirrus instruction. */
+
+ static int
+ is_cirrus_insn (insn)
+ rtx insn;
+ {
+ enum attr_cirrus 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_cirrus (insn);
+
+ return attr != CIRRUS_NO;
+ }
+
+ /* Cirrus reorg for invalid instruction combinations. */
+
+ static void
+ cirrus_reorg (first)
+ rtx first;
+ {
+ enum attr_cirrus attr;
+ rtx body = PATTERN (first);
+ rtx t;
+ int nops;
+
+ /* Any branch must be followed by 2 non Cirrus instructions. */
+ if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN)
+ {
+ nops = 0;
+ t = next_nonnote_insn (first);
+
+ if (is_cirrus_insn (t))
+ ++ nops;
+
+ if (is_cirrus_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 Cirrus insn. */
+ if (get_attr_cirrus (first) == CIRRUS_DOUBLE)
+ {
+ if (is_cirrus_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 Cirrus
+ 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_cirrus_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_cirrus (first) == CIRRUS_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_cirrus (first);
+
+ /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...)
+ must be followed by a non-coprocessor instruction. */
+ if (attr == CIRRUS_COMPARE)
+ {
+ nops = 0;
+
+ t = next_nonnote_insn (first);
+
+ if (is_cirrus_insn (t))
+ ++ nops;
+
+ if (is_cirrus_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)
*** 5355,5360 ****
--- 5652,5659 ----
case LE:
case GT:
case GE:
+ if (TARGET_CIRRUS)
+ return CCFPmode;
return CCFPEmode;
default:
*************** arm_reorg (first)
*** 6678,6683 ****
--- 6977,6988 ----
/* 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_CIRRUS_FIX_INVALID_INSNS
+ && (is_cirrus_insn (insn)
+ || GET_CODE (insn) == JUMP_INSN
+ || is_load_address (insn)))
+ cirrus_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)
*** 9168,9173 ****
--- 9473,9488 ----
fprintf (stream, "%s", arithmetic_instr (x, 1));
return;
+ /* Truncate Cirrus 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)
*** 9274,9279 ****
--- 9589,9631 ----
fputs (thumb_condition_code (x, 1), stream);
return;
+
+ /* Cirrus 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': /* Cirrus register in F mode. */
+ case 'X': /* Cirrus register in D mode. */
+ case 'Y': /* Cirrus register in FX mode. */
+ case 'Z': /* Cirrus register in DX mode. */
+ if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
+ abort ();
+
+ fprintf (stream, "mv%s%s",
+ code == 'W' ? "f"
+ : code == 'X' ? "d"
+ : code == 'Y' ? "fx" : "dx", reg_names[REGNO (x)] + 2);
+
+ return;
+
+ /* Print cirrus 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)) != CIRRUS_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)
*** 9765,9770 ****
--- 10117,10134 ----
|| GET_CODE (scanbody) == PARALLEL)
|| get_attr_conds (this_insn) != CONDS_NOCOND)
fail = TRUE;
+
+ /* A conditional cirrus instruction must be followed by
+ a non Cirrus 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 Cirrus
+ instructions to be safe. */
+ if (GET_CODE (scanbody) != USE
+ && GET_CODE (scanbody) != CLOBBER
+ && get_attr_cirrus (this_insn) != CIRRUS_NO)
+ fail = TRUE;
break;
default:
*************** arm_hard_regno_mode_ok (regno, mode)
*** 9848,9853 ****
--- 10212,10225 ----
start of an even numbered register pair. */
return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
+ if (IS_CIRRUS_REGNUM (regno))
+ /* We have outlawed SI values in Cirrus 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 Cirrus SI values
+ get sign extended to 64bits-- aldyh. */
+ 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)
*** 9886,9891 ****
--- 10258,10266 ----
if (regno == CC_REGNUM)
return NO_REGS;
+
+ if (IS_CIRRUS_REGNUM (regno))
+ return CIRRUS_REGS;
return FPU_REGS;
}
Index: gcc/config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.181
diff -c -3 -p -w -r1.181 arm.h
*** gcc/config/arm/arm.h 5 Feb 2003 22:37:53 -0000 1.181
--- gcc/config/arm/arm.h 10 Feb 2003 11:23:50 -0000
*************** Boston, MA 02111-1307, USA. */
*** 96,101 ****
--- 96,102 ----
#define TARGET_CPU_arm9 0x0080
#define TARGET_CPU_arm9tdmi 0x0080
#define TARGET_CPU_xscale 0x0100
+ #define TARGET_CPU_ep9312 0x0200
/* Configure didn't specify. */
#define TARGET_CPU_generic 0x8000
*************** extern GTY(()) rtx aof_pic_label;
*** 164,169 ****
--- 165,178 ----
#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_ep9312
+ #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
*** 171,176 ****
--- 180,186 ----
#endif
#endif
#endif
+ #endif
#undef CPP_SPEC
#define CPP_SPEC "%(cpp_cpu_arch) %(subtarget_cpp_spec) \
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 212,217 ****
--- 222,229 ----
%{march=strongarm1100:-D__ARM_ARCH_4__} \
%{march=xscale:-D__ARM_ARCH_5TE__} \
%{march=xscale:-D__XSCALE__} \
+ %{march=ep9312:-D__ARM_ARCH_4T__} \
+ %{march=ep9312:-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
*** 251,256 ****
--- 263,270 ----
%{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
%{mcpu=xscale:-D__ARM_ARCH_5TE__} \
%{mcpu=xscale:-D__XSCALE__} \
+ %{mcpu=ep9312:-D__ARM_ARCH_4T__} \
+ %{mcpu=ep9312:-D__MAVERICK__} \
%{!mcpu*:%(cpp_cpu_arch_default)}} \
"
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 376,381 ****
--- 390,398 ----
/* Nonzero means to use ARM/Thumb Procedure Call Standard conventions. */
#define ARM_FLAG_ATPCS (1 << 22)
+ /* Fix invalid Cirrus instruction combinations by inserting NOPs. */
+ #define CIRRUS_FIX_INVALID_INSNS (1 << 23)
+
#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
*** 387,392 ****
--- 404,411 ----
#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_CIRRUS (arm_is_cirrus)
+ #define TARGET_ANY_HARD_FLOAT (TARGET_HARD_FLOAT || TARGET_CIRRUS)
#define TARGET_VFP (target_flags & ARM_FLAG_VFP)
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
#define TARGET_INTERWORK (target_flags & ARM_FLAG_INTERWORK)
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 403,408 ****
--- 422,428 ----
#define TARGET_BACKTRACE (leaf_function_p () \
? (target_flags & THUMB_FLAG_LEAF_BACKTRACE) \
: (target_flags & THUMB_FLAG_BACKTRACE))
+ #define TARGET_CIRRUS_FIX_INVALID_INSNS (target_flags & CIRRUS_FIX_INVALID_INSNS)
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis. */
#ifndef SUBTARGET_SWITCHES
*************** Unrecognized value in TARGET_CPU_DEFAULT
*** 481,486 ****
--- 501,510 ----
N_("Thumb: Assume function pointers may go to non-Thumb aware code") }, \
{"no-caller-super-interworking", -THUMB_FLAG_CALLER_SUPER_INTERWORKING, \
"" }, \
+ {"cirrus-fix-invalid-insns", CIRRUS_FIX_INVALID_INSNS, \
+ N_("Cirrus: Place NOPs to avoid invalid instruction combinations") }, \
+ {"no-cirrus-fix-invalid-insns", -CIRRUS_FIX_INVALID_INSNS, \
+ N_("Cirrus: Do not break up invalid instruction combinations with NOPs") },\
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT, "" } \
}
*************** enum floating_point_type
*** 530,536 ****
{
FP_HARD,
FP_SOFT2,
! FP_SOFT3
};
/* Recast the floating point class to be the floating point attribute. */
--- 554,561 ----
{
FP_HARD,
FP_SOFT2,
! FP_SOFT3,
! FP_CIRRUS
};
/* Recast the floating point class to be the floating point attribute. */
*************** extern enum floating_point_type arm_fpu_
*** 548,553 ****
--- 573,583 ----
#define FP_DEFAULT FP_SOFT2
#endif
+ #if TARGET_CPU_DEFAULT == TARGET_CPU_ep9312
+ #undef FP_DEFAULT
+ #define FP_DEFAULT FP_CIRRUS
+ #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;
*** 570,575 ****
--- 600,608 ----
/* Nonzero if this chip is a StrongARM. */
extern int arm_is_strong;
+ /* Nonzero if this chip is a Cirrus variant. */
+ extern int arm_is_cirrus;
+
/* Nonzero if this chip is an XScale. */
extern int arm_is_xscale;
*************** extern const char * structure_size_strin
*** 756,761 ****
--- 789,799 ----
*: See CONDITIONAL_REGISTER_USAGE */
+ /*
+ mvf0 Cirrus floating point result
+ mvf1-mvf3 Cirrus floating point scratch
+ mvf4-mvf15 S Cirrus floating point variable. */
+
/* The stack backtrace structure is as follows:
fp points to here: | save code pointer | [fp]
| return link value | [fp, #-4]
*************** extern const char * structure_size_strin
*** 785,791 ****
0,0,0,0,0,0,0,0, \
0,0,0,0,0,1,0,1, \
0,0,0,0,0,0,0,0, \
! 1,1,1 \
}
/* 1 for registers not available across function calls.
--- 823,831 ----
0,0,0,0,0,0,0,0, \
0,0,0,0,0,1,0,1, \
0,0,0,0,0,0,0,0, \
! 1,1,1, \
! 1,1,1,1,1,1,1,1, \
! 1,1,1,1,1,1,1,1 \
}
/* 1 for registers not available across function calls.
*************** extern const char * structure_size_strin
*** 801,807 ****
1,1,1,1,0,0,0,0, \
0,0,0,0,1,1,1,1, \
1,1,1,1,0,0,0,0, \
! 1,1,1 \
}
#ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE
--- 841,849 ----
1,1,1,1,0,0,0,0, \
0,0,0,0,1,1,1,1, \
1,1,1,1,0,0,0,0, \
! 1,1,1, \
! 1,1,1,1,1,1,1,1, \
! 1,1,1,1,1,1,1,1 \
}
#ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE
*************** extern const char * structure_size_strin
*** 818,823 ****
--- 860,879 ----
regno <= LAST_ARM_FP_REGNUM; ++regno) \
fixed_regs[regno] = call_used_regs[regno] = 1; \
} \
+ \
+ if (TARGET_CIRRUS) \
+ { \
+ for (regno = FIRST_ARM_FP_REGNUM; \
+ regno <= LAST_ARM_FP_REGNUM; ++ regno) \
+ fixed_regs[regno] = call_used_regs[regno] = 1; \
+ for (regno = FIRST_CIRRUS_FP_REGNUM; \
+ regno <= LAST_CIRRUS_FP_REGNUM; ++ regno) \
+ { \
+ fixed_regs[regno] = 0; \
+ call_used_regs[regno] = regno < FIRST_CIRRUS_FP_REGNUM + 4; \
+ } \
+ } \
+ \
if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
*************** extern const char * structure_size_strin
*** 941,948 ****
/* Base register for access to arguments of the function. */
#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,1010 ----
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM 26
+ #define FIRST_CIRRUS_FP_REGNUM 27
+ #define LAST_CIRRUS_FP_REGNUM 42
+ #define IS_CIRRUS_REGNUM(REGNUM) \
+ (((REGNUM) >= FIRST_CIRRUS_FP_REGNUM) && ((REGNUM) <= LAST_CIRRUS_FP_REGNUM))
+
/* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP. */
! /* Cirrus registers take us up to 43... */
! #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
*************** extern const char * structure_size_strin
*** 990,995 ****
--- 1052,1059 ----
3, 2, 1, 0, 12, 14, 4, 5, \
6, 7, 8, 10, 9, 11, 13, 15, \
16, 17, 18, 19, 20, 21, 22, 23, \
+ 27, 28, 29, 30, 31, 32, 33, 34, \
+ 35, 36, 37, 38, 39, 40, 41, 42, \
24, 25, 26 \
}
*************** enum reg_class
*** 1008,1013 ****
--- 1072,1078 ----
{
NO_REGS,
FPU_REGS,
+ CIRRUS_REGS,
LO_REGS,
STACK_REG,
BASE_REGS,
*************** enum reg_class
*** 1025,1030 ****
--- 1090,1096 ----
{ \
"NO_REGS", \
"FPU_REGS", \
+ "CIRRUS_REGS", \
"LO_REGS", \
"STACK_REG", \
"BASE_REGS", \
*************** enum reg_class
*** 1039,1053 ****
of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \
{ \
! { 0x0000000 }, /* NO_REGS */ \
! { 0x0FF0000 }, /* FPU_REGS */ \
! { 0x00000FF }, /* LO_REGS */ \
! { 0x0002000 }, /* STACK_REG */ \
! { 0x00020FF }, /* BASE_REGS */ \
! { 0x000FF00 }, /* HI_REGS */ \
! { 0x1000000 }, /* CC_REG */ \
! { 0x200FFFF }, /* GENERAL_REGS */ \
! { 0x2FFFFFF } /* ALL_REGS */ \
}
/* The same information, inverted:
--- 1105,1120 ----
of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \
{ \
! { 0x00000000, 0x0 }, /* NO_REGS */ \
! { 0x00FF0000, 0x0 }, /* FPU_REGS */ \
! { 0xF8000000, 0x000007FF }, /* CIRRUS_REGS */ \
! { 0x000000FF, 0x0 }, /* LO_REGS */ \
! { 0x00002000, 0x0 }, /* STACK_REG */ \
! { 0x000020FF, 0x0 }, /* BASE_REGS */ \
! { 0x0000FF00, 0x0 }, /* HI_REGS */ \
! { 0x01000000, 0x0 }, /* CC_REG */ \
! { 0x0200FFFF, 0x0 }, /* GENERAL_REGS */\
! { 0xFAFFFFFF, 0x000007FF } /* ALL_REGS */ \
}
/* The same information, inverted:
*************** enum reg_class
*** 1080,1085 ****
--- 1147,1153 ----
ARM, but several more letters for the Thumb. */
#define REG_CLASS_FROM_LETTER(C) \
( (C) == 'f' ? FPU_REGS \
+ : (C) == 'v' ? CIRRUS_REGS \
: (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS) \
: TARGET_ARM ? NO_REGS \
: (C) == 'h' ? HI_REGS \
*************** enum reg_class
*** 1143,1150 ****
(C) == 'R' ? (GET_CODE (OP) == MEM \
&& GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
&& CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
! (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) \
! : 0)
#define EXTRA_CONSTRAINT_THUMB(X, C) \
((C) == 'Q' ? (GET_CODE (X) == MEM \
--- 1211,1219 ----
(C) == 'R' ? (GET_CODE (OP) == MEM \
&& GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
&& CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
! (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \
! (C) == 'T' ? cirrus_memory_offset (OP) : \
! 0)
#define EXTRA_CONSTRAINT_THUMB(X, C) \
((C) == 'Q' ? (GET_CODE (X) == MEM \
*************** enum reg_class
*** 1188,1200 ****
/* 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
--- 1257,1274 ----
/* 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 Cirrus registers. */ \
+ ((TARGET_CIRRUS \
+ && (CLASS) == CIRRUS_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
*** 1217,1222 ****
--- 1291,1299 ----
\
if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
low = ((val & 0xf) ^ 0x8) - 0x8; \
+ else if (TARGET_CIRRUS) \
+ /* 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
*** 1289,1301 ****
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)
--- 1366,1384 ----
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) == CIRRUS_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. */
/* 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 : \
! (FROM) == CIRRUS_REGS && (TO) != CIRRUS_REGS ? 20 : \
! (FROM) != CIRRUS_REGS && (TO) == CIRRUS_REGS ? 20 : \
! 2) \
: \
((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2)
*************** enum reg_class
*** 1347,1352 ****
--- 1430,1437 ----
#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_CIRRUS && GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ ? gen_rtx_REG (MODE, FIRST_CIRRUS_FP_REGNUM) \
: gen_rtx_REG (MODE, ARG_REGISTER (1)))
/* Define how to find the value returned by a function.
*************** enum reg_class
*** 1358,1365 ****
--- 1443,1452 ----
/* 1 if N is a possible register number for a function value.
On the ARM, only r0 and f0 can return results. */
+ /* On a Cirrus chip, mvf0 can return results. */
#define FUNCTION_VALUE_REGNO_P(REGNO) \
((REGNO) == ARG_REGISTER (1) \
+ || (TARGET_ARM && ((REGNO) == FIRST_CIRRUS_FP_REGNUM) && TARGET_CIRRUS) \
|| (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT))
/* How large values are returned */
*************** extern int making_const_table;
*** 2449,2454 ****
--- 2536,2544 ----
{"multi_register_push", {PARALLEL}}, \
{"cc_register", {REG}}, \
{"logical_binary_operator", {AND, IOR, XOR}}, \
+ {"cirrus_register_operand", {REG}}, \
+ {"cirrus_fp_register", {REG}}, \
+ {"cirrus_shift_const", {CONST_INT}}, \
{"dominant_cc_register", {REG}},
/* Define this if you have special predicates that know special things
Index: gcc/config/arm/arm.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.md,v
retrieving revision 1.118
diff -c -3 -p -w -r1.118 arm.md
*** gcc/config/arm/arm.md 5 Feb 2003 22:37:53 -0000 1.118
--- gcc/config/arm/arm.md 10 Feb 2003 11:23:54 -0000
***************
*** 386,391 ****
--- 386,393 ----
(and (eq_attr "core_cycles" "multi")
(eq_attr "type" "!mult,load,store1,store2,store3,store4")) 32 32)
+ (include "cirrus.md")
+
;;---------------------------------------------------------------------------
;; Insn patterns
;;
***************
*** 394,399 ****
--- 396,403 ----
;; 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.
+ ;; Cirrus 64bit additions should not be split because we have a native
+ ;; 64bit addition instructions.
(define_expand "adddi3"
[(parallel
***************
*** 403,408 ****
--- 407,422 ----
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[0], DImode))
+ operands[0] = force_reg (DImode, operands[0]);
+ if (!cirrus_fp_register (operands[1], DImode))
+ operands[1] = force_reg (DImode, operands[1]);
+ emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+
if (TARGET_THUMB)
{
if (GET_CODE (operands[1]) != REG)
***************
*** 429,435 ****
(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)
--- 443,449 ----
(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_CIRRUS"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
***************
*** 457,463 ****
(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)
--- 471,477 ----
(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_CIRRUS"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
***************
*** 486,492 ****
(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)
--- 500,506 ----
(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_CIRRUS"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
***************
*** 789,795 ****
(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")))]
--- 803,809 ----
(set_attr "length" "4,8")]
)
! (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")))]
***************
*** 801,807 ****
(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")))]
--- 815,821 ----
(set_attr "predicable" "yes")]
)
! (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")))]
***************
*** 857,862 ****
--- 871,885 ----
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
+ if (TARGET_CIRRUS
+ && TARGET_ARM
+ && cirrus_fp_register (operands[0], DImode)
+ && cirrus_fp_register (operands[1], DImode))
+ {
+ emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+
if (TARGET_THUMB)
{
if (GET_CODE (operands[1]) != REG)
***************
*** 1042,1048 ****
(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")))]
--- 1065,1071 ----
(set_attr "length" "*,8")]
)
! (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")))]
***************
*** 1053,1059 ****
[(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")))]
--- 1076,1082 ----
[(set_attr "type" "farith")]
)
! (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")))]
***************
*** 1332,1338 ****
"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")))]
--- 1355,1361 ----
"smlalbb%?\\t%Q0, %R0, %2, %3"
[(set_attr "type" "mult")])
! (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")))]
***************
*** 1342,1348 ****
(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")))]
--- 1365,1371 ----
(set_attr "predicable" "yes")]
)
! (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")))]
***************
*** 2529,2534 ****
--- 2552,2570 ----
[(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 && (TARGET_CIRRUS)"
+ "
+ 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 "*arm_shiftsi3"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(match_operator:SI 3 "shift_operator"
***************
*** 2702,2708 ****
[(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"
--- 2738,2744 ----
[(set_attr "length" "2")]
)
! (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"
***************
*** 2711,2717 ****
(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"
--- 2747,2753 ----
(set_attr "predicable" "yes")]
)
! (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"
***************
*** 2735,2741 ****
;; 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))]
--- 2771,2777 ----
;; it does, but tell the final scan operator the truth. Similarly for
;; (neg (abs...))
! (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))]
***************
*** 2763,2769 ****
(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"
--- 2799,2805 ----
(set_attr "length" "8")]
)
! (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"
***************
*** 2772,2778 ****
(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"
--- 2808,2814 ----
(set_attr "predicable" "yes")]
)
! (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"
***************
*** 2884,2890 ****
;; 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"
--- 2920,2926 ----
;; Fixed <--> Floating conversion insns
! (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"
***************
*** 2893,2899 ****
(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"
--- 2929,2935 ----
(set_attr "predicable" "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"
***************
*** 2902,2908 ****
(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"
--- 2938,2944 ----
(set_attr "predicable" "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"
***************
*** 2911,2917 ****
(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"
--- 2947,2953 ----
(set_attr "predicable" "yes")]
)
! (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"
***************
*** 2922,2928 ****
;; 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")))]
--- 2958,2964 ----
;; Truncation insns
! (define_insn "*arm_truncdfsf2"
[(set (match_operand:SF 0 "s_register_operand" "=f")
(float_truncate:SF
(match_operand:DF 1 "s_register_operand" "f")))]
***************
*** 3654,3660 ****
(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"
--- 3690,3696 ----
(set_attr "pool_range" "32,32")]
)
! (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"
***************
*** 3743,3749 ****
(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));
"
--- 3779,3785 ----
(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_CIRRUS"
"*
return (output_move_double (operands));
"
***************
*** 3761,3766 ****
--- 3797,3803 ----
[(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_CIRRUS
&& ( register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode))"
"*
***************
*** 4769,4774 ****
--- 4806,4812 ----
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
(match_operand:SF 1 "general_operand" "r,mE,r"))]
"TARGET_ARM
+ && !TARGET_CIRRUS
&& TARGET_SOFT_FLOAT
&& (GET_CODE (operands[0]) != MEM
|| register_operand (operands[1], SFmode))"
***************
*** 4909,4914 ****
--- 4947,4953 ----
[(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_CIRRUS
"
"* return output_move_double (operands);"
[(set_attr "length" "8,8,8")
***************
*** 5414,5421 ****
(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;
--- 5453,5463 ----
(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_CIRRUS && !cirrus_fp_register (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[1]);
+
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
DONE;
***************
*** 5425,5432 ****
(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;
--- 5467,5477 ----
(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_CIRRUS && !cirrus_fp_register (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[1]);
+
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
DONE;
***************
*** 5531,5536 ****
--- 5576,5640 ----
(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).
+
+ ;; Cirrus SF compare instruction
+ (define_insn "*cirrus_cmpsf"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
+ (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcmps%?\\tr15, %V0, %V1"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "compare")]
+ )
+
+ ;; Cirrus DF compare instruction
+ (define_insn "*cirrus_cmpdf"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
+ (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcmpd%?\\tr15, %V0, %V1"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "compare")]
+ )
+
+ ;; Cirrus DI compare instruction
+ (define_expand "cmpdi"
+ [(match_operand:DI 0 "cirrus_fp_register" "")
+ (match_operand:DI 1 "cirrus_fp_register" "")]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "{
+ arm_compare_op0 = operands[0];
+ arm_compare_op1 = operands[1];
+ DONE;
+ }")
+
+ (define_insn "*cirrus_cmpdi"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
+ (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcmp64%?\\tr15, %V0, %V1"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "compare")]
+ )
+
+ ;; Cirrus SI compare instruction
+ (define_insn "*cirrus_cmpsi_1"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_operand:SI 0 "cirrus_fp_register" "v")
+ (match_operand:SI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfcmp32%?\\tr15, %V0, %V1"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "compare")]
+ )
+
(define_insn "*cmpsf_trap"
[(set (reg:CCFPE CC_REGNUM)
(compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
***************
*** 6347,6354 ****
)
(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))]
--- 6451,6458 ----
)
(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))]
***************
*** 6361,6368 ****
)
(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))]
--- 6465,6472 ----
)
(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))]
***************
*** 6393,6400 ****
)
(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))]
--- 6497,6504 ----
)
(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))]
***************
*** 6476,6483 ****
)
(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 "" ""))]
--- 6580,6587 ----
)
(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 "" ""))]
***************
*** 8274,8279 ****
--- 8378,8386 ----
(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (const_int 0)))]
"TARGET_ARM
+ && (!TARGET_CIRRUS
+ || (!cirrus_fp_register (operands[0], SImode)
+ && !cirrus_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: gcc/config/arm/t-arm-elf
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/t-arm-elf,v
retrieving revision 1.16
diff -c -3 -p -w -r1.16 t-arm-elf
*** gcc/config/arm/t-arm-elf 8 May 2002 15:01:13 -0000 1.16
--- gcc/config/arm/t-arm-elf 10 Feb 2003 11:23:54 -0000
*************** dp-bit.c: $(srcdir)/config/fp-bit.c
*** 24,29 ****
--- 24,33 ----
MULTILIB_OPTIONS = marm/mthumb
MULTILIB_DIRNAMES = arm thumb
MULTILIB_EXCEPTIONS =
+
+ # MULTILIB_OPTIONS += mcpu=ep9312
+ # MULTILIB_DIRNAMES += ep9312
+ # MULTILIB_EXCEPTIONS += *mthumb/*mcpu=ep9312*
# MULTILIB_OPTIONS += mlittle-endian/mbig-endian
# MULTILIB_DIRNAMES += le be
Index: gcc/doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.235
diff -c -3 -p -w -r1.235 invoke.texi
*** gcc/doc/invoke.texi 8 Feb 2003 14:51:05 -0000 1.235
--- gcc/doc/invoke.texi 10 Feb 2003 11:24:12 -0000
*************** in the following sections.
*** 386,391 ****
--- 386,392 ----
-msingle-pic-base -mno-single-pic-base @gol
-mpic-register=@var{reg} @gol
-mnop-fun-dllimport @gol
+ -mcirrus-fix-invalid-insns -mno-cirrus-fix-invalid-insns @gol
-mpoke-function-name @gol
-mthumb -marm @gol
-mtpcs-frame -mtpcs-leaf-frame @gol
*************** assembly code. Permissible names are: @
*** 6132,6138 ****
@samp{strongarm}, @samp{strongarm110}, @samp{strongarm1100},
@samp{arm8}, @samp{arm810}, @samp{arm9}, @samp{arm9e}, @samp{arm920},
@samp{arm920t}, @samp{arm940t}, @samp{arm9tdmi}, @samp{arm10tdmi},
! @samp{arm1020t}, @samp{xscale}.
@itemx -mtune=@var{name}
@opindex mtune
--- 6133,6139 ----
@samp{strongarm}, @samp{strongarm110}, @samp{strongarm1100},
@samp{arm8}, @samp{arm810}, @samp{arm9}, @samp{arm9e}, @samp{arm920},
@samp{arm920t}, @samp{arm940t}, @samp{arm9tdmi}, @samp{arm10tdmi},
! @samp{arm1020t}, @samp{xscale}, @samp{ep9312}.
@itemx -mtune=@var{name}
@opindex mtune
*************** name to determine what kind of instructi
*** 6152,6158 ****
assembly code. This option can be used in conjunction with or instead
of the @option{-mcpu=} option. Permissible names are: @samp{armv2},
@samp{armv2a}, @samp{armv3}, @samp{armv3m}, @samp{armv4}, @samp{armv4t},
! @samp{armv5}, @samp{armv5t}, @samp{armv5te}.
@item -mfpe=@var{number}
@itemx -mfp=@var{number}
--- 6153,6159 ----
assembly code. This option can be used in conjunction with or instead
of the @option{-mcpu=} option. Permissible names are: @samp{armv2},
@samp{armv2a}, @samp{armv3}, @samp{armv3m}, @samp{armv4}, @samp{armv4t},
! @samp{armv5}, @samp{armv5t}, @samp{armv5te}, @samp{ep9312}.
@item -mfpe=@var{number}
@itemx -mfp=@var{number}
*************** before execution begins.
*** 6223,6228 ****
--- 6224,6241 ----
@opindex mpic-register
Specify the register to be used for PIC addressing. The default is R10
unless stack-checking is enabled, when R9 is used.
+
+ @item -mcirrus-fix-invalid-insns
+ @opindex -mcirrus-fix-invalid-insns
+ @opindex -mno-cirrus-fix-invalid-insns
+ Insert NOPs into the instruction stream to in order to work around
+ problems with invalid Maverick instruction combinations. This option
+ is only valid if the @option{-mcpu=ep9312} option has been used to
+ enable generation of instructions for the Cirrus Maverick floating
+ point co-processor. This option is not enabled by default, since the
+ problem is only present in older Maverick implemenations. The default
+ can be re-enabled by use of the @option{-mno-cirrus-fix-invalid-insns}
+ switch.
@item -mpoke-function-name
@opindex mpoke-function-name
*** /dev/null Sat Oct 19 15:41:17 2002
--- gcc/config/arm/cirrus.md Sat Feb 8 12:06:34 2003
***************
*** 0 ****
--- 1,667 ----
+ ;; Cirrus EP9312 "Maverick" ARM floating point co-processor description.
+ ;; Copyright (C) 2003 Free Software Foundation, Inc.
+ ;; Contributed by Red Hat.
+ ;; Written by Aldy Hernandez (aldyh@redhat.com)
+
+ ;; This file is part of GNU CC.
+
+ ;; GNU CC is free software; you can redistribute it and/or modify
+ ;; it under the terms of the GNU General Public License as published by
+ ;; the Free Software Foundation; either version 2, or (at your option)
+ ;; any later version.
+
+ ;; GNU CC is distributed in the hope that it will be useful,
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ ;; GNU General Public License for more details.
+
+ ;; You should have received a copy of the GNU General Public License
+ ;; along with GNU CC; see the file COPYING. If not, write to
+ ;; the Free Software Foundation, 59 Temple Place - Suite 330,
+ ;; Boston, MA 02111-1307, USA.
+
+
+ (define_attr "cirrus_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 "cirrus_type" "normal,farith,dmult" (const_string "normal"))
+
+ ; Cirrus types for invalid insn combinations
+ ; no Not a cirrus insn
+ ; yes Cirrus insn
+ ; double cfldrd, cfldr64, cfstrd, cfstr64
+ ; compare cfcmps, cfcmpd, cfcmp32, cfcmp64
+ ; move cfmvdlr, cfmvdhr, cfmvsr, cfmv64lr, cfmv64hr
+ (define_attr "cirrus" "no,yes,double,compare,move" (const_string "no"))
+
+ (define_function_unit "cirrus_fpa" 1 0
+ (and (eq_attr "cirrus_fpu" "yes")
+ (eq_attr "cirrus_type" "farith")) 4 1)
+
+ (define_function_unit "cirrus_fpa" 1 0
+ (and (eq_attr "cirrus_fpu" "yes")
+ (eq_attr "cirrus_type" "dmult")) 7 4)
+
+ (define_function_unit "cirrus_fpa" 1 0
+ (and (eq_attr "cirrus_fpu" "yes")
+ (eq_attr "cirrus_type" "normal")) 1 1)
+
+ (define_insn "cirrus_adddi3"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (plus:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:DI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfadd64%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "*cirrus_addsi3"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (plus:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfadd32%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "yes")]
+ )
+
+ ;; 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_CIRRUS
+ && !cirrus_fp_register (operands[2], SFmode))
+ operands[2] = force_reg (SFmode, operands[2]);
+ ")
+
+ (define_insn "*cirrus_addsf3"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (plus:SF (match_operand:SF 1 "cirrus_fp_register" "v")
+ (match_operand:SF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfadds%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "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_CIRRUS
+ && !cirrus_fp_register (operands[2], DFmode))
+ operands[2] = force_reg (DFmode, operands[2]);
+ ")
+
+ (define_insn "*cirrus_adddf3"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (plus:DF (match_operand:DF 1 "cirrus_fp_register" "v")
+ (match_operand:DF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfaddd%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "cirrus_subdi3"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (minus:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:DI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsub64%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "*cirrus_subsi3_insn"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (minus:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfsub32%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "yes")]
+ )
+
+ (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_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[1]);
+ if (!cirrus_fp_register (operands[2], SFmode))
+ operands[2] = force_reg (SFmode, operands[2]);
+ }
+ ")
+
+ (define_insn "*cirrus_subsf3"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (minus:SF (match_operand:SF 1 "cirrus_fp_register" "v")
+ (match_operand:SF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsubs%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "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_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[1]);
+ if (!cirrus_fp_register (operands[2], DFmode))
+ operands[2] = force_reg (DFmode, operands[2]);
+ }
+ ")
+
+ (define_insn "*cirrus_subdf3"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (minus:DF (match_operand:DF 1 "cirrus_fp_register" "v")
+ (match_operand:DF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsubd%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "*cirrus_mulsi3"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (mult:SI (match_operand:SI 2 "cirrus_fp_register" "v")
+ (match_operand:SI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfmul32%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "muldi3"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (mult:DI (match_operand:DI 2 "cirrus_fp_register" "v")
+ (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmul64%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "dmult")
+ (set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "*cirrus_mulsi3addsi"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (plus:SI
+ (mult:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_fp_register" "v"))
+ (match_operand:SI 3 "cirrus_fp_register" "0")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfmac32%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "yes")]
+ )
+
+ ;; Cirrus SI multiply-subtract
+ (define_insn "*cirrus_mulsi3subsi"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (minus:SI
+ (match_operand:SI 1 "cirrus_fp_register" "0")
+ (mult:SI (match_operand:SI 2 "cirrus_fp_register" "v")
+ (match_operand:SI 3 "cirrus_fp_register" "v"))))]
+ "0 && TARGET_ARM && TARGET_CIRRUS"
+ "cfmsc32%?\\t%V0, %V2, %V3"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "yes")]
+ )
+
+ (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_CIRRUS
+ && !cirrus_fp_register (operands[2], SFmode))
+ operands[2] = force_reg (SFmode, operands[2]);
+ ")
+
+ (define_insn "*cirrus_mulsf3"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (mult:SF (match_operand:SF 1 "cirrus_fp_register" "v")
+ (match_operand:SF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmuls%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "farith")
+ (set_attr "cirrus" "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_CIRRUS
+ && !cirrus_fp_register (operands[2], DFmode))
+ operands[2] = force_reg (DFmode, operands[2]);
+ ")
+
+ (define_insn "*cirrus_muldf3"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (mult:DF (match_operand:DF 1 "cirrus_fp_register" "v")
+ (match_operand:DF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmuld%?\\t%V0, %V1, %V2"
+ [(set_attr "cirrus_type" "dmult")
+ (set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "cirrus_ashl_const"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (ashift:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfsh32%?\\t%V0, %V1, #%s2"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "cirrus_ashiftrt_const"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (ashiftrt:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfsh32%?\\t%V0, %V1, #-%s2"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "cirrus_ashlsi3"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (ashift:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "register_operand" "r")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfrshl32%?\\t%V1, %V0, %s2"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "ashldi3_cirrus"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "register_operand" "r")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfrshl64%?\\t%V1, %V0, %s2"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "cirrus_ashldi_const"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsh64%?\\t%V0, %V1, #%s2"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "cirrus_ashiftrtdi_const"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (ashiftrt:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsh64%?\\t%V0, %V1, #-%s2"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "*cirrus_absdi2"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (abs:DI (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfabs64%?\\t%V0, %V1"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ ;; This doesn't really clobber ``cc''. Fixme: aldyh.
+ (define_insn "*cirrus_negdi2"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (neg:DI (match_operand:DI 1 "cirrus_fp_register" "v")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfneg64%?\\t%V0, %V1"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "*cirrus_negsi2"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (neg:SI (match_operand:SI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfneg32%?\\t%V0, %V1"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (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 "*cirrus_negsf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (neg:SF (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfnegs%?\\t%V0, %V1"
+ [(set_attr "cirrus" "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 "*cirrus_negdf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (neg:DF (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfnegd%?\\t%V0, %V1"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_expand "abssi2"
+ [(parallel
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (abs:SI (match_operand:SI 1 "s_register_operand" "")))
+ (clobber (reg:CC CC_REGNUM))])]
+ "TARGET_ARM"
+ "")
+
+ ;; This doesn't really clobber the condition codes either.
+ (define_insn "*cirrus_abssi2"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (abs:SI (match_operand:SI 1 "cirrus_fp_register" "v")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfabs32%?\\t%V0, %V1"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (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 "*cirrus_abssf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (abs:SF (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfabss%?\\t%V0, %V1"
+ [(set_attr "cirrus" "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 "*cirrus_absdf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (abs:DF (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfabsd%?\\t%V0, %V1"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (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_CIRRUS)
+ {
+ emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
+ DONE;
+ }
+ ")
+
+ ;; Convert Cirrus-SI to Cirrus-SF
+ (define_insn "cirrus_floatsisf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (float:SF (match_operand:SI 1 "s_register_operand" "r")))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmv64lr%?\\t%Z2, %1\;cfcvt32s%?\\t%V0, %Y2"
+ [(set_attr "length" "8")
+ (set_attr "cirrus" "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_CIRRUS)
+ {
+ emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
+ DONE;
+ }
+ ")
+
+ (define_insn "cirrus_floatsidf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (float:DF (match_operand:SI 1 "s_register_operand" "r")))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmv64lr%?\\t%Z2, %1\;cfcvt32d%?\\t%V0, %Y2"
+ [(set_attr "length" "8")
+ (set_attr "cirrus" "move")]
+ )
+
+ (define_insn "floatdisf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (float:SF (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvt64s%?\\t%V0, %V1"
+ [(set_attr "cirrus" "yes")])
+
+ (define_insn "floatdidf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (float:DF (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvt64d%?\\t%V0, %V1"
+ [(set_attr "cirrus" "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_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[0], SImode))
+ operands[0] = force_reg (SImode, operands[0]);
+ if (!cirrus_fp_register (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[0]);
+ emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
+ DONE;
+ }
+ ")
+
+ (define_insn "cirrus_truncsfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (match_operand:SF 1 "cirrus_fp_register" "v")))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cftruncs32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
+ [(set_attr "length" "8")
+ (set_attr "cirrus" "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_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[0]);
+ emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
+ DONE;
+ }
+ ")
+
+ (define_insn "cirrus_truncdfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (match_operand:DF 1 "cirrus_fp_register" "v")))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cftruncd32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
+ [(set_attr "length" "8")]
+ )
+
+ (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 "*cirrus_truncdfsf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (float_truncate:SF
+ (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvtds%?\\t%V0, %V1"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "*cirrus_extendsfdf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (float_extend:DF (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvtsd%?\\t%V0, %V1"
+ [(set_attr "cirrus" "yes")]
+ )
+
+ (define_insn "*cirrus_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_CIRRUS"
+ "*
+ {
+ 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 "cirrus" "no,no,no,move,yes,double,double,yes")]
+ )
+
+ ;; Cirrus SI values have been outlawed. Look in arm.h for the comment
+ ;; on HARD_REGNO_MODE_OK.
+
+ (define_insn "*cirrus_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_CIRRUS && 0
+ && (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 "cirrus" "no,no,no,no,move,yes,yes,yes,yes")]
+ )
+
+ (define_insn "*cirrus_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_CIRRUS
+ && (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 "cirrus" "yes,yes,move,yes,yes,no,no,no")]
+ )
+
+ (define_insn "*cirrus_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_CIRRUS
+ && (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 "cirrus" "no,no,no,no,no,yes,double,move,yes,double")]
+ )
+
Index: htdocs/gcc-3.4/changes.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-3.4/changes.html,v
retrieving revision 1.13
diff -c -3 -p -w -r1.13 changes.html
*** htdocs/gcc-3.4/changes.html 1 Feb 2003 17:41:41 -0000 1.13
--- htdocs/gcc-3.4/changes.html 10 Feb 2003 11:29:16 -0000
***************
*** 80,85 ****
--- 80,93 ----
Enabled at run time with the <code>-m2e</code> command line
switch, or at configure time by specifying sh2e as the machine
part of the target triple.</li>
+
+ <li>Support for the Cirrus EP9312 Maverick floating point
+ co-processor added to the ARM port. Enabled at run time with the
+ <code>-mcpu=ep9312</code> command line switch. Note however that
+ the multilibs to support this chip are currently disabled in
+ gcc/config/arm/t-arm-elf, so if you want to enable their
+ production you will have to uncomment the entries in that
+ file.</li>
</ul>