]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[NDS32] Add unaligned access support.
authorMonk Chiang <sh.chiang04@gmail.com>
Sun, 22 Apr 2018 07:46:39 +0000 (07:46 +0000)
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>
Sun, 22 Apr 2018 07:46:39 +0000 (07:46 +0000)
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

gcc/ChangeLog
gcc/config/nds32/constants.md
gcc/config/nds32/nds32-intrinsic.c
gcc/config/nds32/nds32-intrinsic.md
gcc/config/nds32/nds32.c
gcc/config/nds32/nds32.h
gcc/config/nds32/nds32.opt
gcc/config/nds32/nds32_intrinsic.h

index 63acb1fbc8e83abef13cd808c1db69605548458c..09597f4fbd9ce56b3a39ee74f3782545a55f0846 100644 (file)
@@ -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
index c54cc92b5e7bfff07e232134c70e17f7f3bf12d2..37c27049ef069915d3f723ad03d34757106bfb5a 100644 (file)
   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
 ])
 
 ;; ------------------------------------------------------------------------
index a835029fd52c0d29068b383c2eae8cf8ca6ea3fb..b9bb2d995f7a8ddf445cc3075d3f1eec287de8b8 100644 (file)
@@ -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);
 
 }
index c7b3102ab59cc0357cadc492530cbac006d2557f..24e7c0bf4a12207dff18a5402e90ed67d7ebb7b8 100644 (file)
        (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;
 })
 
        (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;
 })
 
    (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;
+})
+
 ;; ------------------------------------------------------------------------
index 36417cbc543d6bda3086ebe45e9bcaf009fb874f..1ce9e06786591521656751f3a944c3025c08b1de 100644 (file)
@@ -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)
index 8203ab82d895a357eb3dd654f53ff2830cc07934..9d673d54e804359eeb0849d760739eb5ad494269 100644 (file)
@@ -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
 };
 
index 4968b74ab45d1c3a998ae1ec25e3c9de939cf08a..dd9b3d1b72c15a229d84b6f257ce4acbe2bf09af 100644 (file)
@@ -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.
index a299c6a1ed7ffc891705c83c51721074af54f011..7bb117712dc6b33ce0b96f411d5fa45842bf0a13 100644 (file)
@@ -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 */