aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2009-11-03 16:25:29 +0000
committerNick Clifton <nickc@gcc.gnu.org>2009-11-03 16:25:29 +0000
commit9595a419c6d743670f8554b8771156d508983efc (patch)
treee2ed6b0428b652d000e627bca0a843d199164895 /gcc
parent48d3ee1d0aff2ecf2545189d878ea55aa8f78002 (diff)
downloadgcc-9595a419c6d743670f8554b8771156d508983efc.zip
gcc-9595a419c6d743670f8554b8771156d508983efc.tar.gz
gcc-9595a419c6d743670f8554b8771156d508983efc.tar.bz2
predicates.md (rx_store_multiple_vector): Reverse order of expected registers.
* config/rx/predicates.md (rx_store_multiple_vector): Reverse order of expected registers. (rx_load_multiple_vector): Likewise. (rx_rtsd_vector): Likewise. * config/rx/rx.c (rx_cpu_type): New variable. (rx_print_operand): Fix bug printing 64-bit constant values. (rx_emit_stack_pushm): Reverse order of pushed registers. (gen_rx_store_vector): Likewise. (is_fast_interrupt_func): Only accept "fast_interrupt" as the attribute name. (is_exception_func): Rename to is_interrupt_func and only accept "interrupt" as the attribute name. (rx_get_stack_layout): Use new function name. (rx_func_attr_inlinable): Likewise. (rx_attribute_table): Remove "exception". (rx_expand_prologue): If necessary push the accumulator register in the prologue of interrupt functions. (rx_expand_epilogue): If necessary pop the accumulator. (rx_builtins): Add RX_BUILTIN_MVTIPL. (rx_expand_builtin_stz): Remove. (rx_expand_builtin_mvtipl): New function. (rx_init_builtins): Handle RX_BUILTIN_MVTIPL. (rx_expand_builtin): Likewise. (rx_enable_fpu): New variable. (rx_handle_option): Handle -fpu, -nofpu, -mcpu and -patch. * config/rx/rx.h (TARGET_CPU_CPP_BUILTINS): Assert machine based on rx_cpu_type. Define __RX_FPU_INSNS__ if FPU insns are allowed. (enum rx_cpu_types): Define. (ASM_SPEC): Pass -m32bit-doubles on to assembler. (INCOMING_FRAME_SP_OFFSET): Define. (ARG_POINTER_CFA_OFFSET): Define. (FRAME_POINTER_CFA_OFFSET): Define. (OVERRIDE_OPTIONS): Enable fast math if RX FPU insns are enabled. (ALLOW_RX_FPU_INSNS): Define. * config/rx/rx.md: Test ALLOW_RX_FPU_INSNS instead of fast_math_flags_set_p. (UNSPEC_BUILTIN_MVTIPL): Define. (revl): Rename to bswapsi2. (bswaphi2): New pattern. (mvtachi): Mark as volatile because it uses a register unknown to GCC. (mvtaclo): Likewise. (racw): Likewise. (mvtc): Remove clobber of cc0. (mvtcp): Delete. (opecp): Delete. * config/rx/rx.opt (mieee): Remove. (fpu): Add. (nofpu): Add. (mcpu=): Add. (patch=): Add. (msave-acc-in-interrupts): Add. * config/rx/t-rx (MULTILIB_OPTIONS): Change default to 64bit doubles. (MULTILIB_DIRS): Likewise. (MULTILIB_MATCHES): Treat -fpu as an alias for -m32bit-doubles. * doc/extend.texi: Remove description of "exception" function attribute. * doc/invoke.texi: Document -fpu, -nofpu, -mcpu=, -patch= and -msave-acc-in-interrupts options. * gcc.target/rx/builtins,c: Remove redundant tests. Add test of MVTIPL instruction. * gcc.target/rx/interrupts.c: Use fast_interrupt and interrupt function attributes. Add -msave-acc-in-interrupts option to the command line. Co-Authored-By: Kevin Buettner <kevinb@redhat.com> From-SVN: r153853
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog64
-rw-r--r--gcc/config/rx/constraints.md2
-rw-r--r--gcc/config/rx/predicates.md18
-rw-r--r--gcc/config/rx/rx.c268
-rw-r--r--gcc/config/rx/rx.h59
-rw-r--r--gcc/config/rx/rx.md82
-rw-r--r--gcc/config/rx/rx.opt34
-rw-r--r--gcc/config/rx/t-rx6
-rw-r--r--gcc/doc/extend.texi7
-rw-r--r--gcc/doc/invoke.texi38
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.target/rx/builtins.c14
-rw-r--r--gcc/testsuite/gcc.target/rx/interrupts.c10
-rw-r--r--gcc/testsuite/gcc.target/rx/rx-abi-function-tests.c2
14 files changed, 459 insertions, 153 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 29aff02..0708ec7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,67 @@
+2009-11-03 Nick Clifton <nickc@redhat.com>
+ Kevin Buettner <kevinb@redhat.com>
+
+ * config/rx/predicates.md (rx_store_multiple_vector): Reverse
+ order of expected registers.
+ (rx_load_multiple_vector): Likewise.
+ (rx_rtsd_vector): Likewise.
+ * config/rx/rx.c (rx_cpu_type): New variable.
+ (rx_print_operand): Fix bug printing 64-bit constant values.
+ (rx_emit_stack_pushm): Reverse order of pushed registers.
+ (gen_rx_store_vector): Likewise.
+ (is_fast_interrupt_func): Only accept "fast_interrupt" as the
+ attribute name.
+ (is_exception_func): Rename to is_interrupt_func and only accept
+ "interrupt" as the attribute name.
+ (rx_get_stack_layout): Use new function name.
+ (rx_func_attr_inlinable): Likewise.
+ (rx_attribute_table): Remove "exception".
+ (rx_expand_prologue): If necessary push the accumulator register
+ in the prologue of interrupt functions.
+ (rx_expand_epilogue): If necessary pop the accumulator.
+ (rx_builtins): Add RX_BUILTIN_MVTIPL.
+ (rx_expand_builtin_stz): Remove.
+ (rx_expand_builtin_mvtipl): New function.
+ (rx_init_builtins): Handle RX_BUILTIN_MVTIPL.
+ (rx_expand_builtin): Likewise.
+ (rx_enable_fpu): New variable.
+ (rx_handle_option): Handle -fpu, -nofpu, -mcpu and -patch.
+ * config/rx/rx.h (TARGET_CPU_CPP_BUILTINS): Assert machine based
+ on rx_cpu_type. Define __RX_FPU_INSNS__ if FPU insns are allowed.
+ (enum rx_cpu_types): Define.
+ (ASM_SPEC): Pass -m32bit-doubles on to assembler.
+ (INCOMING_FRAME_SP_OFFSET): Define.
+ (ARG_POINTER_CFA_OFFSET): Define.
+ (FRAME_POINTER_CFA_OFFSET): Define.
+ (OVERRIDE_OPTIONS): Enable fast math if RX FPU insns are enabled.
+ (ALLOW_RX_FPU_INSNS): Define.
+ * config/rx/rx.md: Test ALLOW_RX_FPU_INSNS instead of
+ fast_math_flags_set_p.
+ (UNSPEC_BUILTIN_MVTIPL): Define.
+ (revl): Rename to bswapsi2.
+ (bswaphi2): New pattern.
+ (mvtachi): Mark as volatile because it uses a register unknown to
+ GCC.
+ (mvtaclo): Likewise.
+ (racw): Likewise.
+ (mvtc): Remove clobber of cc0.
+ (mvtcp): Delete.
+ (opecp): Delete.
+ * config/rx/rx.opt (mieee): Remove.
+ (fpu): Add.
+ (nofpu): Add.
+ (mcpu=): Add.
+ (patch=): Add.
+ (msave-acc-in-interrupts): Add.
+ * config/rx/t-rx (MULTILIB_OPTIONS): Change default to 64bit
+ doubles.
+ (MULTILIB_DIRS): Likewise.
+ (MULTILIB_MATCHES): Treat -fpu as an alias for -m32bit-doubles.
+ * doc/extend.texi: Remove description of "exception" function
+ attribute.
+ * doc/invoke.texi: Document -fpu, -nofpu, -mcpu=, -patch= and
+ -msave-acc-in-interrupts options.
+
2009-11-03 Richard Guenther <rguenther@suse.de>
* c-common.c (fold_offsetof_1): Use HOST_WIDE_INT_PRINT_DEC.
diff --git a/gcc/config/rx/constraints.md b/gcc/config/rx/constraints.md
index f15b586..52bf7df 100644
--- a/gcc/config/rx/constraints.md
+++ b/gcc/config/rx/constraints.md
@@ -55,7 +55,7 @@
;; This constraint is used by the SUBSI3 pattern because the
;; RX SUB instruction can only take a 4-bit unsigned integer
-;; value.
+;; value. Also used by the MVTIPL instruction.
(define_constraint "Uint04"
"@internal An unsigned 4-bit immediate value"
(and (match_code "const_int")
diff --git a/gcc/config/rx/predicates.md b/gcc/config/rx/predicates.md
index 75cf8eb..d7a363e 100644
--- a/gcc/config/rx/predicates.md
+++ b/gcc/config/rx/predicates.md
@@ -117,16 +117,22 @@
/* Check that the next element is the first push. */
element = XVECEXP (op, 0, 1);
if ( ! SET_P (element)
+ || ! REG_P (SET_SRC (element))
+ || GET_MODE (SET_SRC (element)) != SImode
|| ! MEM_P (SET_DEST (element))
- || ! REG_P (XEXP (SET_DEST (element), 0))
- || REGNO (XEXP (SET_DEST (element), 0)) != SP_REG
- || ! REG_P (SET_SRC (element)))
+ || GET_MODE (SET_DEST (element)) != SImode
+ || GET_CODE (XEXP (SET_DEST (element), 0)) != MINUS
+ || ! REG_P (XEXP (XEXP (SET_DEST (element), 0), 0))
+ || REGNO (XEXP (XEXP (SET_DEST (element), 0), 0)) != SP_REG
+ || ! CONST_INT_P (XEXP (XEXP (SET_DEST (element), 0), 1))
+ || INTVAL (XEXP (XEXP (SET_DEST (element), 0), 1))
+ != GET_MODE_SIZE (SImode))
return false;
src_regno = REGNO (SET_SRC (element));
/* Check that the remaining elements use SP-<disp>
- addressing and incremental register numbers. */
+ addressing and decreasing register numbers. */
for (i = 2; i < count; i++)
{
element = XVECEXP (op, 0, i);
@@ -134,7 +140,7 @@
if ( ! SET_P (element)
|| ! REG_P (SET_SRC (element))
|| GET_MODE (SET_SRC (element)) != SImode
- || REGNO (SET_SRC (element)) != src_regno + (i - 1)
+ || REGNO (SET_SRC (element)) != src_regno - (i - 1)
|| ! MEM_P (SET_DEST (element))
|| GET_MODE (SET_DEST (element)) != SImode
|| GET_CODE (XEXP (SET_DEST (element), 0)) != MINUS
@@ -142,7 +148,7 @@
|| REGNO (XEXP (XEXP (SET_DEST (element), 0), 0)) != SP_REG
|| ! CONST_INT_P (XEXP (XEXP (SET_DEST (element), 0), 1))
|| INTVAL (XEXP (XEXP (SET_DEST (element), 0), 1))
- != (i - 1) * GET_MODE_SIZE (SImode))
+ != i * GET_MODE_SIZE (SImode))
return false;
}
return true;
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index cf2b098..885f525 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -51,6 +51,8 @@
#include "target-def.h"
#include "langhooks.h"
+enum rx_cpu_types rx_cpu_type = RX600;
+
/* Return true if OP is a reference to an object in a small data area. */
static bool
@@ -249,7 +251,6 @@ rx_is_mode_dependent_addr (rtx addr)
}
}
-
/* A C compound statement to output to stdio stream FILE the
assembler syntax for an instruction operand that is a memory
reference whose address is ADDR. */
@@ -445,8 +446,13 @@ rx_print_operand (FILE * file, rtx op, int letter)
fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
else if (CONST_INT_P (op))
{
+ HOST_WIDE_INT v = INTVAL (op);
+
fprintf (file, "#");
- rx_print_integer (file, INTVAL (op) >> 32);
+ /* Trickery to avoid problems with shifting 32 bits at a time. */
+ v = v >> 16;
+ v = v >> 16;
+ rx_print_integer (file, v);
}
else
{
@@ -840,22 +846,20 @@ has_func_attr (const_tree decl, const char * func_attr)
return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
}
-/* Returns true if the provided function has
- the "[fast_]interrupt" attribute. */
+/* Returns true if the provided function has the "fast_interrupt" attribute. */
static inline bool
is_fast_interrupt_func (const_tree decl)
{
- return has_func_attr (decl, "interrupt")
- || has_func_attr (decl, "fast_interrupt") ;
+ return has_func_attr (decl, "fast_interrupt");
}
-/* Returns true if the provided function has the "exception" attribute. */
+/* Returns true if the provided function has the "interrupt" attribute. */
static inline bool
-is_exception_func (const_tree decl)
+is_interrupt_func (const_tree decl)
{
- return has_func_attr (decl, "exception");
+ return has_func_attr (decl, "interrupt");
}
/* Returns true if the provided function has the "naked" attribute. */
@@ -945,8 +949,8 @@ rx_set_current_function (tree fndecl)
{
/* Remember the last target of rx_set_current_function. */
static tree rx_previous_fndecl;
- bool prev_was_interrupt;
- bool current_is_interrupt;
+ bool prev_was_fast_interrupt;
+ bool current_is_fast_interrupt;
/* Only change the context if the function changes. This hook is called
several times in the course of compiling a function, and we don't want
@@ -954,18 +958,19 @@ rx_set_current_function (tree fndecl)
if (fndecl == rx_previous_fndecl)
return;
- prev_was_interrupt
+ prev_was_fast_interrupt
= rx_previous_fndecl
? is_fast_interrupt_func (rx_previous_fndecl) : false;
- current_is_interrupt
+
+ current_is_fast_interrupt
= fndecl ? is_fast_interrupt_func (fndecl) : false;
- if (prev_was_interrupt != current_is_interrupt)
+ if (prev_was_fast_interrupt != current_is_fast_interrupt)
{
- use_fixed_regs = current_is_interrupt;
+ use_fixed_regs = current_is_fast_interrupt;
target_reinit ();
}
-
+
rx_previous_fndecl = fndecl;
}
@@ -1057,8 +1062,8 @@ rx_get_stack_layout (unsigned int * lowest,
if (df_regs_ever_live_p (reg)
&& (! call_used_regs[reg]
/* Even call clobbered registered must
- be pushed inside exception handlers. */
- || is_exception_func (NULL_TREE)))
+ be pushed inside interrupt handlers. */
+ || is_interrupt_func (NULL_TREE)))
{
if (low == 0)
low = reg;
@@ -1142,9 +1147,8 @@ rx_emit_stack_pushm (rtx * operands)
gcc_assert (REG_P (first_push));
asm_fprintf (asm_out_file, "\tpushm\t%s-%s\n",
- reg_names [REGNO (first_push)],
- reg_names [REGNO (first_push) + last_reg]);
-
+ reg_names [REGNO (first_push) - last_reg],
+ reg_names [REGNO (first_push)]);
}
/* Generate a PARALLEL that will pass the rx_store_multiple_vector predicate. */
@@ -1167,14 +1171,30 @@ gen_rx_store_vector (unsigned int low, unsigned int high)
XVECEXP (vector, 0, i + 1) =
gen_rtx_SET (SImode,
gen_rtx_MEM (SImode,
- i == 0 ? stack_pointer_rtx
- : gen_rtx_MINUS (SImode, stack_pointer_rtx,
- GEN_INT (i * UNITS_PER_WORD))),
- gen_rtx_REG (SImode, low + i));
-
+ gen_rtx_MINUS (SImode, stack_pointer_rtx,
+ GEN_INT ((i + 1) * UNITS_PER_WORD))),
+ gen_rtx_REG (SImode, high - i));
return vector;
}
+/* Mark INSN as being frame related. If it is a PARALLEL
+ then mark each element as being frame related as well. */
+
+static void
+mark_frame_related (rtx insn)
+{
+ RTX_FRAME_RELATED_P (insn) = 1;
+ insn = PATTERN (insn);
+
+ if (GET_CODE (insn) == PARALLEL)
+ {
+ unsigned int i;
+
+ for (i = 0; i < XVECLEN (insn, 0); i++)
+ RTX_FRAME_RELATED_P (XVECEXP (insn, 0, i)) = 1;
+ }
+}
+
void
rx_expand_prologue (void)
{
@@ -1183,6 +1203,7 @@ rx_expand_prologue (void)
unsigned int mask;
unsigned int low;
unsigned int high;
+ unsigned int reg;
rtx insn;
/* Naked functions use their own, programmer provided prologues. */
@@ -1196,14 +1217,12 @@ rx_expand_prologue (void)
/* If we use any of the callee-saved registers, save them now. */
if (mask)
{
- unsigned int reg;
-
/* Push registers in reverse order. */
for (reg = FIRST_PSEUDO_REGISTER; reg --;)
if (mask & (1 << reg))
{
insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg)));
- RTX_FRAME_RELATED_P (insn) = 1;
+ mark_frame_related (insn);
}
}
else if (low)
@@ -1214,7 +1233,57 @@ rx_expand_prologue (void)
insn = emit_insn (gen_stack_pushm (GEN_INT (((high - low) + 1)
* UNITS_PER_WORD),
gen_rx_store_vector (low, high)));
- RTX_FRAME_RELATED_P (insn) = 1;
+ mark_frame_related (insn);
+ }
+
+ if (is_interrupt_func (NULL_TREE) && TARGET_SAVE_ACC_REGISTER)
+ {
+ unsigned int acc_high, acc_low;
+
+ /* Interrupt handlers have to preserve the accumulator
+ register if so requested by the user. Use the first
+ two pushed register as intermediaries. */
+ if (mask)
+ {
+ acc_low = acc_high = 0;
+
+ for (reg = 1; reg < FIRST_PSEUDO_REGISTER; reg ++)
+ if (mask & (1 << reg))
+ {
+ if (acc_low == 0)
+ acc_low = reg;
+ else
+ {
+ acc_high = reg;
+ break;
+ }
+ }
+
+ /* We have assumed that there are at least two registers pushed... */
+ gcc_assert (acc_high != 0);
+
+ /* Note - the bottom 16 bits of the accumulator are inaccessible.
+ We just assume that they are zero. */
+ emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
+ emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
+ emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_low)));
+ emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_high)));
+ }
+ else
+ {
+ acc_low = low;
+ acc_high = low + 1;
+
+ /* We have assumed that there are at least two registers pushed... */
+ gcc_assert (acc_high <= high);
+
+ emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
+ emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
+ emit_insn (gen_stack_pushm (GEN_INT (2 * UNITS_PER_WORD),
+ gen_rx_store_vector (acc_low, acc_high)));
+ }
+
+ frame_size += 2 * UNITS_PER_WORD;
}
/* If needed, set up the frame pointer. */
@@ -1270,8 +1339,8 @@ rx_output_function_prologue (FILE * file,
if (is_fast_interrupt_func (NULL_TREE))
asm_fprintf (file, "\t; Note: Fast Interrupt Handler\n");
- if (is_exception_func (NULL_TREE))
- asm_fprintf (file, "\t; Note: Exception Handler\n");
+ if (is_interrupt_func (NULL_TREE))
+ asm_fprintf (file, "\t; Note: Interrupt Handler\n");
if (is_naked_func (NULL_TREE))
asm_fprintf (file, "\t; Note: Naked Function\n");
@@ -1382,6 +1451,7 @@ rx_expand_epilogue (bool is_sibcall)
unsigned int stack_size;
unsigned int register_mask;
unsigned int regs_size;
+ unsigned int reg;
unsigned HOST_WIDE_INT total_size;
if (is_naked_func (NULL_TREE))
@@ -1407,14 +1477,14 @@ rx_expand_epilogue (bool is_sibcall)
their caller. Instead they branch to their sibling and allow their
return instruction to return to this function's parent.
- - Fast interrupt and exception handling functions have to use special
+ - Fast and normal interrupt handling functions have to use special
return instructions.
- Functions where we have pushed a fragmented set of registers into the
call-save area must have the same set of registers popped. */
if (is_sibcall
|| is_fast_interrupt_func (NULL_TREE)
- || is_exception_func (NULL_TREE)
+ || is_interrupt_func (NULL_TREE)
|| register_mask)
{
/* Cannot use the special instructions - deconstruct by hand. */
@@ -1422,10 +1492,47 @@ rx_expand_epilogue (bool is_sibcall)
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (total_size)));
- if (register_mask)
+ if (is_interrupt_func (NULL_TREE) && TARGET_SAVE_ACC_REGISTER)
{
- unsigned int reg;
+ unsigned int acc_low, acc_high;
+
+ /* Reverse the saving of the accumulator register onto the stack.
+ Note we must adjust the saved "low" accumulator value as it
+ is really the middle 32-bits of the accumulator. */
+ if (register_mask)
+ {
+ acc_low = acc_high = 0;
+ for (reg = 1; reg < FIRST_PSEUDO_REGISTER; reg ++)
+ if (register_mask & (1 << reg))
+ {
+ if (acc_low == 0)
+ acc_low = reg;
+ else
+ {
+ acc_high = reg;
+ break;
+ }
+ }
+ emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_high)));
+ emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_low)));
+ }
+ else
+ {
+ acc_low = low;
+ acc_high = low + 1;
+ emit_insn (gen_stack_popm (GEN_INT (2 * UNITS_PER_WORD),
+ gen_rx_popm_vector (acc_low, acc_high)));
+ }
+
+ emit_insn (gen_ashlsi3 (gen_rtx_REG (SImode, acc_low),
+ gen_rtx_REG (SImode, acc_low),
+ GEN_INT (16)));
+ emit_insn (gen_mvtaclo (gen_rtx_REG (SImode, acc_low)));
+ emit_insn (gen_mvtachi (gen_rtx_REG (SImode, acc_high)));
+ }
+ if (register_mask)
+ {
for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg ++)
if (register_mask & (1 << reg))
emit_insn (gen_stack_pop (gen_rtx_REG (SImode, reg)));
@@ -1441,7 +1548,7 @@ rx_expand_epilogue (bool is_sibcall)
if (is_fast_interrupt_func (NULL_TREE))
emit_jump_insn (gen_fast_interrupt_return ());
- else if (is_exception_func (NULL_TREE))
+ else if (is_interrupt_func (NULL_TREE))
emit_jump_insn (gen_exception_return ());
else if (! is_sibcall)
emit_jump_insn (gen_simple_return ());
@@ -1670,6 +1777,7 @@ enum rx_builtin
RX_BUILTIN_MVTACHI,
RX_BUILTIN_MVTACLO,
RX_BUILTIN_MVTC,
+ RX_BUILTIN_MVTIPL,
RX_BUILTIN_RACW,
RX_BUILTIN_REVW,
RX_BUILTIN_RMPA,
@@ -1725,6 +1833,7 @@ rx_init_builtins (void)
ADD_RX_BUILTIN1 (RMPA, "rmpa", void, void);
ADD_RX_BUILTIN1 (MVFC, "mvfc", intSI, integer);
ADD_RX_BUILTIN2 (MVTC, "mvtc", void, integer, integer);
+ ADD_RX_BUILTIN1 (MVTIPL, "mvtipl", void, integer);
ADD_RX_BUILTIN1 (RACW, "racw", void, integer);
ADD_RX_BUILTIN1 (ROUND, "round", intSI, float);
ADD_RX_BUILTIN1 (REVW, "revw", intSI, intSI);
@@ -1733,20 +1842,6 @@ rx_init_builtins (void)
}
static rtx
-rx_expand_builtin_stz (rtx arg, rtx target, rtx (* gen_func)(rtx, rtx))
-{
- if (! CONST_INT_P (arg))
- return NULL_RTX;
-
- if (target == NULL_RTX || ! REG_P (target))
- target = gen_reg_rtx (SImode);
-
- emit_insn (gen_func (target, arg));
-
- return target;
-}
-
-static rtx
rx_expand_void_builtin_1_arg (rtx arg, rtx (* gen_func)(rtx), bool reg)
{
if (reg && ! REG_P (arg))
@@ -1791,6 +1886,21 @@ rx_expand_builtin_mvfc (tree t_arg, rtx target)
}
static rtx
+rx_expand_builtin_mvtipl (rtx arg)
+{
+ /* The RX610 does not support the MVTIPL instruction. */
+ if (rx_cpu_type == RX610)
+ return NULL_RTX;
+
+ if (! CONST_INT_P (arg) || ! IN_RANGE (arg, 0, (1 << 4) - 1))
+ return NULL_RTX;
+
+ emit_insn (gen_mvtipl (arg));
+
+ return NULL_RTX;
+}
+
+static rtx
rx_expand_builtin_mac (tree exp, rtx (* gen_func)(rtx, rtx))
{
rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
@@ -1887,6 +1997,7 @@ rx_expand_builtin (tree exp,
case RX_BUILTIN_RMPA: emit_insn (gen_rmpa ()); return NULL_RTX;
case RX_BUILTIN_MVFC: return rx_expand_builtin_mvfc (arg, target);
case RX_BUILTIN_MVTC: return rx_expand_builtin_mvtc (exp);
+ case RX_BUILTIN_MVTIPL: return rx_expand_builtin_mvtipl (op);
case RX_BUILTIN_RACW: return rx_expand_void_builtin_1_arg
(op, gen_racw, false);
case RX_BUILTIN_ROUND: return rx_expand_builtin_round (op, target);
@@ -1945,7 +2056,7 @@ rx_elf_asm_destructor (rtx symbol, int priority)
rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */false);
}
-/* Check "interrupt", "exception" and "naked" attributes. */
+/* Check "fast_interrupt", "interrupt" and "naked" attributes. */
static tree
rx_handle_func_attribute (tree * node,
@@ -1975,9 +2086,8 @@ rx_handle_func_attribute (tree * node,
const struct attribute_spec rx_attribute_table[] =
{
/* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler. */
- { "interrupt", 0, 0, true, false, false, rx_handle_func_attribute },
{ "fast_interrupt", 0, 0, true, false, false, rx_handle_func_attribute },
- { "exception", 0, 0, true, false, false, rx_handle_func_attribute },
+ { "interrupt", 0, 0, true, false, false, rx_handle_func_attribute },
{ "naked", 0, 0, true, false, false, rx_handle_func_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};
@@ -1993,7 +2103,7 @@ static bool
rx_func_attr_inlinable (const_tree decl)
{
return ! is_fast_interrupt_func (decl)
- && ! is_exception_func (decl)
+ && ! is_interrupt_func (decl)
&& ! is_naked_func (decl);
}
@@ -2115,6 +2225,20 @@ rx_is_legitimate_constant (rtx x)
( 1 << (rx_max_constant_size * 8)));
}
+/* This is a tri-state variable. The default value of 0 means that the user
+ has specified neither -mfpu nor -mnofpu on the command line. In this case
+ the selection of RX FPU instructions is entirely based upon the size of
+ the floating point object and whether unsafe math optimizations were
+ enabled. If 32-bit doubles have been enabled then both floats and doubles
+ can make use of FPU instructions, otherwise only floats may do so.
+
+ If the value is 1 then the user has specified -mfpu and the FPU
+ instructions should be used. Unsafe math optimizations will automatically
+ be enabled and doubles set to 32-bits. If the value is -1 then -mnofpu
+ has been specified and FPU instructions will not be used, even if unsafe
+ math optimizations have been enabled. */
+int rx_enable_fpu = 0;
+
/* Extra processing for target specific command line options. */
static bool
@@ -2122,6 +2246,27 @@ rx_handle_option (size_t code, const char * arg ATTRIBUTE_UNUSED, int value)
{
switch (code)
{
+ /* -mfpu enables the use of RX FPU instructions. This implies the use
+ of 32-bit doubles and also the enabling of fast math optimizations.
+ (Since the RX FPU instructions are not IEEE compliant). The -mnofpu
+ option disables the use of RX FPU instructions, but does not make
+ place any constraints on the size of doubles or the use of fast math
+ optimizations.
+
+ The selection of 32-bit vs 64-bit doubles is handled by the setting
+ of the 32BIT_DOUBLES mask in the rx.opt file. Enabling fast math
+ optimizations is performed in OVERRIDE_OPTIONS since if it was done
+ here it could be overridden by a -fno-fast-math option specified
+ *earlier* on the command line. (Target specific options are
+ processed before generic ones). */
+ case OPT_fpu:
+ rx_enable_fpu = 1;
+ break;
+
+ case OPT_nofpu:
+ rx_enable_fpu = -1;
+ break;
+
case OPT_mint_register_:
switch (value)
{
@@ -2145,12 +2290,21 @@ rx_handle_option (size_t code, const char * arg ATTRIBUTE_UNUSED, int value)
break;
case OPT_mmax_constant_size_:
- /* Make sure that the the -mmax-constant_size option is in range. */
+ /* Make sure that the -mmax-constant_size option is in range. */
return IN_RANGE (value, 0, 4);
+ case OPT_mcpu_:
+ case OPT_patch_:
+ if (strcasecmp (arg, "RX610") == 0)
+ rx_cpu_type = RX610;
+ /* FIXME: Should we check for non-RX cpu names here ? */
+ break;
+
default:
- return true;
+ break;
}
+
+ return true;
}
static int
diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h
index a01e194..bb7cf7f 100644
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -24,18 +24,24 @@
{ \
builtin_define ("__RX__"); \
builtin_assert ("cpu=RX"); \
- builtin_assert ("machine=RX"); \
+ if (rx_cpu_type == RX610) \
+ builtin_assert ("machine=RX610"); \
+ else \
+ builtin_assert ("machine=RX600"); \
\
if (TARGET_BIG_ENDIAN_DATA) \
builtin_define ("__RX_BIG_ENDIAN__"); \
else \
builtin_define ("__RX_LITTLE_ENDIAN__");\
\
- if (TARGET_64BIT_DOUBLES) \
- builtin_define ("__RX_64BIT_DOUBLES__");\
- else \
+ if (TARGET_32BIT_DOUBLES) \
builtin_define ("__RX_32BIT_DOUBLES__");\
+ else \
+ builtin_define ("__RX_64BIT_DOUBLES__");\
\
+ if (ALLOW_RX_FPU_INSNS) \
+ builtin_define ("__RX_FPU_INSNS__"); \
+ \
if (TARGET_AS100_SYNTAX) \
builtin_define ("__RX_AS100_SYNTAX__"); \
else \
@@ -43,6 +49,17 @@
} \
while (0)
+enum rx_cpu_types
+{
+ RX600,
+ RX610
+};
+
+extern enum rx_cpu_types rx_cpu_type;
+
+#undef CC1_SPEC
+#define CC1_SPEC "%{mas100-syntax:%{gdwarf*:%e-mas100-syntax is incompatible with -gdwarf}}"
+
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s} crtbegin.o%s"
@@ -52,7 +69,8 @@
#undef ASM_SPEC
#define ASM_SPEC "\
%{mbig-endian-data:-mbig-endian-data} \
-%{m64bit-doubles:-m64bit-doubles} \
+%{m32bit-doubles:-m32bit-doubles} \
+%{!m32bit-doubles:-m64bit-doubles} \
%{msmall-data-limit*:-msmall-data-limit} \
%{mrelax:-relax} \
"
@@ -88,16 +106,17 @@
#define LONG_LONG_TYPE_SIZE 64
#define FLOAT_TYPE_SIZE 32
-#define DOUBLE_TYPE_SIZE (TARGET_64BIT_DOUBLES ? 64 : 32)
+#define DOUBLE_TYPE_SIZE (TARGET_32BIT_DOUBLES ? 32 : 64)
#define LONG_DOUBLE_TYPE_SIZE DOUBLE_TYPE_SIZE
-#ifdef __RX_64BIT_DOUBLES__
-#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
-#define LIBGCC2_DOUBLE_TYPE_SIZE 64
-#define LIBGCC2_HAS_DF_MODE 1
-#else
+#ifdef __RX_32BIT_DOUBLES__
+#define LIBGCC2_HAS_DF_MODE 0
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 32
#define LIBGCC2_DOUBLE_TYPE_SIZE 32
+#else
+#define LIBGCC2_HAS_DF_MODE 1
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#define LIBGCC2_DOUBLE_TYPE_SIZE 64
#endif
#define DEFAULT_SIGNED_CHAR 0
@@ -591,7 +610,6 @@ typedef unsigned int CUMULATIVE_ARGS;
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
rx_print_operand_address (FILE, ADDR)
-
#define CC_NO_CARRY 0400
#define NOTICE_UPDATE_CC(EXP, INSN) rx_notice_update_cc (EXP, INSN)
@@ -614,19 +632,28 @@ extern int rx_float_compare_mode;
#define PREFERRED_DEBUGGING_TYPE (TARGET_AS100_SYNTAX \
? DBX_DEBUG : DWARF2_DEBUG)
-#undef CC1_SPEC
-#define CC1_SPEC "%{mas100-syntax:%{gdwarf*:%e-mas100-syntax is incompatible with -gdwarf}}"
+#define INCOMING_FRAME_SP_OFFSET 4
+#define ARG_POINTER_CFA_OFFSET(FNDECL) 4
+#define FRAME_POINTER_CFA_OFFSET(FNDECL) 4
+
+extern int rx_enable_fpu;
/* For some unknown reason LTO compression is not working, at
least on my local system. So set the default compression
- level to none, for now. */
+ level to none, for now.
+
+ For an explanation of rx_flag_no_fpu see rx_handle_option(). */
#define OVERRIDE_OPTIONS \
do \
{ \
if (flag_lto_compression_level == -1) \
flag_lto_compression_level = 0; \
+ \
+ if (rx_enable_fpu == 1) \
+ set_fast_math_flags (true); \
} \
while (0)
/* This macro is used to decide when RX FPU instructions can be used. */
-#define ALLOW_RX_FPU_INSNS flag_unsafe_math_optimizations
+#define ALLOW_RX_FPU_INSNS ((rx_enable_fpu != -1) \
+ && flag_unsafe_math_optimizations)
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index 165da4f..360f623 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -27,8 +27,8 @@
;; This code iterator is used for sign- and zero- extensions.
(define_mode_iterator small_int_modes [(HI "") (QI "")])
-;; We do not handle DFmode here because by default it is
-;; the same as SFmode, and if -m64bit-doubles is active
+;; We do not handle DFmode here because it is either
+;; the same as SFmode, or if -m64bit-doubles is active
;; then all operations on doubles have to be handled by
;; library functions.
(define_mode_iterator register_modes
@@ -75,15 +75,14 @@
(UNSPEC_BUILTIN_MVTACHI 41)
(UNSPEC_BUILTIN_MVTACLO 42)
(UNSPEC_BUILTIN_MVTC 43)
- (UNSPEC_BUILTIN_MVTCP 44)
- (UNSPEC_BUILTIN_OPEPC 45)
- (UNSPEC_BUILTIN_RACW 46)
- (UNSPEC_BUILTIN_REVW 47)
- (UNSPEC_BUILTIN_RMPA 48)
- (UNSPEC_BUILTIN_ROUND 49)
- (UNSPEC_BUILTIN_SAT 50)
- (UNSPEC_BUILTIN_SETPSW 51)
- (UNSPEC_BUILTIN_WAIT 52)
+ (UNSPEC_BUILTIN_MVTIPL 44)
+ (UNSPEC_BUILTIN_RACW 45)
+ (UNSPEC_BUILTIN_REVW 46)
+ (UNSPEC_BUILTIN_RMPA 47)
+ (UNSPEC_BUILTIN_ROUND 48)
+ (UNSPEC_BUILTIN_SAT 49)
+ (UNSPEC_BUILTIN_SETPSW 50)
+ (UNSPEC_BUILTIN_WAIT 51)
]
)
@@ -1002,10 +1001,8 @@
(set_attr "timings" "11,11,11,11,11,33")
(set_attr "length" "3,4,5,6,7,6")]
)
-
+
;; Floating Point Instructions
-;; These patterns are only enabled with -ffast-math because the RX FPU
-;; cannot handle sub-normal values.
(define_insn "addsf3"
[(set (match_operand:SF 0 "register_operand" "=r,r,r")
@@ -1298,7 +1295,6 @@
[(set_attr "length" "3,6")
(set_attr "timings" "22")]
)
-
;; Block move functions.
@@ -1580,8 +1576,8 @@
;; Move to Accumulator (high)
(define_insn "mvtachi"
- [(unspec:SI [(match_operand:SI 0 "register_operand" "r")]
- UNSPEC_BUILTIN_MVTACHI)]
+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
+ UNSPEC_BUILTIN_MVTACHI)]
""
"mvtachi\t%0"
[(set_attr "length" "3")]
@@ -1589,8 +1585,8 @@
;; Move to Accumulator (low)
(define_insn "mvtaclo"
- [(unspec:SI [(match_operand:SI 0 "register_operand" "r")]
- UNSPEC_BUILTIN_MVTACLO)]
+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
+ UNSPEC_BUILTIN_MVTACLO)]
""
"mvtaclo\t%0"
[(set_attr "length" "3")]
@@ -1598,8 +1594,8 @@
;; Round Accumulator
(define_insn "racw"
- [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")]
- UNSPEC_BUILTIN_RACW)]
+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")]
+ UNSPEC_BUILTIN_RACW)]
""
"racw\t%0"
[(set_attr "length" "3")]
@@ -1679,7 +1675,7 @@
;; Move from control register
(define_insn "mvfc"
- [(set (match_operand:SI 0 "register_operand" "=r")
+ [(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "immediate_operand" "i")]
UNSPEC_BUILTIN_MVFC))]
""
@@ -1691,13 +1687,24 @@
(define_insn "mvtc"
[(unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i")
(match_operand:SI 1 "nonmemory_operand" "r,i")]
- UNSPEC_BUILTIN_MVTC)
- (clobber (cc0))]
+ UNSPEC_BUILTIN_MVTC)]
""
"mvtc\t%1, %C0"
- [(set_attr "length" "3,7")
- (set_attr "cc" "clobber")] ;; Just in case the control
- ;; register selected is the psw.
+ [(set_attr "length" "3,7")]
+ ;; Ignore possible clobbering of the comparison flags in the
+ ;; PSW register. This is a cc0 target so any cc0 setting
+ ;; instruction will always be paired with a cc0 user, without
+ ;; the possibility of this instruction being placed in between
+ ;; them.
+)
+
+;; Move to interrupt priority level
+(define_insn "mvtipl"
+ [(unspec:SI [(match_operand:SI 0 "immediate_operand" "Uint04")]
+ UNSPEC_BUILTIN_MVTIPL)]
+ ""
+ "mvtipl\t%0"
+ [(set_attr "length" "3")]
)
;;---------- Interrupts ------------------------
@@ -1748,27 +1755,6 @@
[(set_attr "length" "5")]
)
-;; Move to co-processor register
-(define_insn "mvtcp"
- [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i")
- (match_operand:SI 1 "nonmemory_operand" "i,r")
- (match_operand:SI 2 "immediate_operand" "i,i")]
- UNSPEC_BUILTIN_MVTCP)]
- ""
- "; mvtcp\t%0, %1, %2"
- [(set_attr "length" "7,5")]
-)
-
-;; Co-processor operation
-(define_insn "opecp"
- [(unspec:SI [(match_operand:SI 0 "immediate_operand" "i")
- (match_operand:SI 1 "immediate_operand" "i")]
- UNSPEC_BUILTIN_OPEPC)]
- ""
- "; opecp\t%0, %1"
- [(set_attr "length" "5")]
-)
-
;;---------- Misc ------------------------
;; Required by cfglayout.c...
diff --git a/gcc/config/rx/rx.opt b/gcc/config/rx/rx.opt
index 83e75bf..768d565 100644
--- a/gcc/config/rx/rx.opt
+++ b/gcc/config/rx/rx.opt
@@ -19,13 +19,31 @@
; <http://www.gnu.org/licenses/>.
;---------------------------------------------------
+m32bit-doubles
+Target RejectNegative Mask(32BIT_DOUBLES)
+Stores doubles in 32 bits.
+
m64bit-doubles
-Target RejectNegative Mask(64BIT_DOUBLES)
-Store doubles in 64 bits.
+Target RejectNegative InverseMask(32BIT_DOUBLES)
+Store doubles in 64 bits. This is the default.
-m32bit-doubles
-Target RejectNegative InverseMask(64BIT_DOUBLES)
-Stores doubles in 32 bits. This is the default.
+fpu
+Target RejectNegative Mask(32BIT_DOUBLES) MaskExists
+Enable the use of RX FPU instructions.
+
+nofpu
+Target RejectNegative InverseMask(32BIT_DOUBLES) MaskExists
+Disable the use of RX FPU instructions.
+
+;---------------------------------------------------
+
+mcpu=
+Target RejectNegative Joined Var(rx_cpu_name)
+Specify the target RX cpu type.
+
+patch=
+Target RejectNegative Joined Var(rx_cpu_name)
+Alias for -mcpu.
;---------------------------------------------------
@@ -72,3 +90,9 @@ Maximum size in bytes of constant values allowed as operands.
mint-register=
Target RejectNegative Joined UInteger Var(rx_interrupt_registers) Init(0)
Specifies the number of registers to reserve for interrupt handlers.
+
+;---------------------------------------------------
+
+msave-acc-in-interrupts
+Target Mask(SAVE_ACC_REGISTER)
+Specifies whether interrupt functions should save and restore the accumulator register.
diff --git a/gcc/config/rx/t-rx b/gcc/config/rx/t-rx
index 39cda72..eb1ca48 100644
--- a/gcc/config/rx/t-rx
+++ b/gcc/config/rx/t-rx
@@ -20,9 +20,9 @@
# Enable multilibs:
-MULTILIB_OPTIONS = m64bit-doubles mbig-endian-data
-MULTILIB_DIRNAMES = 64fp big-endian-data
-MULTILIB_MATCHES = m64bit-doubles=mieee
+MULTILIB_OPTIONS = m32bit-doubles mbig-endian-data
+MULTILIB_DIRNAMES = 32fp big-endian-data
+MULTILIB_MATCHES = m32bit-doubles=fpu
MULTILIB_EXCEPTIONS =
MULTILIB_EXTRA_OPTS =
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index cb764c6..bfcc5fb 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2270,13 +2270,6 @@ on data in the eight bit data area. Note the eight bit data area is limited to
You must use GAS and GLD from GNU binutils version 2.7 or later for
this attribute to work correctly.
-@item exception
-@cindex exception handler functions on the RX processor
-Use this attribute on the RX to indicate that the specified function
-is an exception handler. The compiler will generate function entry and
-exit sequences suitable for use in an exception handler when this
-attribute is present.
-
@item exception_handler
@cindex exception handler functions on the Blackfin processor
Use this attribute on the Blackfin to indicate that the specified function
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 93d87cc..ed652ec 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -784,14 +784,16 @@ See RS/6000 and PowerPC Options.
-msdata=@var{opt} -mvxworks -G @var{num} -pthread}
@emph{RX Options}
-@gccoptlist{-m64bit-doubles -m32bit-doubles -mieee -mno-ieee@gol
+@gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol
+-mcpu= -patch=@gol
-mbig-endian-data -mlittle-endian-data @gol
-msmall-data @gol
-msim -mno-sim@gol
-mas100-syntax -mno-as100-syntax@gol
-mrelax@gol
-mmax-constant-size=@gol
--mint-register=}
+-mint-register=@gol
+-msave-acc-in-interrupts}
@emph{S/390 and zSeries Options}
@gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol
@@ -15408,16 +15410,37 @@ These @option{-m} options are defined for RX implementations:
@table @gcctabopt
@item -m64bit-doubles
@itemx -m32bit-doubles
+@itemx -fpu
+@itemx -nofpu
@opindex m64bit-doubles
@opindex m32bit-doubles
+@opindex fpu
+@opindex nofpu
Make the @code{double} data type be 64-bits (@option{-m64bit-doubles})
or 32-bits (@option{-m32bit-doubles}) in size. The default is
-@option{-m32bit-doubles}. @emph{Note} the RX's hardware floating
+@option{-m64bit-doubles}. @emph{Note} the RX's hardware floating
point instructions are only used for 32-bit floating point values, and
then only if @option{-ffast-math} has been specified on the command
line. This is because the RX FPU instructions do not properly support
denormal (or sub-normal) values.
+The options @option{-fpu} and @option{-nofpu} have been provided at
+the request of Rensas for compatibility with their toolchain. The
+@option{-mfpu} option enables the use of RX FPU instructions by
+selecting 32-bit doubles and enabling unsafe math optimizations. The
+@option{-mnofpu} option disables the use of RX FPU instructions, even
+if @option{-m32bit-doubles} is active and unsafe math optimizations
+have been enabled.
+
+@item -mcpu=@var{name}
+@itemx -patch=@var{name}
+@opindex -mcpu
+@opindex -patch
+Selects the type of RX CPU to be targeted. Currently on two types are
+supported, the generic @var{RX600} and the specific @var{RX610}. The
+only difference between them is that the @var{RX610} does not support
+the @code{MVTIPL} instruction.
+
@item -mbig-endian-data
@itemx -mlittle-endian-data
@opindex mbig-endian-data
@@ -15493,6 +15516,15 @@ of fast interrupt handlers. A value of 2 reserves @code{r13} and
@code{r12}. A value of 3 reserves @code{r13}, @code{r12} and
@code{r11}, and a value of 4 reserves @code{r13} through @code{r10}.
A value of 0, the default, does not reserve any registers.
+
+@item -msave-acc-in-interrupts
+@opindex msave-acc-in-interrupts
+Specifies that interrupt handler functions should preserve the
+accumulator register. This is only necessary if normal code might use
+the accumulator register, for example because it performs 64-bit
+multiplications. The default is to ignore the accumulator as this
+makes the interrupt handlers faster.
+
@end table
@emph{Note:} The generic GCC command line @option{-ffixed-@var{reg}}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d3ad5c7..32e07cc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2009-11-03 Nick Clifton <nickc@redhat.com>
+
+ * gcc.target/rx/builtins,c: Remove redundant tests.
+ Add test of MVTIPL instruction.
+ * gcc.target/rx/interrupts.c: Use fast_interrupt and interrupt
+ function attributes. Add -msave-acc-in-interrupts option to the
+ command line.
+
2009-11-03 Andrew Stubbs <ams@codesourcery.com>
Maxim Kuvyrkov <maxim@codesourcery.com>
diff --git a/gcc/testsuite/gcc.target/rx/builtins.c b/gcc/testsuite/gcc.target/rx/builtins.c
index 0744802..2a6241d 100644
--- a/gcc/testsuite/gcc.target/rx/builtins.c
+++ b/gcc/testsuite/gcc.target/rx/builtins.c
@@ -17,7 +17,6 @@
to correctly set the psw flags. */
int saturate_add (int, int) __attribute__((__noinline__));
-int subtract_with_borrow (int, int, int) __attribute__((__noinline__));
int exchange (int, int) __attribute__((__noinline__));
int
@@ -33,6 +32,13 @@ saturate_add (int arg1, int arg2)
return __builtin_rx_sat (arg1);
}
+int
+exchange (int arg1, int arg2)
+{
+ arg1 = __builtin_rx_xchg (arg2);
+ return arg1;
+}
+
long
multiply_and_accumulate (long arg1, long arg2, long arg3)
{
@@ -157,3 +163,9 @@ rmpa (int * multiplicand, int * multiplier, int num)
{
__builtin_rx_rmpa ();
}
+
+void
+set_interrupts (void)
+{
+ __builtin_mvtipl (3);
+}
diff --git a/gcc/testsuite/gcc.target/rx/interrupts.c b/gcc/testsuite/gcc.target/rx/interrupts.c
index 910e870..cdc4903 100644
--- a/gcc/testsuite/gcc.target/rx/interrupts.c
+++ b/gcc/testsuite/gcc.target/rx/interrupts.c
@@ -1,10 +1,10 @@
/* { dg-do compile } */
-/* { dg-options "-mint-register=3" } */
+/* { dg-options "-mint-register=3 -msave-acc-in-interrupts" } */
/* Verify that the RX specific function attributes work. */
+void fast_interrupt (void) __attribute__((__fast_interrupt__));
void interrupt (void) __attribute__((__interrupt__));
-void exception (void) __attribute__((__exception__));
int naked (int) __attribute__((__naked__));
int flag = 0;
@@ -13,16 +13,16 @@ int flag = 0;
by the -fixed-xxx gcc command line option. Returns via RTFI. */
void
-interrupt (void)
+fast_interrupt (void)
{
flag = 1;
}
-/* Exception handler. Must preserve any register it uses, even
+/* Interrupt handler. Must preserve any register it uses, even
call clobbered ones. Returns via RTE. */
void
-exception (void)
+interrupt (void)
{
switch (flag)
{
diff --git a/gcc/testsuite/gcc.target/rx/rx-abi-function-tests.c b/gcc/testsuite/gcc.target/rx/rx-abi-function-tests.c
index 0c4ec3f..e07ff71 100644
--- a/gcc/testsuite/gcc.target/rx/rx-abi-function-tests.c
+++ b/gcc/testsuite/gcc.target/rx/rx-abi-function-tests.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-options "-msim" } */
-/* Note: The -msim abiove is actually there to override the default
+/* Note: The -msim above is actually there to override the default
options which include -ansi -pendantic and -Wlong-long... */
extern int printf (const char *, ...);