[v3] MIPS: R6: load/store can process unaligned address

Message ID 20211011104239.407933-1-yunqiang.su@cipunited.com
State Committed
Commit 30a08286e67e3aee17347f8d02e8f868a995beb9
Headers
Series [v3] MIPS: R6: load/store can process unaligned address |

Commit Message

YunQiang Su Oct. 11, 2021, 10:42 a.m. UTC
  MIPS release 6 requires the lw/ld/sw/sd can work with
unaligned address, while it can be implemented by
full hardware or trap&emulate.

Since it doesn't have to be fully done by hardware, we add a
pair of options -m(no-)unaligned-access. Kernels may need them.

gcc/ChangeLog:

	* config/mips/mips.h (ISA_HAS_UNALIGNED_ACCESS):
	(STRICT_ALIGNMENT): R6 can unaligned access.
	* config/mips/mips.md (movmisalign<mode>): Likewise.
	* config/mips/mips.opt: add -m(no-)unaligned-access
	* doc/invoke.texi: Likewise.

gcc/testsuite/ChangeLog:

	* gcc.target/mips/mips.exp: add unaligned-access
	* gcc.target/mips/unaligned-2.c: New test.
	* gcc.target/mips/unaligned-3.c: New test.
---
 gcc/config/mips/mips.h                      |  6 ++-
 gcc/config/mips/mips.md                     | 10 ++++
 gcc/config/mips/mips.opt                    |  4 ++
 gcc/doc/invoke.texi                         | 10 ++++
 gcc/testsuite/gcc.target/mips/mips.exp      |  1 +
 gcc/testsuite/gcc.target/mips/unaligned-2.c | 53 +++++++++++++++++++++
 gcc/testsuite/gcc.target/mips/unaligned-3.c | 53 +++++++++++++++++++++
 7 files changed, 136 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/unaligned-2.c
 create mode 100644 gcc/testsuite/gcc.target/mips/unaligned-3.c
  

Comments

Jeff Law Dec. 3, 2021, 2:44 a.m. UTC | #1
On 10/11/2021 4:42 AM, YunQiang Su wrote:
> MIPS release 6 requires the lw/ld/sw/sd can work with
> unaligned address, while it can be implemented by
> full hardware or trap&emulate.
>
> Since it doesn't have to be fully done by hardware, we add a
> pair of options -m(no-)unaligned-access. Kernels may need them.
>
> gcc/ChangeLog:
>
> 	* config/mips/mips.h (ISA_HAS_UNALIGNED_ACCESS):
> 	(STRICT_ALIGNMENT): R6 can unaligned access.
> 	* config/mips/mips.md (movmisalign<mode>): Likewise.
> 	* config/mips/mips.opt: add -m(no-)unaligned-access
> 	* doc/invoke.texi: Likewise.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/mips/mips.exp: add unaligned-access
> 	* gcc.target/mips/unaligned-2.c: New test.
> 	* gcc.target/mips/unaligned-3.c: New test.
This is OK.  Sorry for the long delay.

jeff
  

Patch

diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 973372e78..34490bfc2 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -243,6 +243,10 @@  struct mips_cpu_info {
 				 && (mips_isa_rev >= 6 \
 				     || ISA_HAS_MSA))
 
+/* ISA load/store instructions can handle unaligned address */
+#define ISA_HAS_UNALIGNED_ACCESS (TARGET_UNALIGNED_ACCESS \
+				 && (mips_isa_rev >= 6))
+
 /* The ISA compression flags that are currently in effect.  */
 #define TARGET_COMPRESSION (target_flags & (MASK_MIPS16 | MASK_MICROMIPS))
 
@@ -1684,7 +1688,7 @@  FP_ASM_SPEC "\
   (ISA_HAS_MSA ? BITS_PER_MSA_REG : LONG_DOUBLE_TYPE_SIZE)
 
 /* All accesses must be aligned.  */
-#define STRICT_ALIGNMENT 1
+#define STRICT_ALIGNMENT (!ISA_HAS_UNALIGNED_ACCESS)
 
 /* Define this if you wish to imitate the way many other C compilers
    handle alignment of bitfields and the structures that contain
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 455b9b802..e35d57d9e 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -4459,6 +4459,16 @@  (define_insn "mov_<store>r"
   [(set_attr "move_type" "store")
    (set_attr "mode" "<MODE>")])
 
+;; Unaligned direct access
+(define_expand "movmisalign<mode>"
+  [(set (match_operand:JOIN_MODE 0)
+	(match_operand:JOIN_MODE 1))]
+  "ISA_HAS_UNALIGNED_ACCESS"
+{
+  if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
+    DONE;
+})
+
 ;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE.
 ;; The required value is:
 ;;
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index 6af8037e9..ebb4c6164 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -404,6 +404,10 @@  mtune=
 Target RejectNegative Joined Var(mips_tune_option) ToLower Enum(mips_arch_opt_value)
 -mtune=PROCESSOR	Optimize the output for PROCESSOR.
 
+munaligned-access
+Target Var(TARGET_UNALIGNED_ACCESS) Init(1)
+Generate code with unaligned load store, valid for MIPS R6.
+
 muninit-const-in-rodata
 Target Var(TARGET_UNINIT_CONST_IN_RODATA)
 Put uninitialized constants in ROM (needs -membedded-data).
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8b3ebcfbc..ffb1f4676 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1069,6 +1069,7 @@  Objective-C and Objective-C++ Dialects}.
 -mcheck-zero-division  -mno-check-zero-division @gol
 -mdivide-traps  -mdivide-breaks @gol
 -mload-store-pairs  -mno-load-store-pairs @gol
+-munaligned-access  -mno-unaligned-access @gol
 -mmemcpy  -mno-memcpy  -mlong-calls  -mno-long-calls @gol
 -mmad  -mno-mad  -mimadd  -mno-imadd  -mfused-madd  -mno-fused-madd  -nocpp @gol
 -mfix-24k  -mno-fix-24k @gol
@@ -25503,6 +25504,15 @@  instructions to enable load/store bonding.  This option is enabled by
 default but only takes effect when the selected architecture is known
 to support bonding.
 
+@item -munaligned-access
+@itemx -mno-unaligned-access
+@opindex munaligned-access
+@opindex mno-unaligned-access
+Enable (disable) direct unaligned access for MIPS Release 6.
+MIPSr6 requires load/store unaligned-access support,
+by hardware or trap&emulate.
+So @option{-mno-unaligned-access} may be needed by kernel.
+
 @item -mmemcpy
 @itemx -mno-memcpy
 @opindex mmemcpy
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index d4d4b90d8..f76ab7adc 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -264,6 +264,7 @@  set mips_option_groups {
     frame-header "-mframe-header-opt|-mno-frame-header-opt"
     stack-protector "-fstack-protector"
     stdlib "REQUIRES_STDLIB"
+    unaligned-access "-m(no-|)unaligned-access"
 }
 
 for { set option 0 } { $option < 32 } { incr option } {
diff --git a/gcc/testsuite/gcc.target/mips/unaligned-2.c b/gcc/testsuite/gcc.target/mips/unaligned-2.c
new file mode 100644
index 000000000..8679afac4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/unaligned-2.c
@@ -0,0 +1,53 @@ 
+/* { dg-options "isa_rev>=6 -mgp64" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-final { scan-assembler-not "\tsb\t" } } */
+/* { dg-final { scan-assembler-not "\tsh\t" } } */
+/* { dg-final { scan-assembler-not "\tlb\t" } } */
+/* { dg-final { scan-assembler-not "\tlh\t" } } */
+/* { dg-final { scan-assembler-not "\tswl\t" } } */
+/* { dg-final { scan-assembler-not "\tswr\t" } } */
+/* { dg-final { scan-assembler-not "\tlwl\t" } } */
+/* { dg-final { scan-assembler-not "\tlwr\t" } } */
+/* { dg-final { scan-assembler-not "\tsdl\t" } } */
+/* { dg-final { scan-assembler-not "\tsdr\t" } } */
+/* { dg-final { scan-assembler-not "\tldl\t" } } */
+/* { dg-final { scan-assembler-not "\tldr\t" } } */
+/* { dg-final { scan-assembler-times "\tsw\t" 1 } } */
+/* { dg-final { scan-assembler-times "\tlw\t" 1 } } */
+/* { dg-final { scan-assembler-times "\tsd\t" 1 } } */
+/* { dg-final { scan-assembler-times "\tld\t" 1 } } */
+/* { dg-final { scan-assembler-not "\tnop" } } */
+
+/* Test to make sure we produce the unaligned load/store for
+   both 64bit and 32bits sized accesses.  */
+
+struct s
+{
+  char c;
+  int i;
+  long long l;
+} __attribute__ ((packed)) s __attribute__((aligned(1) ));
+
+NOMIPS16 void
+sd (long long l)
+{
+  s.l = l;
+}
+
+NOMIPS16 long long
+ld ()
+{
+  return s.l;
+}
+
+NOMIPS16 void
+sw (int i)
+{
+  s.i = i;
+}
+
+NOMIPS16 int
+lw ()
+{
+  return s.i;
+}
diff --git a/gcc/testsuite/gcc.target/mips/unaligned-3.c b/gcc/testsuite/gcc.target/mips/unaligned-3.c
new file mode 100644
index 000000000..d0fbe19de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/unaligned-3.c
@@ -0,0 +1,53 @@ 
+/* { dg-options "isa_rev>=6 -mgp64 -mno-unaligned-access" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-final { scan-assembler-times "\tsb\t" 12 } } */
+/* { dg-final { scan-assembler-times "\tlbu\t" 12 } } */
+/* { dg-final { scan-assembler-not "\tsh\t" } } */
+/* { dg-final { scan-assembler-not "\tlh\t" } } */
+/* { dg-final { scan-assembler-not "\tsw\t" } } */
+/* { dg-final { scan-assembler-not "\tlw\t" } } */
+/* { dg-final { scan-assembler-not "\tsd\t" } } */
+/* { dg-final { scan-assembler-not "\tld\t" } } */
+/* { dg-final { scan-assembler-not "\tswl\t" } } */
+/* { dg-final { scan-assembler-not "\tswr\t" } } */
+/* { dg-final { scan-assembler-not "\tlwl\t" } } */
+/* { dg-final { scan-assembler-not "\tlwr\t" } } */
+/* { dg-final { scan-assembler-not "\tsdl\t" } } */
+/* { dg-final { scan-assembler-not "\tsdr\t" } } */
+/* { dg-final { scan-assembler-not "\tldl\t" } } */
+/* { dg-final { scan-assembler-not "\tldr\t" } } */
+/* { dg-final { scan-assembler-not "\tnop" } } */
+
+/* Test to make sure we produce the unaligned load/store for
+   both 64bit and 32bits sized accesses.  */
+
+struct s
+{
+  char c;
+  int i;
+  long long l;
+} __attribute__ ((packed)) s __attribute__((aligned(1) ));
+
+NOMIPS16 void
+sd (long long l)
+{
+  s.l = l;
+}
+
+NOMIPS16 long long
+ld ()
+{
+  return s.l;
+}
+
+NOMIPS16 void
+sw (int i)
+{
+  s.i = i;
+}
+
+NOMIPS16 int
+lw ()
+{
+  return s.i;
+}