/* Definitions for GCC. Part of the machine description for CRIS.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ 2008, 2009 Free Software Foundation, Inc.
Contributed by Axis Communications. Written by Hans-Peter Nilsson.
This file is part of GCC.
{ CRIS_RETINSN_UNKNOWN = 0, CRIS_RETINSN_RET, CRIS_RETINSN_JUMP };
/* Per-function machine data. */
-struct machine_function GTY(())
+struct GTY(()) machine_function
{
int needs_return_address_on_stack;
/* Fix for reg_overlap_mentioned_p. */
static int cris_reg_overlap_mentioned_p (rtx, rtx);
+static enum machine_mode cris_promote_function_mode (const_tree, enum machine_mode,
+ int *, const_tree, int);
+
static void cris_print_base (rtx, FILE *);
static void cris_print_index (rtx, FILE *);
static bool cris_handle_option (size_t, const char *, int);
+static bool cris_frame_pointer_required (void);
+
/* This is the parsed result of the "-max-stack-stackframe=" option. If
it (still) is zero, then there was no such option given. */
int cris_max_stackframe = 0;
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST cris_address_cost
-#undef TARGET_PROMOTE_FUNCTION_ARGS
-#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
+#undef TARGET_PROMOTE_FUNCTION_MODE
+#define TARGET_PROMOTE_FUNCTION_MODE cris_promote_function_mode
+
#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX cris_struct_value_rtx
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | CRIS_SUBTARGET_DEFAULT)
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION cris_handle_option
+#undef TARGET_FRAME_POINTER_REQUIRED
+#define TARGET_FRAME_POINTER_REQUIRED cris_frame_pointer_required
struct gcc_target targetm = TARGET_INITIALIZER;
if (SET_DEST (exp) == cc0_rtx)
{
CC_STATUS_INIT;
- cc_status.value1 = SET_SRC (exp);
- /* Handle flags for the special btstq on one bit. */
- if (GET_CODE (SET_SRC (exp)) == ZERO_EXTRACT
- && XEXP (SET_SRC (exp), 1) == const1_rtx)
+ if (GET_CODE (SET_SRC (exp)) == COMPARE
+ && XEXP (SET_SRC (exp), 1) == const0_rtx)
+ cc_status.value1 = XEXP (SET_SRC (exp), 0);
+ else
+ cc_status.value1 = SET_SRC (exp);
+
+ /* Handle flags for the special btstq on one bit. */
+ if (GET_CODE (cc_status.value1) == ZERO_EXTRACT
+ && XEXP (cc_status.value1, 1) == const1_rtx)
{
- if (CONST_INT_P (XEXP (SET_SRC (exp), 0)))
+ if (CONST_INT_P (XEXP (cc_status.value1, 0)))
/* Using cmpq. */
cc_status.flags = CC_INVERTED;
else
cc_status.flags = CC_Z_IN_NOT_N;
}
- if (GET_CODE (SET_SRC (exp)) == COMPARE)
+ else if (GET_CODE (SET_SRC (exp)) == COMPARE)
{
if (!REG_P (XEXP (SET_SRC (exp), 0))
&& XEXP (SET_SRC (exp), 1) != const0_rtx)
}
return false;
+ case ZERO_EXTRACT:
+ if (outer_code != COMPARE)
+ return false;
+ /* fall through */
+
case ZERO_EXTEND: case SIGN_EXTEND:
*total = rtx_cost (XEXP (x, 0), outer_code, speed);
return true;
}
/* Make sure operands are in the right order for an addsi3 insn as
- generated by a define_split. A MEM as the first operand isn't
- recognized by addsi3 after reload. OPERANDS contains the operands,
- with the first at OPERANDS[N] and the second at OPERANDS[N+1]. */
+ generated by a define_split. Nothing but REG_P as the first
+ operand is recognized by addsi3 after reload. OPERANDS contains
+ the operands, with the first at OPERANDS[N] and the second at
+ OPERANDS[N+1]. */
void
cris_order_for_addsi3 (rtx *operands, int n)
{
- if (MEM_P (operands[n]))
+ if (!REG_P (operands[n]))
{
rtx tem = operands[n];
operands[n] = operands[n + 1];
|| CRIS_FUNCTION_ARG_SIZE (mode, type) > 8);
}
+/* A combination of defining TARGET_PROMOTE_FUNCTION_MODE, promoting arguments
+ and *not* defining TARGET_PROMOTE_PROTOTYPES or PROMOTE_MODE gives the
+ best code size and speed for gcc, ipps and products in gcc-2.7.2. */
+
+enum machine_mode
+cris_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
+ enum machine_mode mode,
+ int *punsignedp ATTRIBUTE_UNUSED,
+ const_tree fntype ATTRIBUTE_UNUSED,
+ int for_return)
+{
+ /* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovered bug 981110 (even
+ when modifying FUNCTION_VALUE to return the promoted mode). Maybe
+ pointless as of now, but let's keep the old behavior. */
+ if (for_return == 1)
+ return mode;
+ return CRIS_PROMOTED_MODE (mode, *punsignedp, type);
+}
+
static int
cris_arg_partial_bytes (CUMULATIVE_ARGS *ca, enum machine_mode mode,
clobbers);
}
+/* Implement TARGET_FRAME_POINTER_REQUIRED.
+
+ Really only needed if the stack frame has variable length (alloca
+ or variable sized local arguments (GNU C extension). See PR39499 and
+ PR38609 for the reason this isn't just 0. */
+
+bool
+cris_frame_pointer_required (void)
+{
+ return !current_function_sp_is_unchanging;
+}
+
#if 0
/* Various small functions to replace macros. Only called from a
debugger. They might collide with gcc functions or system functions,