Commit bc8a8810 by Monk Chiang Committed by Chung-Ju Wu

[NDS32] Add unaligned access support.

gcc/
	* config/nds32/constants.md (unspec_volatile_element): Add enum values
	for unaligned access.
	* config/nds32/nds32-intrinsic.c: Implementation of expanding
	unaligned access.
	* config/nds32/nds32-intrinsic.md: Likewise.
	* config/nds32/nds32_intrinsic.h: Likewise.
	* config/nds32/nds32.h (nds32_builtins): Likewise.
	* config/nds32/nds32.opt (munaligned-access): New option.
	* config/nds32/nds32.c (nds32_asm_file_start): Display
	flag_unaligned_access status.

Co-Authored-By: Chung-Ju Wu <jasonwucj@gmail.com>

From-SVN: r259545
parent 020c350c
2018-04-22 Monk Chiang <sh.chiang04@gmail.com>
Chung-Ju Wu <jasonwucj@gmail.com>
* config/nds32/constants.md (unspec_volatile_element): Add enum values
for unaligned access.
* config/nds32/nds32-intrinsic.c: Implementation of expanding
unaligned access.
* config/nds32/nds32-intrinsic.md: Likewise.
* config/nds32/nds32_intrinsic.h: Likewise.
* config/nds32/nds32.h (nds32_builtins): Likewise.
* config/nds32/nds32.opt (munaligned-access): New option.
* config/nds32/nds32.c (nds32_asm_file_start): Display
flag_unaligned_access status.
2018-04-20 Kito Cheng <kito.cheng@gmail.com>
* config/riscv/elf.h (LINK_SPEC): Pass --no-relax if
......
......@@ -136,6 +136,9 @@
UNSPEC_VOLATILE_GET_TRIG_TYPE
UNSPEC_VOLATILE_RELAX_GROUP
UNSPEC_VOLATILE_POP25_RETURN
UNSPEC_VOLATILE_UNALIGNED_FEATURE
UNSPEC_VOLATILE_ENABLE_UNALIGNED
UNSPEC_VOLATILE_DISABLE_UNALIGNED
])
;; ------------------------------------------------------------------------
......@@ -523,6 +523,12 @@ static struct builtin_description bdesc_noarg[] =
NDS32_BUILTIN(unspec_return_address, "return_address", RETURN_ADDRESS)
NDS32_BUILTIN(unspec_get_all_pending_int, "get_all_pending_int",
GET_ALL_PENDING_INT)
NDS32_BUILTIN(unspec_unaligned_feature, "unaligned_feature",
UNALIGNED_FEATURE)
NDS32_NO_TARGET_BUILTIN(unspec_enable_unaligned, "enable_unaligned",
ENABLE_UNALIGNED)
NDS32_NO_TARGET_BUILTIN(unspec_disable_unaligned, "disable_unaligned",
DISABLE_UNALIGNED)
};
/* Intrinsics that take just one argument. */
......@@ -1099,5 +1105,8 @@ nds32_init_builtins_impl (void)
ADD_NDS32_BUILTIN2 ("unaligned_store_w", void, ptr_uint, unsigned, UASTORE_W);
ADD_NDS32_BUILTIN2 ("unaligned_store_dw", void, ptr_ulong, long_long_unsigned,
UASTORE_DW);
ADD_NDS32_BUILTIN0 ("unaligned_feature", unsigned, UNALIGNED_FEATURE);
ADD_NDS32_BUILTIN0 ("enable_unaligned", void, ENABLE_UNALIGNED);
ADD_NDS32_BUILTIN0 ("disable_unaligned", void, DISABLE_UNALIGNED);
}
......@@ -1306,11 +1306,19 @@
(unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "r"))] UNSPEC_UALOAD_W))]
""
{
if (TARGET_ISA_V3M)
nds32_expand_unaligned_load (operands, SImode);
if (flag_unaligned_access)
{
rtx mem = gen_rtx_MEM (SImode, operands[1]);
emit_move_insn (operands[0], mem);
}
else
emit_insn (gen_unaligned_load_w (operands[0],
gen_rtx_MEM (SImode, (operands[1]))));
{
if (TARGET_ISA_V3M)
nds32_expand_unaligned_load (operands, SImode);
else
emit_insn (gen_unaligned_load_w (operands[0],
gen_rtx_MEM (SImode, (operands[1]))));
}
DONE;
})
......@@ -1372,11 +1380,19 @@
(unspec:SI [(match_operand:SI 1 "register_operand" "r")] UNSPEC_UASTORE_W))]
""
{
if (TARGET_ISA_V3M)
nds32_expand_unaligned_store (operands, SImode);
if (flag_unaligned_access)
{
rtx mem = gen_rtx_MEM (SImode, operands[0]);
emit_move_insn (mem, operands[1]);
}
else
emit_insn (gen_unaligned_store_w (gen_rtx_MEM (SImode, operands[0]),
operands[1]));
{
if (TARGET_ISA_V3M)
nds32_expand_unaligned_store (operands, SImode);
else
emit_insn (gen_unaligned_store_w (gen_rtx_MEM (SImode, operands[0]),
operands[1]));
}
DONE;
})
......@@ -1420,4 +1436,63 @@
(set_attr "length" "4")]
)
(define_expand "unspec_unaligned_feature"
[(set (match_operand:SI 0 "register_operand" "")
(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE))]
""
{
/* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */
rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__);
rtx temp_reg = gen_reg_rtx (SImode);
rtx temp2_reg = gen_reg_rtx (SImode);
emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
emit_move_insn (temp_reg, operands[0]);
emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
emit_insn (gen_iorsi3 (operands[0], operands[0], temp2_reg));
emit_insn (gen_unspec_volatile_mtsr (operands[0], system_reg));
emit_insn (gen_unspec_dsb ());
emit_insn (gen_unspec_volatile_mfsr (operands[0], system_reg));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
emit_insn (gen_ashlsi3 (operands[0], operands[0], GEN_INT (8)));
emit_insn (gen_lshrsi3 (operands[0], operands[0], GEN_INT (31)));
DONE;
})
(define_expand "unspec_enable_unaligned"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
""
{
/* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */
rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__);
rtx temp_reg = gen_reg_rtx (SImode);
rtx temp2_reg = gen_reg_rtx (SImode);
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
emit_insn (gen_iorsi3 (temp_reg, temp_reg, temp2_reg));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
DONE;
})
(define_expand "unspec_disable_unaligned"
[(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_UNALIGNED_FEATURE)]
""
{
/* Get $MMU_CTL system register form nds32_intrinsic_register_names[] */
rtx system_reg = GEN_INT (__NDS32_REG_MMU_CTL__);
rtx temp_reg = gen_reg_rtx (SImode);
rtx temp2_reg = gen_reg_rtx (SImode);
emit_insn (gen_unspec_volatile_mfsr (temp_reg, system_reg));
emit_move_insn (temp2_reg, GEN_INT (0x800 << 12));
emit_insn (gen_one_cmplsi2 (temp2_reg, temp2_reg));
emit_insn (gen_andsi3 (temp_reg, temp_reg, temp2_reg));
emit_insn (gen_unspec_volatile_mtsr (temp_reg, system_reg));
emit_insn (gen_unspec_dsb ());
DONE;
})
;; ------------------------------------------------------------------------
......@@ -2885,6 +2885,10 @@ nds32_asm_file_start (void)
((TARGET_REDUCED_REGS) ? "Yes"
: "No"));
fprintf (asm_out_file, "\t! Support unaligned access\t\t: %s\n",
(flag_unaligned_access ? "Yes"
: "No"));
fprintf (asm_out_file, "\t! ------------------------------------\n");
if (optimize_size)
......
......@@ -512,6 +512,10 @@ enum nds32_builtins
NDS32_BUILTIN_SET_TRIG_LEVEL,
NDS32_BUILTIN_SET_TRIG_EDGE,
NDS32_BUILTIN_GET_TRIG_TYPE,
NDS32_BUILTIN_UNALIGNED_FEATURE,
NDS32_BUILTIN_ENABLE_UNALIGNED,
NDS32_BUILTIN_DISABLE_UNALIGNED,
NDS32_BUILTIN_COUNT
};
......
......@@ -320,3 +320,7 @@ Generate single-precision floating-point instructions.
mext-fpu-dp
Target Report Mask(FPU_DOUBLE)
Generate double-precision floating-point instructions.
munaligned-access
Target Report Var(flag_unaligned_access) Init(0)
Enable unaligned word and halfword accesses to packed data.
......@@ -720,4 +720,10 @@ enum nds32_dpref
#define __nds32__get_trig_type(a) \
(__builtin_nds32_get_trig_type ((a)))
#define __nds32__unaligned_feature() \
(__builtin_nds32_unaligned_feature())
#define __nds32__enable_unaligned() \
(__builtin_nds32_enable_unaligned())
#define __nds32__disable_unaligned() \
(__builtin_nds32_disable_unaligned())
#endif /* nds32_intrinsic.h */
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