aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/nds32
diff options
context:
space:
mode:
authorChung-Ju Wu <jasonwucj@gmail.com>2018-04-08 06:00:34 +0000
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>2018-04-08 06:00:34 +0000
commit43fa41c1aaa57d59cbb00ed5c8cfa185d075b105 (patch)
tree652b54713eade088d9d7858699c190b4c8fb12da /gcc/config/nds32
parent57aaf0cc9e8bd98c3aac58f21d2ff4f610bc637a (diff)
downloadgcc-43fa41c1aaa57d59cbb00ed5c8cfa185d075b105.zip
gcc-43fa41c1aaa57d59cbb00ed5c8cfa185d075b105.tar.gz
gcc-43fa41c1aaa57d59cbb00ed5c8cfa185d075b105.tar.bz2
[NDS32] New option -malways-align and -malign-functions.
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
Diffstat (limited to 'gcc/config/nds32')
-rw-r--r--gcc/config/nds32/nds32-md-auxiliary.c20
-rw-r--r--gcc/config/nds32/nds32.c47
-rw-r--r--gcc/config/nds32/nds32.h8
-rw-r--r--gcc/config/nds32/nds32.md38
-rw-r--r--gcc/config/nds32/nds32.opt8
5 files changed, 87 insertions, 34 deletions
diff --git a/gcc/config/nds32/nds32-md-auxiliary.c b/gcc/config/nds32/nds32-md-auxiliary.c
index 95bd829..720e85a 100644
--- a/gcc/config/nds32/nds32-md-auxiliary.c
+++ b/gcc/config/nds32/nds32-md-auxiliary.c
@@ -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
diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c
index 9bd7f3f..76980d3 100644
--- a/gcc/config/nds32/nds32.c
+++ b/gcc/config/nds32/nds32.c
@@ -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. */
diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h
index 13664f1..dc82c0a 100644
--- a/gcc/config/nds32/nds32.h
+++ b/gcc/config/nds32/nds32.h
@@ -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
diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md
index 9e3e20a..dd25e06 100644
--- a/gcc/config/nds32/nds32.md
+++ b/gcc/config/nds32/nds32.md
@@ -1426,16 +1426,29 @@
(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 ();
}
@@ -1477,16 +1490,29 @@
(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 ();
}
diff --git a/gcc/config/nds32/nds32.opt b/gcc/config/nds32/nds32.opt
index bb2bbce..ec6b9d4 100644
--- a/gcc/config/nds32/nds32.opt
+++ b/gcc/config/nds32/nds32.opt
@@ -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.