Skip to content

Commit 8aaa948

Browse files
author
Richard Earnshaw
committed
arm: big-endian issue in gen_cpymem_ldrd_strd [PR105981]
The code in gen_cpymem_ldrd_strd has been incorrect for big-endian since r230663. The problem is that we use gen_lowpart, etc. to split the 64-bit quantity, but fail to account for the fact that these routines are really dealing with 64-bit /values/ and in big-endian the ordering of the sub-registers changes. To fix this, I've renamed the conceptually misnamed low_reg and hi_reg as first_reg and second_reg, and then used different logic for big-endian targets to initialize these values. This makes the logic clearer than trying to think about high bits and low bits. gcc/ChangeLog: PR target/105981 * config/arm/arm.cc (gen_cpymem_ldrd_strd): Rename low_reg and hi_reg to first_reg and second_reg respectively. Initialize them correctly when generating big-endian code.
1 parent 052d895 commit 8aaa948

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

gcc/config/arm/arm.cc

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15744,23 +15744,31 @@ gen_cpymem_ldrd_strd (rtx *operands)
1574415744
{
1574515745
len -= 8;
1574615746
reg0 = gen_reg_rtx (DImode);
15747-
rtx low_reg = NULL_RTX;
15748-
rtx hi_reg = NULL_RTX;
15747+
rtx first_reg = NULL_RTX;
15748+
rtx second_reg = NULL_RTX;
1574915749

1575015750
if (!src_aligned || !dst_aligned)
1575115751
{
15752-
low_reg = gen_lowpart (SImode, reg0);
15753-
hi_reg = gen_highpart_mode (SImode, DImode, reg0);
15752+
if (BYTES_BIG_ENDIAN)
15753+
{
15754+
second_reg = gen_lowpart (SImode, reg0);
15755+
first_reg = gen_highpart_mode (SImode, DImode, reg0);
15756+
}
15757+
else
15758+
{
15759+
first_reg = gen_lowpart (SImode, reg0);
15760+
second_reg = gen_highpart_mode (SImode, DImode, reg0);
15761+
}
1575415762
}
1575515763
if (MEM_ALIGN (src) >= 2 * BITS_PER_WORD)
1575615764
emit_move_insn (reg0, src);
1575715765
else if (src_aligned)
1575815766
emit_insn (gen_unaligned_loaddi (reg0, src));
1575915767
else
1576015768
{
15761-
emit_insn (gen_unaligned_loadsi (low_reg, src));
15769+
emit_insn (gen_unaligned_loadsi (first_reg, src));
1576215770
src = next_consecutive_mem (src);
15763-
emit_insn (gen_unaligned_loadsi (hi_reg, src));
15771+
emit_insn (gen_unaligned_loadsi (second_reg, src));
1576415772
}
1576515773

1576615774
if (MEM_ALIGN (dst) >= 2 * BITS_PER_WORD)
@@ -15769,9 +15777,9 @@ gen_cpymem_ldrd_strd (rtx *operands)
1576915777
emit_insn (gen_unaligned_storedi (dst, reg0));
1577015778
else
1577115779
{
15772-
emit_insn (gen_unaligned_storesi (dst, low_reg));
15780+
emit_insn (gen_unaligned_storesi (dst, first_reg));
1577315781
dst = next_consecutive_mem (dst);
15774-
emit_insn (gen_unaligned_storesi (dst, hi_reg));
15782+
emit_insn (gen_unaligned_storesi (dst, second_reg));
1577515783
}
1577615784

1577715785
src = next_consecutive_mem (src);

0 commit comments

Comments
 (0)