/* The Blackfin code generation auxiliary output file.
- Copyright (C) 2005-2017 Free Software Foundation, Inc.
+ Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Analog Devices.
This file is part of GCC.
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+#define IN_TARGET_CODE 1
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
CALL_INSN_FUNCTION_USAGE (call) = use;
}
\f
-/* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */
+/* Implement TARGET_HARD_REGNO_NREGS. */
-int
-hard_regno_mode_ok (int regno, machine_mode mode)
+static unsigned int
+bfin_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+ if (mode == PDImode && (regno == REG_A0 || regno == REG_A1))
+ return 1;
+ if (mode == V2PDImode && (regno == REG_A0 || regno == REG_A1))
+ return 2;
+ return CLASS_MAX_NREGS (GENERAL_REGS, mode);
+}
+
+/* Implement TARGET_HARD_REGNO_MODE_OK.
+
+ Do not allow to store a value in REG_CC for any mode.
+ Do not allow to store value in pregs if mode is not SI. */
+static bool
+bfin_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
/* Allow only dregs to store value of mode HI or QI */
enum reg_class rclass = REGNO_REG_CLASS (regno);
if (mode == CCmode)
- return 0;
+ return false;
if (mode == V2HImode)
return D_REGNO_P (regno);
if (mode == SImode
&& TEST_HARD_REG_BIT (reg_class_contents[PROLOGUE_REGS], regno))
- return 1;
+ return true;
return TEST_HARD_REG_BIT (reg_class_contents[MOST_REGS], regno);
}
+/* Implement TARGET_MODES_TIEABLE_P. */
+
+static bool
+bfin_modes_tieable_p (machine_mode mode1, machine_mode mode2)
+{
+ return (mode1 == mode2
+ || ((GET_MODE_CLASS (mode1) == MODE_INT
+ || GET_MODE_CLASS (mode1) == MODE_FLOAT)
+ && (GET_MODE_CLASS (mode2) == MODE_INT
+ || GET_MODE_CLASS (mode2) == MODE_FLOAT)
+ && mode1 != BImode && mode2 != BImode
+ && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
+ && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD));
+}
+
/* Implements target hook vector_mode_supported_p. */
static bool
#ifdef SUBTARGET_FDPIC_NOT_SUPPORTED
if (TARGET_FDPIC)
- error ("-mfdpic is not supported, please use a bfin-linux-uclibc target");
+ error ("%<-mfdpic%> is not supported, please use a bfin-linux-uclibc "
+ "target");
#endif
/* Library identification */
if (global_options_set.x_bfin_library_id && ! TARGET_ID_SHARED_LIBRARY)
- error ("-mshared-library-id= specified without -mid-shared-library");
+ error ("%<-mshared-library-id=%> specified without "
+ "%<-mid-shared-library%>");
if (stack_limit_rtx && TARGET_FDPIC)
{
- warning (0, "-fstack-limit- options are ignored with -mfdpic; use -mstack-check-l1");
+ warning (0, "%<-fstack-limit-%> options are ignored with %<-mfdpic%>; "
+ "use %<-mstack-check-l1%>");
stack_limit_rtx = NULL_RTX;
}
/* Don't allow the user to specify -mid-shared-library and -msep-data
together, as it makes little sense from a user's point of view... */
if (TARGET_SEP_DATA && TARGET_ID_SHARED_LIBRARY)
- error ("cannot specify both -msep-data and -mid-shared-library");
+ error ("cannot specify both %<-msep-data%> and %<-mid-shared-library%>");
/* ... internally, however, it's nearly the same. */
if (TARGET_SEP_DATA)
target_flags |= MASK_ID_SHARED_LIBRARY | MASK_LEAF_ID_SHARED_LIBRARY;
flag_pic = 0;
if (TARGET_MULTICORE && bfin_cpu_type != BFIN_CPU_BF561)
- error ("-mmulticore can only be used with BF561");
+ error ("%<-mmulticore%> can only be used with BF561");
if (TARGET_COREA && !TARGET_MULTICORE)
- error ("-mcorea should be used with -mmulticore");
+ error ("%<-mcorea%> should be used with %<-mmulticore%>");
if (TARGET_COREB && !TARGET_MULTICORE)
- error ("-mcoreb should be used with -mmulticore");
+ error ("%<-mcoreb%> should be used with %<-mmulticore%>");
if (TARGET_COREA && TARGET_COREB)
- error ("-mcorea and -mcoreb can%'t be used together");
+ error ("%<-mcorea%> and %<-mcoreb%> can%'t be used together");
flag_schedule_insns = 0;
memcpy can use 32 bit loads/stores. */
if (TYPE_SIZE (type)
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && wi::gtu_p (TYPE_SIZE (type), 8)
+ && wi::gtu_p (wi::to_wide (TYPE_SIZE (type)), 8)
&& align < 32)
return 32;
return align;
point. */
if (!loop->incoming_src && loop->head != loop->incoming_dest)
{
- rtx label = BB_HEAD (loop->incoming_dest);
+ rtx_insn *label = BB_HEAD (loop->incoming_dest);
/* If we're jumping to the final basic block in the loop, and there's
only one cheap instruction before the end (typically an increment of
an induction variable), we can just emit a copy here instead of a
&& any_condjump_p (insn)
&& (cbranch_predicted_taken_p (insn)))
{
- rtx target = JUMP_LABEL (insn);
+ rtx_insn *target = JUMP_LABEL_AS_INSN (insn);
rtx_insn *next = next_real_insn (target);
if (GET_CODE (PATTERN (next)) == UNSPEC_VOLATILE
/* Table of valid machine attributes. */
static const struct attribute_spec bfin_attribute_table[] =
{
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
- affects_type_identity } */
- { "interrupt_handler", 0, 0, false, true, true, handle_int_attribute,
- false },
- { "exception_handler", 0, 0, false, true, true, handle_int_attribute,
- false },
- { "nmi_handler", 0, 0, false, true, true, handle_int_attribute, false },
- { "nesting", 0, 0, false, true, true, NULL, false },
- { "kspisusp", 0, 0, false, true, true, NULL, false },
- { "saveall", 0, 0, false, true, true, NULL, false },
- { "longcall", 0, 0, false, true, true, bfin_handle_longcall_attribute,
- false },
- { "shortcall", 0, 0, false, true, true, bfin_handle_longcall_attribute,
- false },
- { "l1_text", 0, 0, true, false, false, bfin_handle_l1_text_attribute,
- false },
- { "l1_data", 0, 0, true, false, false, bfin_handle_l1_data_attribute,
- false },
- { "l1_data_A", 0, 0, true, false, false, bfin_handle_l1_data_attribute,
- false },
- { "l1_data_B", 0, 0, true, false, false, bfin_handle_l1_data_attribute,
- false },
- { "l2", 0, 0, true, false, false, bfin_handle_l2_attribute, false },
- { NULL, 0, 0, false, false, false, NULL, false }
+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+ affects_type_identity, handler, exclude } */
+ { "interrupt_handler", 0, 0, false, true, true, false,
+ handle_int_attribute, NULL },
+ { "exception_handler", 0, 0, false, true, true, false,
+ handle_int_attribute, NULL },
+ { "nmi_handler", 0, 0, false, true, true, false, handle_int_attribute,
+ NULL },
+ { "nesting", 0, 0, false, true, true, false, NULL, NULL },
+ { "kspisusp", 0, 0, false, true, true, false, NULL, NULL },
+ { "saveall", 0, 0, false, true, true, false, NULL, NULL },
+ { "longcall", 0, 0, false, true, true, false,
+ bfin_handle_longcall_attribute, NULL },
+ { "shortcall", 0, 0, false, true, true, false,
+ bfin_handle_longcall_attribute, NULL },
+ { "l1_text", 0, 0, true, false, false, false,
+ bfin_handle_l1_text_attribute, NULL },
+ { "l1_data", 0, 0, true, false, false, false,
+ bfin_handle_l1_data_attribute, NULL },
+ { "l1_data_A", 0, 0, true, false, false, false,
+ bfin_handle_l1_data_attribute, NULL },
+ { "l1_data_B", 0, 0, true, false, false, false,
+ bfin_handle_l1_data_attribute, NULL },
+ { "l2", 0, 0, true, false, false, false, bfin_handle_l2_attribute, NULL },
+ { NULL, 0, 0, false, false, false, false, NULL, NULL }
};
\f
/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
#undef TARGET_CAN_USE_DOLOOP_P
#define TARGET_CAN_USE_DOLOOP_P bfin_can_use_doloop_p
+#undef TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS bfin_hard_regno_nregs
+#undef TARGET_HARD_REGNO_MODE_OK
+#define TARGET_HARD_REGNO_MODE_OK bfin_hard_regno_mode_ok
+
+#undef TARGET_MODES_TIEABLE_P
+#define TARGET_MODES_TIEABLE_P bfin_modes_tieable_p
+
+#undef TARGET_CONSTANT_ALIGNMENT
+#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
+
struct gcc_target targetm = TARGET_INITIALIZER;