+2019-02-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * 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 <rguenther@suse.de>
Jakub Jelinek <jakub@redhat.com>
-# 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.
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
+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
--- /dev/null
+/* 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
+<http://www.gnu.org/licenses/>. */
+
+/*
+ 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);
extern unsigned int reg_or_subreg_regno (rtx);
#endif /* RTX_CODE */
+extern rtl_opt_pass * make_pass_visium_reorg (gcc::context *);
+
#endif
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. */
moviu r9,%u FUNCTION
movil r9,%l FUNCTION
+ [nop]
moviu r20,%u STATIC
bra tr,r9,r9
movil r20,%l STATIC
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,
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;
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
+; 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.
? 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))
(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)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
-; 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")
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.
+2019-02-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/visium/lib2funcs.c (__set_trampoline_parity): Replace
+ TRAMPOLINE_SIZE with __LIBGCC_TRAMPOLINE_SIZE__.
+
2019-01-31 Uroš Bizjak <ubizjak@gmail.com>
* config/alpha/t-linux: Add -mfp-rounding-mode=d
{
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