aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMonk Chiang <sh.chiang04@gmail.com>2018-04-22 07:46:39 +0000
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>2018-04-22 07:46:39 +0000
commitbc8a88100dcbd7ed77b71add5e8f072284a05dd3 (patch)
tree8924a0437b50d343c19639556f3dff02c3cf04fd /gcc
parent020c350c3cd59cb2d24beca1d36d498c52426557 (diff)
downloadgcc-bc8a88100dcbd7ed77b71add5e8f072284a05dd3.zip
gcc-bc8a88100dcbd7ed77b71add5e8f072284a05dd3.tar.gz
gcc-bc8a88100dcbd7ed77b71add5e8f072284a05dd3.tar.bz2
[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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/nds32/constants.md3
-rw-r--r--gcc/config/nds32/nds32-intrinsic.c9
-rw-r--r--gcc/config/nds32/nds32-intrinsic.md91
-rw-r--r--gcc/config/nds32/nds32.c4
-rw-r--r--gcc/config/nds32/nds32.h4
-rw-r--r--gcc/config/nds32/nds32.opt4
-rw-r--r--gcc/config/nds32/nds32_intrinsic.h6
8 files changed, 127 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 63acb1f..09597f4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+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
diff --git a/gcc/config/nds32/constants.md b/gcc/config/nds32/constants.md
index c54cc92..37c2704 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 a835029..b9bb2d9 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 c7b3102..24e7c0b 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 36417cb..1ce9e06 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 8203ab8..9d673d5 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 4968b74..dd9b3d1 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 a299c6a..7bb1177 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 */