/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010 Free Software Foundation, Inc.
+ 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
This file is part of GCC.
#include "function.h"
#include "optabs.h"
#include "diagnostic-core.h"
-#include "toplev.h"
#include "basic-block.h"
#include "tm_p.h"
#include "ggc.h"
-#include <ctype.h>
#include "target.h"
#include "target-def.h"
#include "targhooks.h"
/* Map register number to smallest register class. */
enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
-/* Map class letter into register class. */
-enum reg_class reg_class_from_letter[256];
-
/* Cached value of frv_stack_info. */
static frv_stack_t *frv_stack_cache = (frv_stack_t *)0;
-/* -mcpu= support */
-frv_cpu_t frv_cpu_type = CPU_TYPE; /* value of -mcpu= */
-
/* Forward references */
-static bool frv_handle_option (size_t, const char *, int);
static void frv_option_override (void);
static bool frv_legitimate_address_p (enum machine_mode, rtx, bool);
static int frv_default_flags_for_cpu (void);
static void frv_asm_out_constructor (rtx, int);
static void frv_asm_out_destructor (rtx, int);
static bool frv_function_symbol_referenced_p (rtx);
-static bool frv_cannot_force_const_mem (rtx);
+static bool frv_cannot_force_const_mem (enum machine_mode, rtx);
static const char *unspec_got_name (int);
static void frv_output_const_unspec (FILE *,
const struct frv_unspec *);
const_tree, bool);
static void frv_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool);
+static unsigned int frv_function_arg_boundary (enum machine_mode,
+ const_tree);
static void frv_output_dwarf_dtprel (FILE *, int, rtx)
ATTRIBUTE_UNUSED;
static reg_class_t frv_secondary_reload (bool, rtx, reg_class_t,
secondary_reload_info *);
static bool frv_frame_pointer_required (void);
static bool frv_can_eliminate (const int, const int);
+static void frv_conditional_register_usage (void);
static void frv_trampoline_init (rtx, tree, rtx);
static bool frv_class_likely_spilled_p (reg_class_t);
| MASK_VLIW_BRANCH \
| MASK_MULTI_CE \
| MASK_NESTED_CE)
-#undef TARGET_HANDLE_OPTION
-#define TARGET_HANDLE_OPTION frv_handle_option
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE frv_option_override
#undef TARGET_OPTION_OPTIMIZATION_TABLE
#define TARGET_FUNCTION_INCOMING_ARG frv_function_incoming_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE frv_function_arg_advance
+#undef TARGET_FUNCTION_ARG_BOUNDARY
+#define TARGET_FUNCTION_ARG_BOUNDARY frv_function_arg_boundary
#undef TARGET_EXPAND_BUILTIN_SAVEREGS
#define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs
#undef TARGET_CAN_ELIMINATE
#define TARGET_CAN_ELIMINATE frv_can_eliminate
+#undef TARGET_CONDITIONAL_REGISTER_USAGE
+#define TARGET_CONDITIONAL_REGISTER_USAGE frv_conditional_register_usage
+
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT frv_trampoline_init
4. In many cases, it's more efficient to calculate the constant in-line. */
static bool
-frv_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
+frv_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x ATTRIBUTE_UNUSED)
{
return TARGET_FDPIC;
}
\f
-/* Implement TARGET_HANDLE_OPTION. */
-
-static bool
-frv_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
-{
- switch (code)
- {
- case OPT_mcpu_:
- if (strcmp (arg, "simple") == 0)
- frv_cpu_type = FRV_CPU_SIMPLE;
- else if (strcmp (arg, "tomcat") == 0)
- frv_cpu_type = FRV_CPU_TOMCAT;
- else if (strcmp (arg, "fr550") == 0)
- frv_cpu_type = FRV_CPU_FR550;
- else if (strcmp (arg, "fr500") == 0)
- frv_cpu_type = FRV_CPU_FR500;
- else if (strcmp (arg, "fr450") == 0)
- frv_cpu_type = FRV_CPU_FR450;
- else if (strcmp (arg, "fr405") == 0)
- frv_cpu_type = FRV_CPU_FR405;
- else if (strcmp (arg, "fr400") == 0)
- frv_cpu_type = FRV_CPU_FR400;
- else if (strcmp (arg, "fr300") == 0)
- frv_cpu_type = FRV_CPU_FR300;
- else if (strcmp (arg, "frv") == 0)
- frv_cpu_type = FRV_CPU_GENERIC;
- else
- return false;
- return true;
-
- default:
- return true;
- }
-}
-
static int
frv_default_flags_for_cpu (void)
{
if (!global_options_set.x_g_switch_value && !TARGET_LIBPIC)
g_switch_value = SDATA_DEFAULT_SIZE;
- /* A C expression which defines the machine-dependent operand
- constraint letters for register classes. If CHAR is such a
- letter, the value should be the register class corresponding to
- it. Otherwise, the value should be `NO_REGS'. The register
- letter `r', corresponding to class `GENERAL_REGS', will not be
- passed to this macro; you do not need to handle it.
-
- The following letters are unavailable, due to being used as
- constraints:
- '0'..'9'
- '<', '>'
- 'E', 'F', 'G', 'H'
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'
- 'Q', 'R', 'S', 'T', 'U'
- 'V', 'X'
- 'g', 'i', 'm', 'n', 'o', 'p', 'r', 's' */
-
- for (i = 0; i < 256; i++)
- reg_class_from_letter[i] = NO_REGS;
-
- reg_class_from_letter['a'] = ACC_REGS;
- reg_class_from_letter['b'] = EVEN_ACC_REGS;
- reg_class_from_letter['c'] = CC_REGS;
- reg_class_from_letter['d'] = GPR_REGS;
- reg_class_from_letter['e'] = EVEN_REGS;
- reg_class_from_letter['f'] = FPR_REGS;
- reg_class_from_letter['h'] = FEVEN_REGS;
- reg_class_from_letter['l'] = LR_REG;
- reg_class_from_letter['q'] = QUAD_REGS;
- reg_class_from_letter['t'] = ICC_REGS;
- reg_class_from_letter['u'] = FCC_REGS;
- reg_class_from_letter['v'] = ICR_REGS;
- reg_class_from_letter['w'] = FCR_REGS;
- reg_class_from_letter['x'] = QUAD_FPR_REGS;
- reg_class_from_letter['y'] = LCR_REG;
- reg_class_from_letter['z'] = SPR_REGS;
- reg_class_from_letter['A'] = QUAD_ACC_REGS;
- reg_class_from_letter['B'] = ACCG_REGS;
- reg_class_from_letter['C'] = CR_REGS;
- reg_class_from_letter['W'] = FDPIC_CALL_REGS; /* gp14+15 */
- reg_class_from_letter['Z'] = FDPIC_REGS; /* gp15 */
-
/* There is no single unaligned SI op for PIC code. Sometimes we
need to use ".4byte" and sometimes we need to use ".picptr".
See frv_assemble_integer for details. */
switches, then GCC will automatically avoid using these registers when the
target switches are opposed to them.) */
-void
+static void
frv_conditional_register_usage (void)
{
int i;
frv_frame_offset_rtx (int offset)
{
rtx offset_rtx = GEN_INT (offset);
- if (IN_RANGE_P (offset, -2048, 2047))
+ if (IN_RANGE (offset, -2048, 2047))
return offset_rtx;
else
{
rtx reg_rtx = gen_rtx_REG (SImode, OFFSET_REGNO);
- if (IN_RANGE_P (offset, -32768, 32767))
+ if (IN_RANGE (offset, -32768, 32767))
emit_insn (gen_movsi (reg_rtx, offset_rtx));
else
{
const char *parallel = (frv_issue_rate () > 1 ? ".p" : "");
/* Do the add using an addi if possible. */
- if (IN_RANGE_P (delta, -2048, 2047))
+ if (IN_RANGE (delta, -2048, 2047))
fprintf (file, "\taddi %s,#%d,%s\n", name_arg0, (int) delta, name_arg0);
else
{
argument with the specified mode and type. If it is not defined,
`PARM_BOUNDARY' is used for all arguments. */
-int
+static unsigned int
frv_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED)
+ const_tree type ATTRIBUTE_UNUSED)
{
return BITS_PER_WORD;
}
ret = FALSE;
else
{
- ret = IN_RANGE_P (INTVAL (x), -2048, 2047);
+ ret = IN_RANGE (INTVAL (x), -2048, 2047);
/* If we can't use load/store double operations, make sure we can
address the second word. */
if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
- ret = IN_RANGE_P (INTVAL (x) + GET_MODE_SIZE (mode) - 1,
- -2048, 2047);
+ ret = IN_RANGE (INTVAL (x) + GET_MODE_SIZE (mode) - 1,
+ -2048, 2047);
}
break;
else
{
value = INTVAL (x1);
- ret = IN_RANGE_P (value, -2048, 2047);
+ ret = IN_RANGE (value, -2048, 2047);
/* If we can't use load/store double operations, make sure we can
address the second word. */
if (ret && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
- ret = IN_RANGE_P (value + GET_MODE_SIZE (mode) - 1, -2048, 2047);
+ ret = IN_RANGE (value + GET_MODE_SIZE (mode) - 1, -2048, 2047);
}
break;
add instruction, so expose this to CSE by copying to
an intermediate register. */
|| (GET_CODE (src) == REG
- && IN_RANGE_P (REGNO (src),
- FIRST_VIRTUAL_REGISTER,
- LAST_VIRTUAL_POINTER_REGISTER))))
+ && IN_RANGE (REGNO (src),
+ FIRST_VIRTUAL_REGISTER,
+ LAST_VIRTUAL_POINTER_REGISTER))))
{
emit_insn (gen_rtx_SET (VOIDmode, dest, copy_to_mode_reg (SImode, src)));
return TRUE;
else
value = CONST_DOUBLE_LOW (src);
- if (IN_RANGE_P (value, -32768, 32767))
+ if (IN_RANGE (value, -32768, 32767))
return "setlos %1, %0";
return "#";
between the two fits in an addi's range, load up the difference, then
conditionally move in 0, and then unconditionally add the first
value. */
- else if (IN_RANGE_P (value1, -2048, 2047)
- && IN_RANGE_P (value2 - value1, -2048, 2047))
+ else if (IN_RANGE (value1, -2048, 2047)
+ && IN_RANGE (value2 - value1, -2048, 2047))
;
/* If neither condition holds, just force the constant into a
between the two fits in an addi's range, load up the difference, then
conditionally move in 0, and then unconditionally add the first
value. */
- else if (IN_RANGE_P (value1, -2048, 2047)
- && IN_RANGE_P (value2 - value1, -2048, 2047))
+ else if (IN_RANGE (value1, -2048, 2047)
+ && IN_RANGE (value2 - value1, -2048, 2047))
{
rtx dest_si = ((GET_MODE (dest) == SImode)
? dest
{
case CONST_INT:
/* Make 12-bit integers really cheap. */
- if (IN_RANGE_P (INTVAL (x), -2048, 2047))
+ if (IN_RANGE (INTVAL (x), -2048, 2047))
{
*total = 0;
return true;