diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a9b7ed292e8..9d130110cab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2019-02-15 Eric Botcazou + + * final.c (insn_current_reference_address): Replace test on JUMP_P + with test on jump_to_label_p. + * config/visium/visium-passes.def: New file. + * config/visium/t-visium (PASSES_EXTRA): Define. + * config/visium/visium-protos.h (make_pass_visium_reorg): Declare. + * config/visium/visium.h (TRAMPOLINE_SIZE): Adjust. + (TRAMPOLINE_ALIGNMENT): Define. + * config/visium/visium.c (visium_option_override): Do not register + the machine-specific reorg pass here. + (visium_trampoline_init): Align the BRA insn on a 64-bit boundary + for the GR6. + (output_branch): Adjust threshold for long branch instruction. + * config/visium/visium.md (cpu): Move around. + (length): Adjust for the GR6. + 2019-02-15 Richard Biener Jakub Jelinek diff --git a/gcc/config/visium/t-visium b/gcc/config/visium/t-visium index ea5e329fa1e..a086615c4b9 100644 --- a/gcc/config/visium/t-visium +++ b/gcc/config/visium/t-visium @@ -1,4 +1,5 @@ -# Multilibs for Visium. +# General rules that all visium/ targets must have. + # Copyright (C) 2012-2019 Free Software Foundation, Inc. # # This file is part of GCC. @@ -17,6 +18,8 @@ # along with GCC; see the file COPYING3. If not see # . +PASSES_EXTRA += $(srcdir)/config/visium/visium-passes.def + # The compiler defaults to -mcpu=gr5 but this may be overridden via --with-cpu # at configure time so the -mcpu setting must be symmetrical. MULTILIB_OPTIONS = mcpu=gr5/mcpu=gr6 muser-mode diff --git a/gcc/config/visium/visium-passes.def b/gcc/config/visium/visium-passes.def new file mode 100644 index 00000000000..17c519cc838 --- /dev/null +++ b/gcc/config/visium/visium-passes.def @@ -0,0 +1,27 @@ +/* Description of target passes for Visium. + Copyright (C) 2018 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* + Macros that can be used in this file: + INSERT_PASS_AFTER (PASS, INSTANCE, TGT_PASS) + INSERT_PASS_BEFORE (PASS, INSTANCE, TGT_PASS) + REPLACE_PASS (PASS, INSTANCE, TGT_PASS) + */ + + INSERT_PASS_AFTER (pass_delay_slots, 1, pass_visium_reorg); diff --git a/gcc/config/visium/visium-protos.h b/gcc/config/visium/visium-protos.h index a8734bd9d89..a44a2cf24e9 100644 --- a/gcc/config/visium/visium-protos.h +++ b/gcc/config/visium/visium-protos.h @@ -61,4 +61,6 @@ extern int visium_expand_block_set (rtx *); extern unsigned int reg_or_subreg_regno (rtx); #endif /* RTX_CODE */ +extern rtl_opt_pass * make_pass_visium_reorg (gcc::context *); + #endif diff --git a/gcc/config/visium/visium.c b/gcc/config/visium/visium.c index 39f6ab3bd1e..67bc2d6d220 100644 --- a/gcc/config/visium/visium.c +++ b/gcc/config/visium/visium.c @@ -484,20 +484,6 @@ visium_option_override (void) else str_align_jumps = "8"; } - - /* We register a machine-specific pass. This pass must be scheduled as - late as possible so that we have the (essentially) final form of the - insn stream to work on. Registering the pass must be done at start up. - It's convenient to do it here. */ - opt_pass *visium_reorg_pass = make_pass_visium_reorg (g); - struct register_pass_info insert_pass_visium_reorg = - { - visium_reorg_pass, /* pass */ - "dbr", /* reference_pass_name */ - 1, /* ref_pass_instance_number */ - PASS_POS_INSERT_AFTER /* po_op */ - }; - register_pass (&insert_pass_visium_reorg); } /* Register the Visium-specific libfuncs with the middle-end. */ @@ -2725,6 +2711,7 @@ visium_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain) moviu r9,%u FUNCTION movil r9,%l FUNCTION + [nop] moviu r20,%u STATIC bra tr,r9,r9 movil r20,%l STATIC @@ -2745,6 +2732,14 @@ visium_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain) NULL_RTX), 0x04890000)); + if (visium_cpu == PROCESSOR_GR6) + { + /* For the GR6, the BRA insn must be aligned on a 64-bit boundary. */ + gcc_assert (TRAMPOLINE_ALIGNMENT >= 64); + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (Pmode, addr, 12)), + gen_int_mode (0, SImode)); + } + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (Pmode, addr, 8)), plus_constant (SImode, expand_shift (RSHIFT_EXPR, SImode, @@ -3059,9 +3054,9 @@ output_branch (rtx label, const char *cond, rtx_insn *insn) gcc_assert (cond); operands[0] = label; - /* If the length of the instruction is greater than 8, then this is a + /* If the length of the instruction is greater than 12, then this is a long branch and we need to work harder to emit it properly. */ - if (get_attr_length (insn) > 8) + if (get_attr_length (insn) > 12) { bool spilled; diff --git a/gcc/config/visium/visium.h b/gcc/config/visium/visium.h index 331a83eafa6..817e7dc70fc 100644 --- a/gcc/config/visium/visium.h +++ b/gcc/config/visium/visium.h @@ -1045,16 +1045,20 @@ struct visium_args moviu r9,%u FUNCTION movil r9,%l FUNCTION + [nop] moviu r20,%u STATIC bra tr,r9,r0 - movil r20,%l STATIC + movil r20,%l STATIC A difficulty is setting the correct instruction parity at run time. TRAMPOLINE_SIZE A C expression for the size in bytes of the trampoline, as an integer. */ -#define TRAMPOLINE_SIZE 20 +#define TRAMPOLINE_SIZE (visium_cpu == PROCESSOR_GR6 ? 24 : 20) + +/* Alignment required for trampolines, in bits. */ +#define TRAMPOLINE_ALIGNMENT (visium_cpu == PROCESSOR_GR6 ? 64 : 32) /* Implicit calls to library routines diff --git a/gcc/config/visium/visium.md b/gcc/config/visium/visium.md index 44c0923dad6..f5354413427 100644 --- a/gcc/config/visium/visium.md +++ b/gcc/config/visium/visium.md @@ -103,6 +103,10 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; +; Attribute for cpu type. +; These must match the values for enum processor_type in visium-opts.h. +(define_attr "cpu" "gr5,gr6" (const (symbol_ref "visium_cpu_attr"))) + ; Instruction type. ; ;imm_reg Move of immediate value to register. @@ -154,14 +158,25 @@ ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)")) ; Length in bytes. -; The allowed range for the offset of short branches is [-131072;131068] +; On the GR6, absolute branches must be aligned on a 64-bit boundary to avoid +; a pipeline hazard. This is done by the assembler, so the length of these +; instructions for the compiler can effectively be 4, 8, or 12 bytes. +; The allowed range for the offset of relative branches is [-131072;131068] ; and it is counted from the address of the insn so we need to subtract ; 8 for forward branches because (pc) points to the next insn for them. (define_attr "length" "" (cond [(eq_attr "type" "abs_branch,call,ret") (if_then_else (eq_attr "empty_delay_slot" "true") - (const_int 8) - (const_int 4)) + (if_then_else (and (eq_attr "cpu" "gr6") + (eq (mod (pc) (const_int 8)) + (const_int 4))) + (const_int 12) + (const_int 8)) + (if_then_else (and (eq_attr "cpu" "gr6") + (eq (mod (pc) (const_int 8)) + (const_int 4))) + (const_int 8) + (const_int 4))) (eq_attr "type" "branch") (if_then_else (leu (plus (minus (match_dup 0) (pc)) (const_int 131060)) @@ -169,7 +184,11 @@ (if_then_else (eq_attr "empty_delay_slot" "true") (const_int 8) (const_int 4)) - (const_int 20)) + (if_then_else (and (eq_attr "cpu" "gr6") + (eq (mod (pc) (const_int 8)) + (const_int 0))) + (const_int 24) + (const_int 20))) (eq_attr "single_insn" "no") (const_int 8)] (const_int 4))) @@ -189,10 +208,6 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -; Attribute for cpu type. -; These must match the values for enum processor_type in visium-opts.h. -(define_attr "cpu" "gr5,gr6" (const (symbol_ref "visium_cpu_attr"))) - (include "gr5.md") (include "gr6.md") diff --git a/gcc/final.c b/gcc/final.c index f6edd6a1dfc..fefc4874b24 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -606,7 +606,7 @@ insn_current_reference_address (rtx_insn *branch) rtx_insn *seq = NEXT_INSN (PREV_INSN (branch)); seq_uid = INSN_UID (seq); - if (!JUMP_P (branch)) + if (!jump_to_label_p (branch)) /* This can happen for example on the PA; the objective is to know the offset to address something in front of the start of the function. Thus, we can treat it like a backward branch. diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 7af2511c11b..65cd3f97cdd 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,8 @@ +2019-02-15 Eric Botcazou + + * config/visium/lib2funcs.c (__set_trampoline_parity): Replace + TRAMPOLINE_SIZE with __LIBGCC_TRAMPOLINE_SIZE__. + 2019-01-31 Uroš Bizjak * config/alpha/t-linux: Add -mfp-rounding-mode=d diff --git a/libgcc/config/visium/lib2funcs.c b/libgcc/config/visium/lib2funcs.c index c2ad0e8c6d8..4554e7d51ca 100644 --- a/libgcc/config/visium/lib2funcs.c +++ b/libgcc/config/visium/lib2funcs.c @@ -315,7 +315,9 @@ __set_trampoline_parity (UWtype *addr) { int i; - for (i = 0; i < (TRAMPOLINE_SIZE * __CHAR_BIT__) / W_TYPE_SIZE; i++) + for (i = 0; + i < (__LIBGCC_TRAMPOLINE_SIZE__ * __CHAR_BIT__) / W_TYPE_SIZE; + i++) addr[i] |= parity_bit (addr[i]); } #endif