diff options
Diffstat (limited to 'gcc/config/epiphany')
-rw-r--r-- | gcc/config/epiphany/epiphany-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/epiphany/epiphany.c | 59 | ||||
-rw-r--r-- | gcc/config/epiphany/epiphany.h | 39 |
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 */ |