2014-04-03 Joern Rennecke gcc: * common/config/epiphany/epiphany-common.c (epiphany_option_optimization_table): Enable section anchors by default at -O1 or higher. * config/epiphany/epiphany.c (TARGET_MAX_ANCHOR_OFFSET): Define. (TARGET_MIN_ANCHOR_OFFSET): Likewise. (epiphany_rtx_costs): PLUS and MINUS carry no extra cost inside SET. (epiphany_legitimate_address_p): For BLKmode, apply SImode check. * config/epiphany/epiphany.h (ASM_OUTPUT_DEF): Define. * config/epiphany/predicates.md (memclob_operand): New predicate. * config/epiphany/epiphany.md (stack_adjust_str): Use memclob_operand and X constraint for operand 3. testsuite: * gcc.target/epiphany/t1068-2.c: New file. diff --git a/gcc/common/config/epiphany/epiphany-common.c b/gcc/common/config/epiphany/epiphany-common.c index 291a7fc..6c467b8 100644 --- a/gcc/common/config/epiphany/epiphany-common.c +++ b/gcc/common/config/epiphany/epiphany-common.c @@ -39,6 +39,8 @@ along with GCC; see the file COPYING3. If not see static const struct default_options epiphany_option_optimization_table[] = { { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + /* Enable section anchors by default at -O1 or higher. */ + { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, { OPT_LEVELS_NONE, 0, NULL, 0 } }; diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c index 301f2ae..1b9a299 100644 --- a/gcc/config/epiphany/epiphany.c +++ b/gcc/config/epiphany/epiphany.c @@ -136,6 +136,13 @@ static rtx frame_insn (rtx); hook_bool_const_tree_hwi_hwi_const_tree_true #define TARGET_ASM_OUTPUT_MI_THUNK epiphany_output_mi_thunk +/* ??? we can use larger offsets for wider-mode sized accesses, but there + is no concept of anchors being dependent on the modes that they are used + for, so we can only use an offset range that would suit all modes. */ +#define TARGET_MAX_ANCHOR_OFFSET 2047 +/* We further restrict the minimum to be a multiple of eight. */ +#define TARGET_MIN_ANCHOR_OFFSET -2040 + #include "target-def.h" #undef TARGET_ASM_ALIGNED_HI_OP @@ -746,6 +753,11 @@ epiphany_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, *total = COSTS_N_INSNS (1); return true; + case PLUS: case MINUS: + if (outer_code == SET) + *total = 0; + return false; + default: return false; } @@ -1987,7 +1999,7 @@ epiphany_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) && LEGITIMATE_OFFSET_ADDRESS_P (mode, XEXP ((x), 1))) return true; if (mode == BLKmode) - return true; + return epiphany_legitimate_address_p (SImode, x, strict); return false; } diff --git a/gcc/config/epiphany/epiphany.h b/gcc/config/epiphany/epiphany.h index bd84b5c..e5c8190 100644 --- a/gcc/config/epiphany/epiphany.h +++ b/gcc/config/epiphany/epiphany.h @@ -940,4 +940,15 @@ extern struct rtl_opt_pass pass_resolve_sw_modes; #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ epiphany_start_function ((FILE), (NAME), (DECL)) +/* This is how we tell the assembler that two symbols have the same value. */ +#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \ + do \ + { \ + assemble_name (FILE, NAME1); \ + fputs (" = ", FILE); \ + assemble_name (FILE, NAME2); \ + fputc ('\n', FILE); \ + } \ + while (0) + #endif /* !GCC_EPIPHANY_H */ diff --git a/gcc/config/epiphany/epiphany.md b/gcc/config/epiphany/epiphany.md index e8756ad..e0cdf71 100644 --- a/gcc/config/epiphany/epiphany.md +++ b/gcc/config/epiphany/epiphany.md @@ -2396,7 +2396,7 @@ (define_insn "stack_adjust_str" (match_operand 1 "any_gpr_operand" "r")) (set (reg:SI GPR_SP) (plus:SI (reg:SI GPR_SP) (match_operand:SI 2 "nonmemory_operand" "rn"))) - (clobber (match_operand:BLK 3 "memory_operand" "=m"))] + (clobber (match_operand:BLK 3 "memclob_operand" "=X"))] "reload_completed" { return (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4 diff --git a/gcc/config/epiphany/predicates.md b/gcc/config/epiphany/predicates.md index b77867c..efbb216 100644 --- a/gcc/config/epiphany/predicates.md +++ b/gcc/config/epiphany/predicates.md @@ -358,6 +358,11 @@ (define_predicate "post_modify_operand" (and (match_code "mem") (match_test "post_modify_address (XEXP (op, 0), Pmode)"))) +; used in the memory clobber of stack_adjust_str, allows addresses with +; large offsets. +(define_predicate "memclob_operand" + (match_code "mem")) + (define_predicate "nonsymbolic_immediate_operand" (ior (match_test "immediate_operand (op, mode)") (match_code "const_vector"))) /* Is this specific enough? */ --- /dev/null 2014-03-19 18:18:19.244212660 +0000 +++ gcc/gcc/testsuite/gcc.target/epiphany/t1068-2.c 2014-04-03 15:14:04.716754677 +0100 @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-common" } */ +/* { dg-final { scan-assembler-times "movt" 4 } } */ + +typedef unsigned int uint32_t; +typedef unsigned int uint16_t; + +struct dma_desc { + uint32_t config; + uint32_t inner_stride; + uint32_t count; + uint32_t outer_stride; + void *src_addr; + void *dst_addr; +}; +typedef struct dma_desc e_dma_desc_t; + +e_dma_desc_t dma; +int a; +int id[8]; +#define NULL ((void *)0) + +static inline void _ez_dma_set(register e_dma_desc_t *dma, + uint32_t config, + e_dma_desc_t *next, + uint16_t inner_src, uint16_t inner_dst, + uint16_t inner_count, uint16_t outer_count, + uint16_t outer_src, uint16_t outer_dst, + void *src, void*dst) { + //register e_dma_desc_t *dmap = dma; + + dma->config = config | (((uint32_t)next)<<16); + dma->inner_stride = (inner_dst << 16) | inner_src; + dma->count = (inner_count << 16) | outer_count; + dma->outer_stride = (outer_dst << 16) | outer_src; + dma->src_addr = src; + dma->dst_addr = dst; +} + +void __attribute__((section(".text.ds1"))) +dmas_inline1(void) { + register e_dma_desc_t *dmap = &dma; + + _ez_dma_set(dmap, 3, NULL, + 1, 2, + 12, 13, + 5, 1, + id, &a); +}