[visium] Adjust to recent assembler change

Message ID 1853354.h98lnE5IXV@polaris
State New
Headers show
Series
  • [visium] Adjust to recent assembler change
Related show

Commit Message

Eric Botcazou Feb. 15, 2019, 10:41 a.m.
This adjusts the compiler to the assembler change I recently istalled:
  https://sourceware.org/ml/binutils/2019-02/msg00035.html

The final.c one-liner is trivial, it changes the test to the exact condition 
under which the fallthrough code won't segfault.

Tested on visium-elf, applied on the mainline.


2019-02-15  Eric Botcazou  <ebotcazou@adacore.com>

libgcc/
	* config/visium/lib2funcs.c (__set_trampoline_parity): Replace
	TRAMPOLINE_SIZE with __LIBGCC_TRAMPOLINE_SIZE__.
gcc/
	* 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.

-- 
Eric Botcazou

Patch

Index: libgcc/config/visium/lib2funcs.c
===================================================================
--- libgcc/config/visium/lib2funcs.c	(revision 268849)
+++ libgcc/config/visium/lib2funcs.c	(working copy)
@@ -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
Index: gcc/final.c
===================================================================
--- gcc/final.c	(revision 268849)
+++ gcc/final.c	(working copy)
@@ -606,7 +606,7 @@  insn_current_reference_address (rtx_insn
 
   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.
Index: gcc/config/visium/t-visium
===================================================================
--- gcc/config/visium/t-visium	(revision 268849)
+++ gcc/config/visium/t-visium	(working copy)
@@ -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
 # <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
Index: gcc/config/visium/visium-passes.def
===================================================================
--- gcc/config/visium/visium-passes.def	(nonexistent)
+++ gcc/config/visium/visium-passes.def	(working copy)
@@ -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
+<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);
Index: gcc/config/visium/visium-protos.h
===================================================================
--- gcc/config/visium/visium-protos.h	(revision 268849)
+++ gcc/config/visium/visium-protos.h	(working copy)
@@ -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
Index: gcc/config/visium/visium.c
===================================================================
--- gcc/config/visium/visium.c	(revision 268849)
+++ gcc/config/visium/visium.c	(working copy)
@@ -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, tre
 
 	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, tre
 					     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 *co
   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;
 
Index: gcc/config/visium/visium.h
===================================================================
--- gcc/config/visium/visium.h	(revision 268849)
+++ gcc/config/visium/visium.h	(working copy)
@@ -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
 
Index: gcc/config/visium/visium.md
===================================================================
--- gcc/config/visium/visium.md	(revision 268849)
+++ gcc/config/visium/visium.md	(working copy)
@@ -103,6 +103,10 @@  (define_c_enum "unspecv" [
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;
 
+; 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 @@  (define_attr "empty_delay_slot" "false,t
 		? 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 @@  (define_attr "length" ""
                          (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 @@  (define_delay (eq_attr "type" "abs_branc
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;
 
-; 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")