diff options
author | Andrew Pinski <apinski@cavium.com> | 2012-07-21 10:38:20 +0000 |
---|---|---|
committer | Andrew Pinski <pinskia@gcc.gnu.org> | 2012-07-21 03:38:20 -0700 |
commit | aea21190650881b9b17580a55f61393eb78f33a4 (patch) | |
tree | 82994461bf1705ad28d5bc60086f1c77591e01f6 | |
parent | 6220bf437fdafee2250024aacff0a37e33ebd96b (diff) | |
download | gcc-aea21190650881b9b17580a55f61393eb78f33a4.zip gcc-aea21190650881b9b17580a55f61393eb78f33a4.tar.gz gcc-aea21190650881b9b17580a55f61393eb78f33a4.tar.bz2 |
mips-protos.h (mips_expand_ext_as_unaligned_load): Add a bool argument.
2012-07-21 Andrew Pinski <apinski@cavium.com>
* config/mips/mips-protos.h (mips_expand_ext_as_unaligned_load):
Add a bool argument.
* config/mips/mips.c (mips_block_move_straight): Update call to
mips_expand_ext_as_unaligned_load.
(mips_expand_ext_as_unaligned_load): Add unsigned_p argument.
Accept DImode dest when the width is that of SImode.
* config/mips/mips.md (extv): Update call to
mips_expand_ext_as_unaligned_load.
(extzv): Likewise.
2012-07-21 Andrew Pinski <apinski@cavium.com>
* gcc.target/mips/unaligned-1.c: New testcase.
From-SVN: r189742
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/mips/mips-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 25 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/unaligned-1.c | 44 |
6 files changed, 88 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fec3d36..4027766 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ 2012-07-21 Andrew Pinski <apinski@cavium.com> + * config/mips/mips-protos.h (mips_expand_ext_as_unaligned_load): + Add a bool argument. + * config/mips/mips.c (mips_block_move_straight): Update call to + mips_expand_ext_as_unaligned_load. + (mips_expand_ext_as_unaligned_load): Add unsigned_p argument. + Accept DImode dest when the width is that of SImode. + * config/mips/mips.md (extv): Update call to + mips_expand_ext_as_unaligned_load. + (extzv): Likewise. + +2012-07-21 Andrew Pinski <apinski@cavium.com> + * config/mips/mips.c (mips_get_unaligned_mem): Copy *op after calling adjust_address. diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index d1fa160..cba76b6 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -241,7 +241,7 @@ extern bool mips_pad_arg_upward (enum machine_mode, const_tree); extern bool mips_pad_reg_upward (enum machine_mode, tree); extern bool mips_expand_ext_as_unaligned_load (rtx, rtx, HOST_WIDE_INT, - HOST_WIDE_INT); + HOST_WIDE_INT, bool); extern bool mips_expand_ins_as_unaligned_store (rtx, rtx, HOST_WIDE_INT, HOST_WIDE_INT); extern bool mips_mem_fits_mode_p (enum machine_mode mode, rtx x); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 498dc27..e4e93e6 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -6916,7 +6916,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length) else { rtx part = adjust_address (src, BLKmode, offset); - if (!mips_expand_ext_as_unaligned_load (regs[i], part, bits, 0)) + if (!mips_expand_ext_as_unaligned_load (regs[i], part, bits, 0, 0)) gcc_unreachable (); } } @@ -7249,9 +7249,10 @@ mips_get_unaligned_mem (rtx *op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos, bool mips_expand_ext_as_unaligned_load (rtx dest, rtx src, HOST_WIDE_INT width, - HOST_WIDE_INT bitpos) + HOST_WIDE_INT bitpos, bool unsigned_p) { rtx left, right, temp; + rtx dest1 = NULL_RTX; /* If TARGET_64BIT, the destination of a 32-bit "extz" or "extzv" will be a paradoxical word_mode subreg. This is the only case in which @@ -7261,6 +7262,16 @@ mips_expand_ext_as_unaligned_load (rtx dest, rtx src, HOST_WIDE_INT width, && GET_MODE (SUBREG_REG (dest)) == SImode) dest = SUBREG_REG (dest); + /* If TARGET_64BIT, the destination of a 32-bit "extz" or "extzv" will + be a DImode, create a new temp and emit a zero extend at the end. */ + if (GET_MODE (dest) == DImode + && REG_P (dest) + && GET_MODE_BITSIZE (SImode) == width) + { + dest1 = dest; + dest = gen_reg_rtx (SImode); + } + /* After the above adjustment, the destination must be the same width as the source. */ if (GET_MODE_BITSIZE (GET_MODE (dest)) != width) @@ -7280,6 +7291,16 @@ mips_expand_ext_as_unaligned_load (rtx dest, rtx src, HOST_WIDE_INT width, emit_insn (gen_mov_lwl (temp, src, left)); emit_insn (gen_mov_lwr (dest, copy_rtx (src), right, temp)); } + + /* If we were loading 32bits and the original register was DI then + sign/zero extend into the orignal dest. */ + if (dest1) + { + if (unsigned_p) + emit_insn (gen_zero_extendsidi2 (dest1, dest)); + else + emit_insn (gen_extendsidi2 (dest1, dest)); + } return true; } diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index b6b2beb..0edc9d9 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -3657,7 +3657,8 @@ { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], INTVAL (operands[2]), - INTVAL (operands[3]))) + INTVAL (operands[3]), + /*unsigned=*/ false)) DONE; else if (register_operand (operands[1], GET_MODE (operands[0])) && ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32) @@ -3694,7 +3695,8 @@ { if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], INTVAL (operands[2]), - INTVAL (operands[3]))) + INTVAL (operands[3]), + /*unsigned=*/true)) DONE; else if (mips_use_ins_ext_p (operands[1], INTVAL (operands[2]), INTVAL (operands[3]))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9450484..25ca135 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-07-21 Andrew Pinski <apinski@cavium.com> + + * gcc.target/mips/unaligned-1.c: New testcase. + 2012-07-21 Hans-Peter Nilsson <hp@axis.com> * gcc.c-torture/execute/20101011-1.c (DO_TEST): Define as 0 for CRIS. diff --git a/gcc/testsuite/gcc.target/mips/unaligned-1.c b/gcc/testsuite/gcc.target/mips/unaligned-1.c new file mode 100644 index 0000000..23b6c8c --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/unaligned-1.c @@ -0,0 +1,44 @@ +/* { dg-options "-O2 -mgp64" } */ +/* { dg-final { scan-assembler-times "sdl\t" 1 } } */ +/* { dg-final { scan-assembler-times "sdr\t" 1 } } */ +/* { dg-final { scan-assembler-times "ldl\t" 1 } } */ +/* { dg-final { scan-assembler-times "ldr\t" 1 } } */ +/* { dg-final { scan-assembler-times "swl\t" 1 } } */ +/* { dg-final { scan-assembler-times "swr\t" 1 } } */ +/* { dg-final { scan-assembler-times "lwl\t" 1 } } */ +/* { dg-final { scan-assembler-times "lwr\t" 1 } } */ +/* { dg-final { scan-assembler-not "nop" } } */ + +/* 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) )); + +void +sd (long long l) +{ + s.l = l; +} + +long long +ld () +{ + return s.l; +} + +void +sw (int i) +{ + s.i = i; +} + +int +lw () +{ + return s.i; +} |