summaryrefslogtreecommitdiff
path: root/gcc/config/epiphany
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/epiphany')
-rw-r--r--gcc/config/epiphany/epiphany-protos.h1
-rw-r--r--gcc/config/epiphany/epiphany.c59
-rw-r--r--gcc/config/epiphany/epiphany.h39
3 files changed, 76 insertions, 23 deletions
diff --git a/gcc/config/epiphany/epiphany-protos.h b/gcc/config/epiphany/epiphany-protos.h
index 334c5337f7c..2e787da8579 100644
--- a/gcc/config/epiphany/epiphany-protos.h
+++ b/gcc/config/epiphany/epiphany-protos.h
@@ -53,3 +53,4 @@ extern bool epiphany_optimize_mode_switching (int entity);
extern bool epiphany_is_interrupt_p (tree);
extern unsigned epiphany_special_round_type_align (tree, unsigned, unsigned);
extern unsigned epiphany_adjust_field_align (tree, unsigned);
+extern void epiphany_start_function (FILE *f, const char *name, tree decl);
diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c
index a4652da87b8..a8fc034811b 100644
--- a/gcc/config/epiphany/epiphany.c
+++ b/gcc/config/epiphany/epiphany.c
@@ -435,14 +435,17 @@ epiphany_handle_interrupt_attribute (tree *node ATTRIBUTE_UNUSED,
}
else if (strcmp (TREE_STRING_POINTER (value), "reset")
&& strcmp (TREE_STRING_POINTER (value), "software_exception")
- && strcmp (TREE_STRING_POINTER (value), "timer")
+ && strcmp (TREE_STRING_POINTER (value), "page_miss")
+ && strcmp (TREE_STRING_POINTER (value), "timer0")
+ && strcmp (TREE_STRING_POINTER (value), "timer1")
+ && strcmp (TREE_STRING_POINTER (value), "message")
&& strcmp (TREE_STRING_POINTER (value), "dma0")
&& strcmp (TREE_STRING_POINTER (value), "dma1")
- && strcmp (TREE_STRING_POINTER (value), "static_flag")
+ && strcmp (TREE_STRING_POINTER (value), "wand")
&& strcmp (TREE_STRING_POINTER (value), "swi"))
{
warning (OPT_Wattributes,
- "argument of %qE attribute is not \"reset\", \"software_exception\", \"timer\", \"dma0\", \"dma1\", \"static_flag\" or \"swi\"",
+ "argument of %qE attribute is not \"reset\", \"software_exception\", \"page_miss\", \"timer0\", \"timer1\", \"message\", \"dma0\", \"dma1\", \"wand\" or \"swi\"",
name);
*no_add_attrs = true;
}
@@ -892,14 +895,20 @@ epiphany_compute_function_type (tree decl)
fn_type = EPIPHANY_FUNCTION_RESET;
else if (!strcmp (TREE_STRING_POINTER (value), "software_exception"))
fn_type = EPIPHANY_FUNCTION_SOFTWARE_EXCEPTION;
- else if (!strcmp (TREE_STRING_POINTER (value), "timer"))
- fn_type = EPIPHANY_FUNCTION_TIMER;
+ else if (!strcmp (TREE_STRING_POINTER (value), "page_miss"))
+ fn_type = EPIPHANY_FUNCTION_PAGE_MISS;
+ else if (!strcmp (TREE_STRING_POINTER (value), "timer0"))
+ fn_type = EPIPHANY_FUNCTION_TIMER0;
+ else if (!strcmp (TREE_STRING_POINTER (value), "timer1"))
+ fn_type = EPIPHANY_FUNCTION_TIMER1;
+ else if (!strcmp (TREE_STRING_POINTER (value), "message"))
+ fn_type = EPIPHANY_FUNCTION_MESSAGE;
else if (!strcmp (TREE_STRING_POINTER (value), "dma0"))
fn_type = EPIPHANY_FUNCTION_DMA0;
else if (!strcmp (TREE_STRING_POINTER (value), "dma1"))
fn_type = EPIPHANY_FUNCTION_DMA1;
- else if (!strcmp (TREE_STRING_POINTER (value), "static_flag"))
- fn_type = EPIPHANY_FUNCTION_STATIC_FLAG;
+ else if (!strcmp (TREE_STRING_POINTER (value), "wand"))
+ fn_type = EPIPHANY_FUNCTION_WAND;
else if (!strcmp (TREE_STRING_POINTER (value), "swi"))
fn_type = EPIPHANY_FUNCTION_SWI;
else
@@ -1812,14 +1821,14 @@ epiphany_expand_epilogue (int sibcall_p)
}
if (interrupt_p)
{
- frame_move_insn (gen_rtx_REG (word_mode, STATUS_REGNUM),
- gen_rtx_REG (SImode, GPR_0));
- frame_move_insn (gen_rtx_REG (word_mode, IRET_REGNUM),
- gen_rtx_REG (SImode, GPR_0+1));
+ emit_move_insn (gen_rtx_REG (word_mode, STATUS_REGNUM),
+ gen_rtx_REG (SImode, GPR_0));
+ emit_move_insn (gen_rtx_REG (word_mode, IRET_REGNUM),
+ gen_rtx_REG (SImode, GPR_0+1));
addr = plus_constant (stack_pointer_rtx,
- (HOST_WIDE_INT) 2 * UNITS_PER_WORD);
- frame_move_insn (gen_rtx_REG (DImode, GPR_0),
- gen_frame_mem (DImode, addr));
+ emit_move_insn (gen_rtx_REG (DImode, GPR_0),
+ gen_frame_mem (DImode, addr));
}
addr = plus_constant (stack_pointer_rtx,
epiphany_stack_offset - (HOST_WIDE_INT) UNITS_PER_WORD);
@@ -2748,4 +2757,28 @@ epiphany_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
}
}
+void
+epiphany_start_function (FILE *file, const char *name, tree decl)
+{
+ tree attrs, int_attr;
+
+ attrs = DECL_ATTRIBUTES (decl);
+ int_attr = lookup_attribute ("interrupt", attrs);
+ if (int_attr)
+ {
+ char buf[99];
+ const char *fname;
+
+ int_attr = TREE_VALUE (TREE_VALUE (int_attr));
+ sprintf (buf, "ivt_entry_%.80s", TREE_STRING_POINTER (int_attr));
+ switch_to_section (get_section (buf, SECTION_CODE, decl));
+ fname = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ fputs ("\tb\t", file);
+ assemble_name (file, fname);
+ fputc ('\n', file);
+ switch_to_section (function_section (decl));
+ }
+ ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
+}
+
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/epiphany/epiphany.h b/gcc/config/epiphany/epiphany.h
index 9d03ee909b8..f92e1973e36 100644
--- a/gcc/config/epiphany/epiphany.h
+++ b/gcc/config/epiphany/epiphany.h
@@ -565,13 +565,13 @@ typedef struct GTY (()) machine_function
#define FRAME_ADDR_RTX(frame) \
((frame) == hard_frame_pointer_rtx ? arg_pointer_rtx : NULL)
+#define EPIPHANY_RETURN_REGNO \
+ ((current_function_decl != NULL \
+ && epiphany_is_interrupt_p (current_function_decl)) \
+ ? IRET_REGNUM : GPR_LR)
/* This is not only for dwarf unwind info, but also for the benefit of
df-scan.c to tell it that LR is live at the function start. */
-#define INCOMING_RETURN_ADDR_RTX \
- gen_rtx_REG (Pmode, \
- (current_function_decl != NULL \
- && epiphany_is_interrupt_p (current_function_decl) \
- ? IRET_REGNUM : GPR_LR))
+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, EPIPHANY_RETURN_REGNO)
/* However, we haven't implemented the rest needed for dwarf2 unwind info. */
#define DWARF2_UNWIND_INFO 0
@@ -579,6 +579,8 @@ typedef struct GTY (()) machine_function
#define RETURN_ADDR_RTX(count, frame) \
(count ? NULL_RTX \
: gen_rtx_UNSPEC (SImode, gen_rtvec (1, const0_rtx), UNSPEC_RETURN_ADDR))
+
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (EPIPHANY_RETURN_REGNO)
/* Trampolines.
An epiphany trampoline looks like this:
@@ -602,6 +604,21 @@ typedef struct GTY (()) machine_function
#define HAVE_POST_MODIFY_DISP TARGET_POST_MODIFY
#define HAVE_POST_MODIFY_REG TARGET_POST_MODIFY
+/* Currently, the only users of the USE_*CREMENT macros are
+ move_by_pieces / store_by_pieces_1 . We don't want them to use
+ POST_MODIFY modes, because we got ample addressing range for the
+ reg+offset addressing mode; besides, there are short index+offset loads,
+ but the only short post-modify load uses POST_MODIFY_REG.
+ Moreover, using auto-increment in move_by_pieces from structure copying
+ in the prologue causes confused debug output.
+ If another pass starts using these macros where the use of these
+ addressing modes would make more sense, we can try checking the
+ current pass. */
+#define USE_LOAD_POST_INCREMENT(MODE) 0
+#define USE_LOAD_POST_DECREMENT(MODE) 0
+#define USE_STORE_POST_INCREMENT(MODE) 0
+#define USE_STORE_POST_DECREMENT(MODE) 0
+
/* Recognize any constant value that is a valid address. */
#define CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
@@ -814,14 +831,12 @@ do { if ((LOG) != 0) fprintf (FILE, "\t.balign %d\n", 1 << (LOG)); } while (0)
enum epiphany_function_type
{
EPIPHANY_FUNCTION_UNKNOWN, EPIPHANY_FUNCTION_NORMAL,
- /* These are interrupt handlers. The name corresponds to the register
- name that contains the return address. */
- EPIPHANY_FUNCTION_ILINK1, EPIPHANY_FUNCTION_ILINK2,
/* These are interrupt handlers. The name corresponds to which type
of interrupt handler we're dealing with. */
EPIPHANY_FUNCTION_RESET, EPIPHANY_FUNCTION_SOFTWARE_EXCEPTION,
- EPIPHANY_FUNCTION_TIMER, EPIPHANY_FUNCTION_DMA0,
- EPIPHANY_FUNCTION_DMA1, EPIPHANY_FUNCTION_STATIC_FLAG,
+ EPIPHANY_FUNCTION_PAGE_MISS,
+ EPIPHANY_FUNCTION_TIMER0, EPIPHANY_FUNCTION_TIMER1, EPIPHANY_FUNCTION_MESSAGE,
+ EPIPHANY_FUNCTION_DMA0, EPIPHANY_FUNCTION_DMA1, EPIPHANY_FUNCTION_WAND,
EPIPHANY_FUNCTION_SWI
};
@@ -878,4 +893,8 @@ extern struct rtl_opt_pass pass_resolve_sw_modes;
implemented. */
#define TARGET_FUSED_MADD (flag_fp_contract_mode == FP_CONTRACT_FAST)
+#undef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+ epiphany_start_function ((FILE), (NAME), (DECL))
+
#endif /* !GCC_EPIPHANY_H */