Commit 43fa41c1 by Chung-Ju Wu Committed by Chung-Ju Wu

[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
parent 57aaf0cc
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
......
......@@ -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
......
......@@ -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. */
......
......@@ -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
......
......@@ -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 ();
}
......
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment