From bc8a88100dcbd7ed77b71add5e8f072284a05dd3 Mon Sep 17 00:00:00 2001 From: Monk Chiang Date: Sun, 22 Apr 2018 07:46:39 +0000 Subject: [PATCH] [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 From-SVN: r259545 --- gcc/ChangeLog | 14 +++++ gcc/config/nds32/constants.md | 3 + gcc/config/nds32/nds32-intrinsic.c | 9 +++ gcc/config/nds32/nds32-intrinsic.md | 91 ++++++++++++++++++++++++++--- gcc/config/nds32/nds32.c | 4 ++ gcc/config/nds32/nds32.h | 4 ++ gcc/config/nds32/nds32.opt | 4 ++ gcc/config/nds32/nds32_intrinsic.h | 6 ++ 8 files changed, 127 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 63acb1fbc8e8..09597f4fbd9c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2018-04-22 Monk Chiang + Chung-Ju Wu + + * 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 * config/riscv/elf.h (LINK_SPEC): Pass --no-relax if diff --git a/gcc/config/nds32/constants.md b/gcc/config/nds32/constants.md index c54cc92b5e7b..37c27049ef06 100644 --- a/gcc/config/nds32/constants.md +++ b/gcc/config/nds32/constants.md @@ -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 ]) ;; ------------------------------------------------------------------------ diff --git a/gcc/config/nds32/nds32-intrinsic.c b/gcc/config/nds32/nds32-intrinsic.c index a835029fd52c..b9bb2d995f7a 100644 --- a/gcc/config/nds32/nds32-intrinsic.c +++ b/gcc/config/nds32/nds32-intrinsic.c @@ -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); } diff --git a/gcc/config/nds32/nds32-intrinsic.md b/gcc/config/nds32/nds32-intrinsic.md index c7b3102ab59c..24e7c0bf4a12 100644 --- a/gcc/config/nds32/nds32-intrinsic.md +++ b/gcc/config/nds32/nds32-intrinsic.md @@ -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; +}) + ;; ------------------------------------------------------------------------ diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c index 36417cbc543d..1ce9e0678659 100644 --- a/gcc/config/nds32/nds32.c +++ b/gcc/config/nds32/nds32.c @@ -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) diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h index 8203ab82d895..9d673d54e804 100644 --- a/gcc/config/nds32/nds32.h +++ b/gcc/config/nds32/nds32.h @@ -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 }; diff --git a/gcc/config/nds32/nds32.opt b/gcc/config/nds32/nds32.opt index 4968b74ab45d..dd9b3d1b72c1 100644 --- a/gcc/config/nds32/nds32.opt +++ b/gcc/config/nds32/nds32.opt @@ -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. diff --git a/gcc/config/nds32/nds32_intrinsic.h b/gcc/config/nds32/nds32_intrinsic.h index a299c6a1ed7f..7bb117712dc6 100644 --- a/gcc/config/nds32/nds32_intrinsic.h +++ b/gcc/config/nds32/nds32_intrinsic.h @@ -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 */ -- 2.47.2