+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
{
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)
{
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
{
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);
.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
{
.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
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))
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)
{
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. */
#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) \
#define STACK_BOUNDARY 64
-#define FUNCTION_BOUNDARY 32
+#define FUNCTION_BOUNDARY \
+ ((NDS32_ALIGN_P () || TARGET_ALIGN_FUNCTION) ? 32 : 16)
#define BIGGEST_ALIGNMENT 64
(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 ();
}
; ---------------------------------------------------------------
+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.