/* Xstormy16 target functions.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
- Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
This file is part of GCC.
GCC 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)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "tm_p.h"
#include "langhooks.h"
#include "tree-gimple.h"
+#include "df.h"
#include "ggc.h"
static rtx emit_addhi3_postreload (rtx, rtx, rtx);
static rtx xstormy16_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
static bool xstormy16_rtx_costs (rtx, int, int, int *);
static int xstormy16_address_cost (rtx);
-static bool xstormy16_return_in_memory (tree, tree);
+static bool xstormy16_return_in_memory (const_tree, const_tree);
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. */
return NO_REGS;
}
-/* Recognize a PLUS that needs the carry register. */
-int
-xstormy16_carry_plus_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- return (GET_CODE (x) == PLUS
- && GET_CODE (XEXP (x, 1)) == CONST_INT
- && (INTVAL (XEXP (x, 1)) < -4 || INTVAL (XEXP (x, 1)) > 4));
-}
-
-/* Detect and error out on out-of-range constants for movhi. */
-int
-xs_hi_general_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if ((GET_CODE (x) == CONST_INT)
- && ((INTVAL (x) >= 32768) || (INTVAL (x) < -32768)))
- error ("constant halfword load operand out of range");
- return general_operand (x, mode);
-}
-
-/* Detect and error out on out-of-range constants for addhi and subhi. */
-int
-xs_hi_nonmemory_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if ((GET_CODE (x) == CONST_INT)
- && ((INTVAL (x) >= 32768) || (INTVAL (x) < -32768)))
- error ("constant arithmetic operand out of range");
- return nonmemory_operand (x, mode);
-}
-
enum reg_class
xstormy16_preferred_reload_class (rtx x, enum reg_class class)
{
if (GET_CODE (x) == PLUS
&& LEGITIMATE_ADDRESS_INTEGER_P (XEXP (x, 1), 0))
- x = XEXP (x, 0);
+ {
+ x = XEXP (x, 0);
+ /* PR 31232: Do not allow INT+INT as an address. */
+ if (GET_CODE (x) == CONST_INT)
+ return 0;
+ }
if ((GET_CODE (x) == PRE_MODIFY
&& GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
&& (! strict || REGNO (x) < FIRST_PSEUDO_REGISTER))
return 1;
- if (xstormy16_below100_symbol(x, mode))
+ if (xstormy16_below100_symbol (x, mode))
return 1;
return 0;
if (GET_CODE (x) == PLUS)
x = XEXP (x, 0);
- if (GET_CODE (x) == POST_INC
- || GET_CODE (x) == PRE_DEC)
- return 1;
+ /* Auto-increment addresses are now treated generically in recog.c. */
return 0;
}
&& (INTVAL (x) == 0));
case 'W':
- return xstormy16_below100_operand(x, GET_MODE(x));
+ return xstormy16_below100_operand (x, GET_MODE (x));
default:
return 0;
/* Does REGNO need to be saved? */
#define REG_NEEDS_SAVE(REGNUM, IFUN) \
- ((regs_ever_live[REGNUM] && ! call_used_regs[REGNUM]) \
+ ((df_regs_ever_live_p (REGNUM) && ! call_used_regs[REGNUM]) \
|| (IFUN && ! fixed_regs[REGNUM] && call_used_regs[REGNUM] \
&& (REGNO_REG_CLASS (REGNUM) != CARRY_REGS) \
- && (regs_ever_live[REGNUM] || ! current_function_is_leaf)))
+ && (df_regs_ever_live_p (REGNUM) || ! current_function_is_leaf)))
/* Compute the stack layout. */
struct xstormy16_stack_layout
is stdarg.h instead of varargs.h. VALIST is the tree of the va_list
variable to initialize. NEXTARG is the machine independent notion of the
'next' argument after the variable arguments. */
-void
+static void
xstormy16_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
{
tree f_base, f_count;
tree base, count;
- tree t;
+ tree t,u;
if (xstormy16_interrupt_function_p ())
error ("cannot use va_start in interrupt function");
NULL_TREE);
t = make_tree (TREE_TYPE (base), virtual_incoming_args_rtx);
- t = build2 (PLUS_EXPR, TREE_TYPE (base), t,
- build_int_cst (NULL_TREE, INCOMING_FRAME_SP_OFFSET));
- t = build2 (MODIFY_EXPR, TREE_TYPE (base), base, t);
+ u = build_int_cst (NULL_TREE, INCOMING_FRAME_SP_OFFSET);
+ u = fold_convert (TREE_TYPE (count), u);
+ t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (base), t, u);
+ t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (base), base, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- t = build2 (MODIFY_EXPR, TREE_TYPE (count), count,
+ t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (count), count,
build_int_cst (NULL_TREE,
current_function_args_info * UNITS_PER_WORD));
TREE_SIDE_EFFECTS (t) = 1;
Note: This algorithm is documented in stormy-abi. */
static tree
-xstormy16_expand_builtin_va_arg (tree valist, tree type, tree *pre_p,
- tree *post_p ATTRIBUTE_UNUSED)
+xstormy16_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
+ tree *post_p ATTRIBUTE_UNUSED)
{
tree f_base, f_count;
tree base, count;
build1 (GOTO_EXPR, void_type_node, lab_fromstack),
NULL_TREE);
gimplify_and_add (t, pre_p);
-
- t = fold_convert (ptr_type_node, count_tmp);
- t = build2 (PLUS_EXPR, ptr_type_node, base, t);
- t = build2 (MODIFY_EXPR, void_type_node, addr, t);
+
+ t = build2 (POINTER_PLUS_EXPR, ptr_type_node, base, count_tmp);
+ t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
gimplify_and_add (t, pre_p);
t = build1 (GOTO_EXPR, void_type_node, lab_gotaddr);
tree r, u;
r = size_int (NUM_ARGUMENT_REGISTERS * UNITS_PER_WORD);
- u = build2 (MODIFY_EXPR, void_type_node, count_tmp, r);
+ u = build2 (GIMPLE_MODIFY_STMT, void_type_node, count_tmp, r);
t = fold_convert (TREE_TYPE (count), r);
t = build2 (GE_EXPR, boolean_type_node, count_tmp, t);
t = build2 (MINUS_EXPR, TREE_TYPE (count), count_tmp, t);
t = build2 (PLUS_EXPR, TREE_TYPE (count), t,
fold_convert (TREE_TYPE (count), size_tree));
- t = fold_convert (TREE_TYPE (base), fold (t));
- t = build2 (MINUS_EXPR, TREE_TYPE (base), base, t);
- t = build2 (MODIFY_EXPR, void_type_node, addr, t);
+ t = fold_convert (TREE_TYPE (t), fold (t));
+ t = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
+ t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (base), base, t);
+ t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
gimplify_and_add (t, pre_p);
t = build1 (LABEL_EXPR, void_type_node, lab_gotaddr);
t = fold_convert (TREE_TYPE (count), size_tree);
t = build2 (PLUS_EXPR, TREE_TYPE (count), count_tmp, t);
- t = build2 (MODIFY_EXPR, TREE_TYPE (count), count, t);
+ t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (count), count, t);
gimplify_and_add (t, pre_p);
addr = fold_convert (build_pointer_type (type), addr);
/* Worker function for FUNCTION_VALUE. */
rtx
-xstormy16_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
+xstormy16_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
{
enum machine_mode mode;
mode = TYPE_MODE (valtype);
else
args = tree_cons (NULL_TREE, arg, args);
}
- lang_hooks.builtin_function (s16builtins[i].name,
- build_function_type (ret_type, args),
- i, BUILT_IN_MD, NULL, NULL);
+ add_builtin_function (s16builtins[i].name,
+ build_function_type (ret_type, args),
+ i, BUILT_IN_MD, NULL, NULL);
}
}
static rtx
-xstormy16_expand_builtin(tree exp, rtx target,
- rtx subtarget ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- int ignore ATTRIBUTE_UNUSED)
+xstormy16_expand_builtin (tree exp, rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
rtx op[10], args[10], pat, copyto[10], retval = 0;
tree fndecl, argtree;
/* Worker function for TARGET_RETURN_IN_MEMORY. */
static bool
-xstormy16_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+xstormy16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
- HOST_WIDE_INT size = int_size_in_bytes (type);
+ const HOST_WIDE_INT size = int_size_in_bytes (type);
return (size == -1 || size > UNITS_PER_WORD * NUM_ARGUMENT_REGISTERS);
}
\f
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO xstormy16_encode_section_info
+/* select_section doesn't handle .bss_below100. */
+#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
+#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false
+
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK xstormy16_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#undef TARGET_BUILD_BUILTIN_VA_LIST
#define TARGET_BUILD_BUILTIN_VA_LIST xstormy16_build_builtin_va_list
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START xstormy16_expand_builtin_va_start
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
-#define TARGET_GIMPLIFY_VA_ARG_EXPR xstormy16_expand_builtin_va_arg
+#define TARGET_GIMPLIFY_VA_ARG_EXPR xstormy16_gimplify_va_arg_expr
#undef TARGET_PROMOTE_FUNCTION_ARGS
-#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
#undef TARGET_PROMOTE_FUNCTION_RETURN
-#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
#undef TARGET_PROMOTE_PROTOTYPES
-#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
+#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY xstormy16_return_in_memory