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.
This commit is contained in:
parent
3d9e676793
commit
30a08286e6
7 changed files with 136 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
;;
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 } {
|
||||
|
|
53
gcc/testsuite/gcc.target/mips/unaligned-2.c
Normal file
53
gcc/testsuite/gcc.target/mips/unaligned-2.c
Normal file
|
@ -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;
|
||||
}
|
53
gcc/testsuite/gcc.target/mips/unaligned-3.c
Normal file
53
gcc/testsuite/gcc.target/mips/unaligned-3.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue