Revised mips alignment patches.

Geoff Keating geoffk@ozemail.com.au
Mon Aug 30 23:50:00 GMT 1999


Gavin's comment was:
> I believe the primary reason for aligning labels is to improve cache
> performance.  And that what alignment is correct for a particular cache
> depends on the characteristics of the cache involved (cache line size
> seems to be the important one here).  And there is no standard (or even
> consistantly used convention) across mips processors for these
> characteristics (right?).  So it doesn't make sense to unconditionaly
> align all labels based on TARGET_64BIT.

Which seems reasonable enough.  So, Jeff Law suggested copying
the switches for this from the Cygnus tree.

However, just about every processor gcc targets has a cache.  Many of
them have varying cache line size or instruction fetching performance
between processors.  So many targets will be wanting these
switches.  The switches are meaningful for all processors, they all
have branches.

At present, m68k, i386, and sparc already have these switches in egcs.
So I'd be adding a fourth implementation.  Probably ppc should have
them too, that makes five.  We don't need five copies of similar code.

Also, all the implementations share a common bug: FUNCTION_BOUNDARY is
not just a request for an alignment, it's also an assertion that
function pointers have certain low bits clear (see
get_pointer_alignment in builtins.c and c_alignof in c-typeck.c).  I
don't believe that, for instance, PLT entries know anything about what
-malign-function= argument was passed to gcc.

The attached patches fix this.  The first adds four new generic
switches.  The second defaults them for MIPS in a reasonable way (I
hope), and the third shows how to change existing implementations to
use them by doing it for sparc.

To make these switches work fully, every target that currently defines
LABEL_ALIGN* or LOOP_ALIGN needs to be changed, but the changes are
simple---usually, just delete the macro definition and add a few lines
to the OVERRIDE_OPTIONS procedure.

I don't like the -falign-functions-<n> syntax much either, but I think
the best way to fix it would be to use proper GNU long option syntax
in a huge incompatible change to the compiler.  Perhaps for gcc 4.0 :-).

I can easily make it -falign-functions=<n> if people think
that's an improvement, but we already have -finline-limit-<n>.

As a bonus, this implementation disables the alignment with -Os and
-O0, which the backends don't do at present; the idea here is that if
you're not scheduling, then probably aligning functions is a waste of
space.

What do people think?

-- 
Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/mips-branch-align-4-generic.patch===
Index: egcs/gcc/ChangeLog
0a
Fri Aug 27 18:41:17 1999  Geoffrey Keating  <geoffk@cygnus.com>

	* flags.h: New variables align_loops, align_loops_log,
	align_jumps, align_jumps_log, align_labels, align_labels_log,
	align_functions, align_functions_log.
	* toplev.c: Define them.
	(f_options): Handle -falign-* when they have no argument.
	(main): Add logic to set variables for -falign-functions,
 	-falign-jumps, -falign-labels, -falign-loops.
	(display_help): Print help for new options.
	* final.c (LABEL_ALIGN): Default to align_labels_log.
	(LABEL_ALIGN_MAX_SKIP): Default to align_labels-1.
	(LOOP_ALIGN): Default to align_loops_log.
	(LOOP_ALIGN_MAX_SKIP): Default to align_loops-1.
	(LABEL_ALIGN_AFTER_BARRIER): Default to align_jumps_log.
	(LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP): Default to align_jumps-1.
	* varasm.c (assemble_start_function): Handle align_functions.
	
.
Changed files:
egcs/gcc/ChangeLog
egcs/gcc/cstamp-h.in
egcs/gcc/final.c
egcs/gcc/flags.h
egcs/gcc/invoke.texi
egcs/gcc/tm.texi
egcs/gcc/toplev.c
egcs/gcc/varasm.c
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/final.c	Sat Aug 21 15:26:06 1999
+++ egcs/gcc/final.c	Fri Aug 27 17:00:41 1999
@@ -797,27 +797,27 @@ get_attr_length (insn)
    address mod X to one mod Y, which is Y - X.  */
 
 #ifndef LABEL_ALIGN
-#define LABEL_ALIGN(LABEL) 0
+#define LABEL_ALIGN(LABEL) align_labels_log
 #endif
 
 #ifndef LABEL_ALIGN_MAX_SKIP
-#define LABEL_ALIGN_MAX_SKIP 0
+#define LABEL_ALIGN_MAX_SKIP (align_labels-1)
 #endif
 
 #ifndef LOOP_ALIGN
-#define LOOP_ALIGN(LABEL) 0
+#define LOOP_ALIGN(LABEL) align_loops_log
 #endif
 
 #ifndef LOOP_ALIGN_MAX_SKIP
-#define LOOP_ALIGN_MAX_SKIP 0
+#define LOOP_ALIGN_MAX_SKIP (align_loops-1)
 #endif
 
 #ifndef LABEL_ALIGN_AFTER_BARRIER
-#define LABEL_ALIGN_AFTER_BARRIER(LABEL) 0
+#define LABEL_ALIGN_AFTER_BARRIER(LABEL) align_jumps_log
 #endif
 
 #ifndef LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
-#define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP 0
+#define LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP (align_jumps-1)
 #endif
 
 #ifndef ADDR_VEC_ALIGN
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/flags.h	Wed Aug 25 12:44:02 1999
+++ egcs/gcc/flags.h	Fri Aug 27 17:48:27 1999
@@ -504,6 +504,20 @@ extern int g_switch_set;
 
 extern int inline_max_insns;
 
+/* Values of the -falign-* flags: how much to align labels in code. 
+   0 means `use default', 1 means `don't align'.  
+   For each variable, there is an _log variant which is the power
+   of two not less than the variable, for .align output.  */
+
+extern int align_loops;
+extern int align_loops_log;
+extern int align_jumps;
+extern int align_jumps_log;
+extern int align_labels;
+extern int align_labels_log;
+extern int align_functions;
+extern int align_functions_log;
+
 /* Nonzero if we dump in VCG format, not plain text.  */
 extern int dump_for_graph;
 
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/invoke.texi	Sat Aug 21 15:28:18 1999
+++ egcs/gcc/invoke.texi	Tue Aug 31 13:37:32 1999
@@ -150,15 +150,16 @@ in the following sections.
 @item Optimization Options
 @xref{Optimize Options,,Options that Control Optimization}.
 @smallexample
--fbranch-probabilities  -foptimize-register-moves
+-falign-functions-@var{n}  -falign-labels-@var{n}  -falign-loops-@var{n} 
+-falign-jumps-@var{n}  -fbranch-probabilities  
 -fcaller-saves  -fcse-follow-jumps  -fcse-skip-blocks
 -fdelayed-branch   -fexpensive-optimizations
 -ffast-math  -ffloat-store  -fforce-addr  -fforce-mem
 -fdata-sections -ffunction-sections  -fgcse 
 -finline-functions -finline-limit-@var{n} -fkeep-inline-functions
 -fno-default-inline -fno-defer-pop  -fno-function-cse
--fno-inline  -fno-peephole  -fomit-frame-pointer -fregmove
--frerun-cse-after-loop  -frerun-loop-opt -fschedule-insns
+-fno-inline  -fno-peephole  -fomit-frame-pointer  -foptimize-register-moves
+-fregmove  -frerun-cse-after-loop  -frerun-loop-opt -fschedule-insns
 -fschedule-insns2  -fstrength-reduce  -fthread-jumps
 -funroll-all-loops  -funroll-loops
 -fmove-all-movables  -freduce-all-givs -fstrict-aliasing
@@ -2601,6 +2602,53 @@ should define a function that computes, 
 allowed to alias.  For an example, see the C front-end function
 @code{c_get_alias_set}.
 @end ifset
+
+@item -falign-functions
+@itemx -falign-functions-@var{n}
+Align the start of functions to the next power-of-two greater than
+@var{n}, skipping up to @var{n} bytes.  For instance,
+@samp{-falign-functions-32} aligns functions to the next 32-byte
+boundary, but @samp{-falign-functions-24} would align to the next
+32-byte boundary only if this can be done by skipping 23 bytes or less.
+
+@samp{-fno-align-functions} and @samp{-falign-functions-1} are
+equivalent and mean that functions will not be aligned.
+
+Some assemblers only support this flag when @var{n} is a power of two;
+in that case, it is rounded up.
+
+If @var{n} is not specified, use a machine-dependent default.
+
+@item -falign-labels
+@itemx -falign-labels-@var{n}
+Align all branch targets to a power-of-two boundary, skipping up to
+@var{n} bytes like @samp{-falign-functions}.  This option can easily
+make code slower, because it must insert dummy operations for when the
+branch target is reached in the usual flow of the code.
+
+If @samp{-falign-loops} or @samp{-falign-jumps} is applicable and
+is greater than this value, then their values are used instead.
+
+If @var{n} is not specified, use a machine-dependent default which is
+very likely to be @samp{1}, meaning no alignment.
+
+@item -falign-loops
+@itemx -falign-loops-@var{n}
+Align loops to a power-of-two boundary, skipping up to @var{n} bytes
+like @samp{-falign-functions}.  The hope is that the loop will be
+executed many times, which will make up for any execution of the dummy
+operations.
+
+If @var{n} is not specified, use a machine-dependent default.
+
+@item -falign-jumps
+@itemx -falign-jumps-@var{n}
+Align branch targets to a power-of-two boundary, for branch targets
+where the targets can only be reached by jumping, skipping up to @var{n}
+bytes like @samp{-falign-functions}.  In this case, no dummy operations
+need be executed.
+
+If @var{n} is not specified, use a machine-dependent default.
 
 @end table
 
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/tm.texi	Tue Aug 24 09:29:05 1999
+++ egcs/gcc/tm.texi	Fri Aug 27 18:07:33 1999
@@ -6474,6 +6474,18 @@ This macro need not be defined if you do
 to be done at such a time.  Most machine descriptions do not currently
 define the macro.
 
+Unless it's necessary to inspect the @var{label} parameter, it is better
+to set the variable @var{align_jumps} in the target's
+@code{OVERRIDE_OPTIONS}.  Otherwise, you should try to honour the user's
+selection in @var{align_jumps} in a @code{LABEL_ALIGN_AFTER_BARRIER}
+implementation.
+
+@findex LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
+@item LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
+The maximum number of bytes to skip when applying 
+@code{LABEL_ALIGN_AFTER_BARRIER}.  This works only if
+@code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined.
+
 @findex LOOP_ALIGN
 @item LOOP_ALIGN (@var{label})
 The alignment (log base 2) to put in front of @var{label}, which follows
@@ -6483,11 +6495,31 @@ This macro need not be defined if you do
 to be done at such a time.  Most machine descriptions do not currently
 define the macro.
 
+Unless it's necessary to inspect the @var{label} parameter, it is better
+to set the variable @var{align_loops} in the target's
+@code{OVERRIDE_OPTIONS}.  Otherwise, you should try to honour the user's
+selection in @var{align_loops} in a @code{LOOP_ALIGN} implementation.
+
+@findex LOOP_ALIGN_MAX_SKIP
+@item LOOP_ALIGN_MAX_SKIP
+The maximum number of bytes to skip when applying @code{LOOP_ALIGN}.
+This works only if @code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined.
+
 @findex LABEL_ALIGN
 @item LABEL_ALIGN (@var{label})
 The alignment (log base 2) to put in front of @var{label}.
 If LABEL_ALIGN_AFTER_BARRIER / LOOP_ALIGN specify a different alignment,
 the maximum of the specified values is used.
+
+Unless it's necessary to inspect the @var{label} parameter, it is better
+to set the variable @var{align_labels} in the target's
+@code{OVERRIDE_OPTIONS}.  Otherwise, you should try to honour the user's
+selection in @var{align_labels} in a @code{LABEL_ALIGN} implementation.
+
+@findex LABEL_ALIGN_MAX_SKIP
+@item LABEL_ALIGN_MAX_SKIP
+The maximum number of bytes to skip when applying @code{LABEL_ALIGN}.
+This works only if @code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined.
 
 @findex ASM_OUTPUT_SKIP
 @item ASM_OUTPUT_SKIP (@var{stream}, @var{nbytes})
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/toplev.c	Wed Aug 25 12:44:07 1999
+++ egcs/gcc/toplev.c	Tue Aug 31 13:24:40 1999
@@ -764,6 +764,20 @@ int flag_instrument_function_entry_exit 
 
 int flag_no_ident = 0;
 
+/* Values of the -falign-* flags: how much to align labels in code. 
+   0 means `use default', 1 means `don't align'.  
+   For each variable, there is an _log variant which is the power
+   of two not less than the variable, for .align output.  */
+
+int align_loops;
+int align_loops_log;
+int align_jumps;
+int align_jumps_log;
+int align_labels;
+int align_labels_log;
+int align_functions;
+int align_functions_log;
+
 /* Table of supported debugging formats.  */
 static struct
 {
@@ -958,6 +972,14 @@ lang_independent_options f_options[] =
    "Assume arguments do not alias each other or globals" },
   {"strict-aliasing", &flag_strict_aliasing, 1,
    "Assume strict aliasing rules apply" },
+  {"align-loops", &align_loops, 0, 
+   "Align the start of loops" },
+  {"align-jumps", &align_jumps, 0, 
+   "Align labels which are only reached by jumping" },
+  {"align-labels", &align_labels, 0,
+   "Align all labels" },
+  {"align-functions", &align_functions, 0,
+   "Align the start of functions" },
   {"check-memory-usage", &flag_check_memory_usage, 1,
    "Generate code to check every memory access" },
   {"prefix-function-name", &flag_prefix_function_name, 1,
@@ -4883,6 +4905,14 @@ main (argc, argv)
       flag_inline_functions = 1;
     }
 
+  if (optimize < 2 || optimize_size)
+    {
+      align_loops = 1;
+      align_jumps = 1;
+      align_labels = 1;
+      align_functions = 1;
+    }
+
   /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
      modify it.  */
   target_flags = 0;
@@ -5101,6 +5131,18 @@ main (argc, argv)
 		fix_register (&p[10], 0, 1);
 	      else if (!strncmp (p, "call-saved-", 11))
 		fix_register (&p[11], 0, 0);
+	      else if (!strncmp (p, "align-loops-", 12))
+		align_loops = read_integral_parameter (p + 12, p - 2,
+						       align_loops);
+	      else if (!strncmp (p, "align-functions-", 16))
+		align_functions = read_integral_parameter (p + 16, p - 2,
+						       align_functions);
+	      else if (!strncmp (p, "align-jumps-", 12))
+		align_jumps = read_integral_parameter (p + 12, p - 2,
+						       align_jumps);
+	      else if (!strncmp (p, "align-labels-", 13))
+		align_labels = read_integral_parameter (p + 13, p - 2,
+							align_labels);
 	      else
 		error ("Invalid option `%s'", argv[i]);
 	    }
@@ -5387,6 +5429,17 @@ main (argc, argv)
 #endif
     }
 
+  /* Set up the align_*_log variables, defaulting them to 1 if they
+     were still unset.  */
+  if (align_loops <= 0) align_loops = 1;
+  align_loops_log = floor_log2 (align_loops);
+  if (align_jumps <= 0) align_jumps = 1;
+  align_jumps_log = floor_log2 (align_jumps);
+  if (align_labels <= 0) align_labels = 1;
+  align_labels_log = floor_log2 (align_labels);
+  if (align_functions <= 0) align_functions = 1;
+  align_functions_log = floor_log2 (align_functions);
+  
   if (profile_block_flag == 3)
     {
       warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/varasm.c	Sat Aug 21 15:26:17 1999
+++ egcs/gcc/varasm.c	Fri Aug 27 17:47:43 1999
@@ -979,6 +979,19 @@ assemble_start_function (decl, fnname)
   if (align > 0)
     ASM_OUTPUT_ALIGN (asm_out_file, align);
 
+  /* Handle a user-specified function alignment.
+     Note that we still need to align to FUNCTION_BOUNDARY, as above,
+     because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all.  */
+  if (align_functions_log > align)
+    {
+#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
+      ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 
+				 align_functions_log, align_functions-1);
+#else
+      ASM_OUTPUT_ALIGN (asm_out_file, align_functions_log);
+#endif
+    }
+
 #ifdef ASM_OUTPUT_FUNCTION_PREFIX
   ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname);
 #endif
0============================================================

===File ~/patches/cygnus/mips-branch-align-4-mips.patch=====
Index: egcs/gcc/ChangeLog
0a
Fri Aug 27 18:41:17 1999  Geoffrey Keating  <geoffk@cygnus.com>

	* config/mips/mips.c (override_options):  On 64-bit targets,
	try to align things to 64-bit boundaries.
	(print_operand): New substitution, %~,
	which aligns labels to align_labels_log.
	* config/mips/mips.md (div_trap_normal): Use %~.
	(div_trap_mips16): Likewise.
	(abssi): Likewise.
	(absdi2): Likewise.
	(ffssi2): Likewise.
	(ffsdi2): Likewise.
	(ashldi3_internal): Likewise.
	(ashrdi3_internal): Likewise.
	(lshrdi3_internal): Likewise.
	(casesi_internal): Likewise.

.
Changed files:
egcs/gcc/ChangeLog
egcs/gcc/config/mips/mips.c
egcs/gcc/config/mips/mips.md
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/config/mips/mips.c	Tue Aug 10 12:57:42 1999
+++ egcs/gcc/config/mips/mips.c	Tue Aug 31 15:26:30 1999
@@ -4413,6 +4413,7 @@ override_options ()
   mips_print_operand_punct['^'] = 1;
   mips_print_operand_punct['$'] = 1;
   mips_print_operand_punct['+'] = 1;
+  mips_print_operand_punct['~'] = 1;
 
   mips_char_to_class['d'] = TARGET_MIPS16 ? M16_REGS : GR_REGS;
   mips_char_to_class['e'] = M16_NA_REGS;
@@ -4493,6 +4494,17 @@ override_options ()
   /* Save GPR registers in word_mode sized hunks.  word_mode hasn't been
      initialized yet, so we can't use that here.  */
   gpr_mode = TARGET_64BIT ? DImode : SImode;
+
+  /* Provide default values for align_* for 64-bit targets.  */
+  if (TARGET_64BIT)
+    {
+      if (align_loops == 0) 
+	align_loops = 8;
+      if (align_jumps == 0) 
+	align_jumps = 8;
+      if (align_functions == 0) 
+	align_functions = 8;
+    }
 }
 
 /* On the mips16, we want to allocate $24 (T_REG) before other
@@ -4617,7 +4629,8 @@ mips_debugger_offset (addr, offset)
    '.'	Print the name of the register with a hard-wired zero (zero or $0).
    '^'	Print the name of the pic call-through register (t9 or $25).
    '$'	Print the name of the stack pointer register (sp or $29).
-   '+'	Print the name of the gp register (gp or $28).  */
+   '+'	Print the name of the gp register (gp or $28).
+   '~'	Output an branch alignment to LABEL_ALIGN(NULL).  */
 
 void
 print_operand (file, op, letter)
@@ -4737,6 +4750,13 @@ print_operand (file, op, letter)
 	    fprintf (file, "\n\t%s.set\tnovolatile", (TARGET_MIPS_AS) ? "" : "#");
 
 	  break;
+
+	case '~':
+	  {
+	    if (align_labels_log > 0)
+	      ASM_OUTPUT_ALIGN (file, align_labels_log);
+	  }
+	break;
 
 	default:
 	  error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/config/mips/mips.md	Thu Jul 22 12:57:47 1999
+++ egcs/gcc/config/mips/mips.md	Wed Aug 25 16:14:37 1999
@@ -2418,16 +2418,16 @@ (define_insn "div_trap_normal"
       if (GENERATE_BRANCHLIKELY)
 	{
           if (GET_CODE (operands[1]) == CONST_INT)
-	    return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n1:%)\";
+	    return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
 	  else
-	    return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n1:%)\";
+	    return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
 	}
       else
 	{
           if (GET_CODE (operands[1]) == CONST_INT)
-	    return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n1:%)\";
+	    return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
 	  else
-	    return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n1:%)\";
+	    return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\";
 	}
     }
   return \"\";
@@ -2462,9 +2462,9 @@ (define_insn "div_trap_mips16"
     {
       /* No branch delay slots on mips16. */ 
       if (GET_CODE (operands[1]) == CONST_INT)
-        return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n1:%)\";
+        return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\";
       else
-        return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n1:%)\";
+        return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\";
     }
   return \"\";
 }"
@@ -2820,12 +2820,12 @@ (define_insn "abssi2"
   if (REGNO (operands[0]) == REGNO (operands[1]))
     {
       if (GENERATE_BRANCHLIKELY)
-	return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
+	return \"%(bltzl\\t%1,1f\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
       else
-	return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n1:\";
+	return \"bgez\\t%1,1f%#\\n\\tsubu\\t%0,%z2,%0\\n%~1:\";
     }	  
   else
-    return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n1:%)\";
+    return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tsubu\\t%0,%z2,%0\\n%~1:%)\";
 }"
   [(set_attr "type"	"multi")
    (set_attr "mode"	"SI")
@@ -2842,9 +2842,9 @@ (define_insn "absdi2"
   operands[2] = const0_rtx;
 
   if (REGNO (operands[0]) == REGNO (operands[1]))
-    return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
+    return \"%(bltzl\\t%1,1f\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
   else
-    return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n1:%)\";
+    return \"%(bgez\\t%1,1f\\n\\tmove\\t%0,%1\\n\\tdsubu\\t%0,%z2,%0\\n%~1:%)\";
 }"
   [(set_attr "type"	"multi")
    (set_attr "mode"	"DI")
@@ -2891,21 +2891,21 @@ (define_insn "ffssi2"
     return \"%(\\
 move\\t%0,%z4\\n\\
 \\tbeq\\t%1,%z4,2f\\n\\
-1:\\tand\\t%2,%1,0x0001\\n\\
+%~1:\\tand\\t%2,%1,0x0001\\n\\
 \\taddu\\t%0,%0,1\\n\\
 \\tbeq\\t%2,%z4,1b\\n\\
 \\tsrl\\t%1,%1,1\\n\\
-2:%)\";
+%~2:%)\";
 
   return \"%(\\
 move\\t%0,%z4\\n\\
 \\tmove\\t%3,%1\\n\\
 \\tbeq\\t%3,%z4,2f\\n\\
-1:\\tand\\t%2,%3,0x0001\\n\\
+%~1:\\tand\\t%2,%3,0x0001\\n\\
 \\taddu\\t%0,%0,1\\n\\
 \\tbeq\\t%2,%z4,1b\\n\\
 \\tsrl\\t%3,%3,1\\n\\
-2:%)\";
+%~2:%)\";
 }"
   [(set_attr "type"	"multi")
    (set_attr "mode"	"SI")
@@ -2927,21 +2927,21 @@ (define_insn "ffsdi2"
     return \"%(\\
 move\\t%0,%z4\\n\\
 \\tbeq\\t%1,%z4,2f\\n\\
-1:\\tand\\t%2,%1,0x0001\\n\\
+%~1:\\tand\\t%2,%1,0x0001\\n\\
 \\tdaddu\\t%0,%0,1\\n\\
 \\tbeq\\t%2,%z4,1b\\n\\
 \\tdsrl\\t%1,%1,1\\n\\
-2:%)\";
+%~2:%)\";
 
   return \"%(\\
 move\\t%0,%z4\\n\\
 \\tmove\\t%3,%1\\n\\
 \\tbeq\\t%3,%z4,2f\\n\\
-1:\\tand\\t%2,%3,0x0001\\n\\
+%~1:\\tand\\t%2,%3,0x0001\\n\\
 \\tdaddu\\t%0,%0,1\\n\\
 \\tbeq\\t%2,%z4,1b\\n\\
 \\tdsrl\\t%3,%3,1\\n\\
-2:%)\";
+%~2:%)\";
 }"
   [(set_attr "type"	"multi")
    (set_attr "mode"	"DI")
@@ -6471,16 +6471,16 @@ (define_insn "ashldi3_internal"
 \\t%(b\\t3f\\n\\
 \\tmove\\t%L0,%z4%)\\n\\
 \\n\\
-1:\\n\\
+%~1:\\n\\
 \\t%(beq\\t%3,%z4,2f\\n\\
 \\tsll\\t%M0,%M1,%2%)\\n\\
 \\n\\
 \\tsubu\\t%3,%z4,%2\\n\\
 \\tsrl\\t%3,%L1,%3\\n\\
 \\tor\\t%M0,%M0,%3\\n\\
-2:\\n\\
+%~2:\\n\\
 \\tsll\\t%L0,%L1,%2\\n\\
-3:\";
+%~3:\";
 }"
   [(set_attr "type"	"darith")
    (set_attr "mode"	"SI")
@@ -6829,16 +6829,16 @@ (define_insn "ashrdi3_internal"
 \\t%(b\\t3f\\n\\
 \\tsra\\t%M0,%M1,31%)\\n\\
 \\n\\
-1:\\n\\
+%~1:\\n\\
 \\t%(beq\\t%3,%z4,2f\\n\\
 \\tsrl\\t%L0,%L1,%2%)\\n\\
 \\n\\
 \\tsubu\\t%3,%z4,%2\\n\\
 \\tsll\\t%3,%M1,%3\\n\\
 \\tor\\t%L0,%L0,%3\\n\\
-2:\\n\\
+%~2:\\n\\
 \\tsra\\t%M0,%M1,%2\\n\\
-3:\";
+%~3:\";
 }"
   [(set_attr "type"	"darith")
    (set_attr "mode"	"DI")
@@ -7210,16 +7210,16 @@ (define_insn "lshrdi3_internal"
 \\t%(b\\t3f\\n\\
 \\tmove\\t%M0,%z4%)\\n\\
 \\n\\
-1:\\n\\
+%~1:\\n\\
 \\t%(beq\\t%3,%z4,2f\\n\\
 \\tsrl\\t%L0,%L1,%2%)\\n\\
 \\n\\
 \\tsubu\\t%3,%z4,%2\\n\\
 \\tsll\\t%3,%M1,%3\\n\\
 \\tor\\t%L0,%L0,%3\\n\\
-2:\\n\\
+%~2:\\n\\
 \\tsrl\\t%M0,%M1,%2\\n\\
-3:\";
+%~3:\";
 }"
   [(set_attr "type"	"darith")
    (set_attr "mode"	"DI")
@@ -9308,7 +9308,7 @@ (define_insn "casesi_internal"
   "TARGET_EMBEDDED_PIC"
   "*
 {
-  output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%S1:\", operands);
+  output_asm_insn (\"%(bal\\t%S1\;sll\\t%0,2\\n%~%S1:\", operands);
   output_asm_insn (\"addu\\t%0,%0,$31%)\", operands);
   output_asm_insn (\"lw\\t%0,%1-%S1(%0)\;addu\\t%0,%0,$31\", operands);
   return \"j\\t%0\";
============================================================

===File ~/patches/cygnus/mips-branch-align-4-sparc.patch====
Index: egcs/gcc/ChangeLog
0a
Tue Aug 31 15:37:09 1999  Geoffrey Keating  <geoffk@cygnus.com>

	* config/sparc/sparc.h: Don't declare sparc_align_*.
	Don't provide LABEL_ALIGN_AFTER_BARRIER or LOOP_ALIGN.
	(DEFAULT_SPARC_ALIGN_FUNCS): Delete; take functionality into
 	sparc.c.
	(FUNCTION_BOUNDARY): Fix incorrect use---it's not just a request,
	it's a promise.
	* config/sparc/sparc.c: Delete sparc_align_loops,
 	sparc_align_jumps, sparc_align_funcs.
	(sparc_override_options): Default align_functions on ultrasparc.
	Provide backwards compatibility for -malign-loops, -malign-jumps,
	-malign-functions.

.
Changed files:
egcs/gcc/ChangeLog
egcs/gcc/config/sparc/sparc.c
egcs/gcc/config/sparc/sparc.h
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/config/sparc/sparc.c	Tue Aug 10 12:57:52 1999
+++ egcs/gcc/config/sparc/sparc.c	Tue Aug 31 15:34:45 1999
@@ -137,11 +137,6 @@ const char *sparc_align_loops_string;
 const char *sparc_align_jumps_string;
 const char *sparc_align_funcs_string;
 
-/* Parsed values, as a power of two.  */
-int sparc_align_loops;
-int sparc_align_jumps;
-int sparc_align_funcs;
-
 char sparc_hard_reg_printed[8];
 
 struct sparc_cpu_select sparc_select[] =
@@ -325,46 +320,21 @@ sparc_override_options ()
   if (! TARGET_FPU)
     target_flags &= ~MASK_VIS;
 
-  /* Validate -malign-loops= value, or provide default.  */
+  /* Supply a default value for align_functions.  */
+  if (align_functions == 0 && sparc_cpu == PROCESSOR_ULTRASPARC)
+    align_functions = 32;
+
+  /* Handle -malign-*=.  The user shouldn't supply both -falign-* and
+     -malign-*; if they do, the -m is applied irregardless of the
+     order of the options.  */
   if (sparc_align_loops_string)
-    {
-      sparc_align_loops = exact_log2 (atoi (sparc_align_loops_string));
-      if (sparc_align_loops < 2 || sparc_align_loops > 7)
-	fatal ("-malign-loops=%s is not between 4 and 128 or is not a power of two",
-	       sparc_align_loops_string);
-    }
-  else
-    {
-      /* ??? This relies on ASM_OUTPUT_ALIGN to not emit the alignment if
-	 its 0.  This sounds a bit kludgey.  */
-      sparc_align_loops = 0;
-    }
+    align_loops = atoi (sparc_align_loops_string);
 
-  /* Validate -malign-jumps= value, or provide default.  */
   if (sparc_align_jumps_string)
-    {
-      sparc_align_jumps = exact_log2 (atoi (sparc_align_jumps_string));
-      if (sparc_align_jumps < 2 || sparc_align_loops > 7)
-	fatal ("-malign-jumps=%s is not between 4 and 128 or is not a power of two",
-	       sparc_align_jumps_string);
-    }
-  else
-    {
-      /* ??? This relies on ASM_OUTPUT_ALIGN to not emit the alignment if
-	 its 0.  This sounds a bit kludgey.  */
-      sparc_align_jumps = 0;
-    }
+    align_jumps = atoi (sparc_align_jumps_string);
 
-  /* Validate -malign-functions= value, or provide default. */
   if (sparc_align_funcs_string)
-    {
-      sparc_align_funcs = exact_log2 (atoi (sparc_align_funcs_string));
-      if (sparc_align_funcs < 2 || sparc_align_loops > 7)
-	fatal ("-malign-functions=%s is not between 4 and 128 or is not a power of two",
-	       sparc_align_funcs_string);
-    }
-  else
-    sparc_align_funcs = DEFAULT_SPARC_ALIGN_FUNCS;
+    align_functions = atoi (sparc_align_funcs_string);
 
   /* Validate PCC_STRUCT_RETURN.  */
   if (flag_pcc_struct_return == DEFAULT_PCC_STRUCT_RETURN)
--- /sloth/disk0/co/egcs-mainline/egcs/gcc/config/sparc/sparc.h	Tue Aug 24 09:29:08 1999
+++ egcs/gcc/config/sparc/sparc.h	Tue Aug 31 15:35:36 1999
@@ -658,6 +658,8 @@ extern enum processor_type sparc_cpu;
 	extern char *m88k_short_data;
 	#define TARGET_OPTIONS { { "short-data-", &m88k_short_data } }  */
 
+/* The -malign-* options are obsolete and should be removed, eventually.  */
+
 #define TARGET_OPTIONS \
 {							\
   { "cpu=",  &sparc_select[1].string, "Use features of and schedule code for given CPU" }, \
@@ -687,13 +689,6 @@ extern struct sparc_cpu_select sparc_sel
 extern const char *sparc_align_loops_string;
 extern const char *sparc_align_jumps_string;
 extern const char *sparc_align_funcs_string;
-/* Parsed values as a power of two.  */
-extern int sparc_align_loops;
-extern int sparc_align_jumps;
-extern int sparc_align_funcs;
-
-#define DEFAULT_SPARC_ALIGN_FUNCS \
-(sparc_cpu == PROCESSOR_ULTRASPARC ? 5 : 2)
 
 /* target machine storage layout */
 
@@ -799,7 +794,7 @@ if (TARGET_ARCH64				\
   (TARGET_ARCH64 ? (((LOC)+15) & ~15) : (((LOC)+7) & ~7))
 
 /* Allocation boundary (in *bits*) for the code of a function.  */
-#define FUNCTION_BOUNDARY (1 << (sparc_align_funcs + 3))
+#define FUNCTION_BOUNDARY 32
 
 /* Alignment of field after `int : 0' in a structure.  */
 #define EMPTY_FIELD_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
@@ -3037,10 +3032,6 @@ do {									\
 #define ASM_OUTPUT_ALIGN(FILE,LOG)	\
   if ((LOG) != 0)			\
     fprintf (FILE, "\t.align %d\n", (1<<(LOG)))
-
-#define LABEL_ALIGN_AFTER_BARRIER(LABEL) (sparc_align_jumps)
-
-#define LOOP_ALIGN(LABEL) (sparc_align_loops)
 
 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
   fprintf (FILE, "\t.skip %u\n", (SIZE))
============================================================


More information about the Gcc-patches mailing list