[NDS32] New option -malways-align and -malign-functions.
authorChung-Ju Wu <jasonwucj@gmail.com>
Sun, 8 Apr 2018 06:00:34 +0000 (06:00 +0000)
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>
Sun, 8 Apr 2018 06:00:34 +0000 (06:00 +0000)
gcc/
* config/nds32/nds32-md-auxiliary.c (output_cond_branch): Output align
information if necessary.
(output_cond_branch_compare_zero): Likewise.
* config/nds32/nds32.c (nds32_adjust_insn_length): Consider align case.
(nds32_target_alignment): Refine for alignment.
* config/nds32/nds32.h (NDS32_ALIGN_P): Define.
(FUNCTION_BOUNDARY): Modify.
* config/nds32/nds32.md (call_internal, call_value_internal): Consider
align case.
* config/nds32/nds32.opt (malways-align, malign-functions): New.

From-SVN: r259217

gcc/ChangeLog
gcc/config/nds32/nds32-md-auxiliary.c
gcc/config/nds32/nds32.c
gcc/config/nds32/nds32.h
gcc/config/nds32/nds32.md
gcc/config/nds32/nds32.opt

index 1cd8f38d86d36aa60294acd873ddac172af03a31..6f98ac7af4b6c588e252fb6746054c3912585be2 100644 (file)
@@ -1,3 +1,16 @@
+2018-04-08  Chung-Ju Wu  <jasonwucj@gmail.com>
+
+       * config/nds32/nds32-md-auxiliary.c (output_cond_branch): Output align
+       information if necessary.
+       (output_cond_branch_compare_zero): Likewise.
+       * config/nds32/nds32.c (nds32_adjust_insn_length): Consider align case.
+       (nds32_target_alignment): Refine for alignment.
+       * config/nds32/nds32.h (NDS32_ALIGN_P): Define.
+       (FUNCTION_BOUNDARY): Modify.
+       * config/nds32/nds32.md (call_internal, call_value_internal): Consider
+       align case.
+       * config/nds32/nds32.opt (malways-align, malign-functions): New.
+
 2018-04-08  Monk Chiang  <sh.chiang04@gmail.com>
 
        * config/nds32/constants.md (unspec_volatile_element): Add values for
index 95bd82969abb860fe7b19aa3dad4fa37fe6929ed..720e85a20eb321e040bcbda5e764ae942455b642 100644 (file)
@@ -128,6 +128,8 @@ output_cond_branch (int code, const char *suffix, bool r5_p,
 {
   char pattern[256];
   const char *cond_code;
+  bool align_p = NDS32_ALIGN_P ();
+  const char *align = align_p ? "\t.align\t2\n" : "";
 
   if (r5_p && REGNO (operands[2]) == 5 && TARGET_16_BIT)
     {
@@ -170,14 +172,14 @@ output_cond_branch (int code, const char *suffix, bool r5_p,
       if (r5_p && TARGET_16_BIT)
        {
          snprintf (pattern, sizeof (pattern),
-                   "b%ss38\t %%2, .LCB%%=\n\tj\t%%3\n.LCB%%=:",
-                   cond_code);
+                   "b%ss38\t %%2, .LCB%%=\n\tj\t%%3\n%s.LCB%%=:",
+                   cond_code, align);
        }
       else
        {
          snprintf (pattern, sizeof (pattern),
-                   "b%s%s\t%%1, %%2, .LCB%%=\n\tj\t%%3\n.LCB%%=:",
-                   cond_code, suffix);
+                   "b%s%s\t%%1, %%2, .LCB%%=\n\tj\t%%3\n%s.LCB%%=:",
+                   cond_code, suffix, align);
        }
     }
   else
@@ -207,6 +209,8 @@ output_cond_branch_compare_zero (int code, const char *suffix,
 {
   char pattern[256];
   const char *cond_code;
+  bool align_p = NDS32_ALIGN_P ();
+  const char *align = align_p ? "\t.align\t2\n" : "";
   if (long_jump_p)
     {
       int inverse_code = nds32_inverse_cond_code (code);
@@ -221,8 +225,8 @@ output_cond_branch_compare_zero (int code, const char *suffix,
              .LCB0:
           */
          snprintf (pattern, sizeof (pattern),
-                   "b%sz%s\t.LCB%%=\n\tj\t%%2\n.LCB%%=:",
-                   cond_code, suffix);
+                   "b%sz%s\t.LCB%%=\n\tj\t%%2\n%s.LCB%%=:",
+                   cond_code, suffix, align);
        }
       else
        {
@@ -233,8 +237,8 @@ output_cond_branch_compare_zero (int code, const char *suffix,
                .LCB0:
           */
          snprintf (pattern, sizeof (pattern),
-                   "b%sz%s\t%%1, .LCB%%=\n\tj\t%%2\n.LCB%%=:",
-                   cond_code, suffix);
+                   "b%sz%s\t%%1, .LCB%%=\n\tj\t%%2\n%s.LCB%%=:",
+                   cond_code, suffix, align);
        }
     }
   else
index 9bd7f3fdb0cf6ed328a21040ab7d721a08679b97..76980d3ab1c0ad3ba762db68a2c24b76bfb1ba9b 100644 (file)
@@ -1566,6 +1566,12 @@ nds32_adjust_insn_length (rtx_insn *insn, int length)
     case CODE_FOR_call_internal:
     case CODE_FOR_call_value_internal:
       {
+       if (NDS32_ALIGN_P ())
+         {
+           rtx_insn *next_insn = next_active_insn (insn);
+           if (next_insn && get_attr_length (next_insn) != 2)
+             adjust_value += 2;
+         }
        /* We need insert a nop after a noretun function call
           to prevent software breakpoint corrupt the next function. */
        if (find_reg_note (insn, REG_NORETURN, NULL_RTX))
@@ -4749,6 +4755,28 @@ nds32_ls_333_p (rtx rt, rtx ra, rtx imm, machine_mode mode)
   return false;
 }
 
+/* Return alignment for the label.  */
+int
+nds32_target_alignment (rtx_insn *label)
+{
+  rtx_insn *insn;
+
+  if (!NDS32_ALIGN_P ())
+    return 0;
+
+  insn = next_active_insn (label);
+
+  /* Always align to 4 byte when first instruction after label is jump
+     instruction since length for that might changed, so let's always align
+     it for make sure we don't lose any perfomance here.  */
+  if (insn == 0
+      || (get_attr_length (insn) == 2
+         && !JUMP_P (insn) && !CALL_P (insn)))
+    return 0;
+  else
+    return 2;
+}
+
 bool
 nds32_split_double_word_load_store_p(rtx *operands, bool load_p)
 {
@@ -4780,25 +4808,6 @@ nds32_use_blocks_for_constant_p (machine_mode mode,
     return false;
 }
 
-/* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte.  */
-int
-nds32_target_alignment (rtx_insn *label)
-{
-  rtx_insn *insn;
-
-  if (optimize_size)
-    return 0;
-
-  insn = next_active_insn (label);
-
-  if (insn == 0)
-    return 0;
-  else if ((get_attr_length (insn) % 4) == 0)
-    return 2;
-  else
-    return 0;
-}
-
 /* ------------------------------------------------------------------------ */
 
 /* PART 5: Initialize target hook structure and definitions.  */
index 13664f187e5badd9c65cdaf764da24cf3ca82894..dc82c0a94948446bcda0c4229be8969c0544e88d 100644 (file)
@@ -135,6 +135,11 @@ enum nds32_16bit_address_type
 #define NDS32_SINGLE_WORD_ALIGN_P(value) (((value) & 0x03) == 0)
 #define NDS32_DOUBLE_WORD_ALIGN_P(value) (((value) & 0x07) == 0)
 
+/* Determine whether we would like to have code generation strictly aligned.
+   We set it strictly aligned when -malways-align is enabled.
+   Check gcc/common/config/nds32/nds32-common.c for the optimizations that
+   apply -malways-align.  */
+#define NDS32_ALIGN_P() (TARGET_ALWAYS_ALIGN)
 /* Get alignment according to mode or type information.
    When 'type' is nonnull, there is no need to look at 'mode'.  */
 #define NDS32_MODE_TYPE_ALIGN(mode, type) \
@@ -643,7 +648,8 @@ enum nds32_builtins
 
 #define STACK_BOUNDARY 64
 
-#define FUNCTION_BOUNDARY 32
+#define FUNCTION_BOUNDARY \
+  ((NDS32_ALIGN_P () || TARGET_ALIGN_FUNCTION) ? 32 : 16)
 
 #define BIGGEST_ALIGNMENT 64
 
index 9e3e20a52fa1b0aa0030efe00278d921994a14ee..dd25e0690eff73b180e457d0fb2affdc0bc28b57 100644 (file)
              (clobber (reg:SI TA_REGNUM))])]
   ""
 {
+  rtx_insn *next_insn = next_active_insn (insn);
+  bool align_p = (!(next_insn && get_attr_length (next_insn) == 2))
+                && NDS32_ALIGN_P ();
   switch (which_alternative)
     {
     case 0:
       if (TARGET_16_BIT)
-       return "jral5\t%0";
+       {
+         if (align_p)
+           return "jral5\t%0\;.align 2";
+         else
+           return "jral5\t%0";
+       }
       else
-       return "jral\t%0";
+       {
+         if (align_p)
+           return "jral\t%0\;.align 2";
+         else
+           return "jral\t%0";
+       }
     case 1:
       return nds32_output_call (insn, operands, operands[0],
-                               "bal\t%0", "jal\t%0", false);
+                               "bal\t%0", "jal\t%0", align_p);
     default:
       gcc_unreachable ();
     }
              (clobber (reg:SI TA_REGNUM))])]
   ""
 {
+  rtx_insn *next_insn = next_active_insn (insn);
+  bool align_p = (!(next_insn && get_attr_length (next_insn) == 2))
+                && NDS32_ALIGN_P ();
   switch (which_alternative)
     {
     case 0:
       if (TARGET_16_BIT)
-       return "jral5\t%1";
+       {
+         if (align_p)
+           return "jral5\t%1\;.align 2";
+         else
+           return "jral5\t%1";
+       }
       else
-       return "jral\t%1";
+       {
+         if (align_p)
+           return "jral\t%1\;.align 2";
+         else
+           return "jral\t%1";
+       }
     case 1:
       return nds32_output_call (insn, operands, operands[1],
-                               "bal\t%1", "jal\t%1", false);
+                               "bal\t%1", "jal\t%1", align_p);
     default:
       gcc_unreachable ();
     }
index bb2bbce18eb62b6c4d4bae12fb78b2276e4fa2fa..ec6b9d4786454678f96af45b72de75c6ba85a5d2 100644 (file)
@@ -69,6 +69,14 @@ Use full-set registers for register allocation.
 
 ; ---------------------------------------------------------------
 
+malways-align
+Target Mask(ALWAYS_ALIGN)
+Always align function entry, jump target and return address.
+
+malign-functions
+Target Mask(ALIGN_FUNCTION)
+Align function entry to 4 byte.
+
 mbig-endian
 Target Undocumented RejectNegative Negative(mlittle-endian) Mask(BIG_ENDIAN)
 Generate code in big-endian mode.