diff options
author | YunQiang Su <yunqiang.su@cipunited.com> | 2021-10-11 06:42:39 -0400 |
---|---|---|
committer | YunQiang Su <syq@debian.org> | 2021-12-07 10:01:23 +0800 |
commit | 30a08286e67e3aee17347f8d02e8f868a995beb9 (patch) | |
tree | 3f72d4fda38abcffce68860861bfaa6040892f36 | |
parent | 3d9e6767939e9658260e2506e81ec32b37cba041 (diff) | |
download | gcc-30a08286e67e3aee17347f8d02e8f868a995beb9.zip gcc-30a08286e67e3aee17347f8d02e8f868a995beb9.tar.gz gcc-30a08286e67e3aee17347f8d02e8f868a995beb9.tar.bz2 |
MIPS: R6: load/store can process unaligned address
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.
-rw-r--r-- | gcc/config/mips/mips.h | 6 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 10 | ||||
-rw-r--r-- | gcc/config/mips/mips.opt | 4 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/mips.exp | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/unaligned-2.c | 53 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/unaligned-3.c | 53 |
7 files changed, 136 insertions, 1 deletions
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 973372e..34490bf 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 455b9b8..e35d57d 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -4459,6 +4459,16 @@ [(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 6af8037..ebb4c61 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 510ed07..8a70ada 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1079,6 +1079,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 @@ -25731,6 +25732,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 d4d4b90..f76ab7a 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 0000000..8679afa --- /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 0000000..d0fbe19 --- /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; +} |