From b0df29af882c4d620b5f6e88a55df70741281ad7 Mon Sep 17 00:00:00 2001 From: Martynas Venckus Date: Mon, 10 Dec 2012 18:06:13 +0000 Subject: Fix unaligned memory loads on Alpha. GCC used to generate them in the following manner: ([reg:A & -8] << (64 - (((reg:FP+reg:B) & 0x7) << 3))) >> 56 This fails when we're doing loads with the offset from the frame pointer %8. Since it's aligned, optimizer makes it a zero. The correct expression is: ([reg:A & -8] << (56 - (((reg:FP+reg:B-1) & 0x7) << 3))) >> 56 This is actually a 13-year-old bug. Checked by Miod; a few files in the kernel were affected. Spotted with SSP for Alpha. OK miod@. Tested by naddy@. --- gnu/gcc/gcc/config/alpha/alpha.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/gnu/gcc/gcc/config/alpha/alpha.md b/gnu/gcc/gcc/config/alpha/alpha.md index 17d4c77e69d..9dd70507427 100644 --- a/gnu/gcc/gcc/config/alpha/alpha.md +++ b/gnu/gcc/gcc/config/alpha/alpha.md @@ -1701,9 +1701,10 @@ (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) (set (match_dup 4) (ashift:DI (match_dup 3) - (minus:DI (const_int 64) + (minus:DI (const_int 56) (ashift:DI - (and:DI (match_dup 2) (const_int 7)) + (and:DI (plus:DI (match_dup 2) (const_int -1)) + (const_int 7)) (const_int 3))))) (set (match_operand:DI 0 "register_operand" "") (ashiftrt:DI (match_dup 4) (const_int 56)))] @@ -1751,9 +1752,10 @@ (mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8)))) (set (match_dup 4) (ashift:DI (match_dup 3) - (minus:DI (const_int 64) + (minus:DI (const_int 56) (ashift:DI - (and:DI (match_dup 2) (const_int 7)) + (and:DI (plus:DI (match_dup 2) (const_int -1)) + (const_int 7)) (const_int 3))))) (set (match_operand:DI 0 "register_operand" "") (ashiftrt:DI (match_dup 4) (const_int 48)))] @@ -1866,10 +1868,11 @@ [(set (match_operand:DI 0 "register_operand" "=r") (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (minus:DI (const_int 64) + (minus:DI (const_int 56) (ashift:DI (and:DI - (match_operand:DI 2 "reg_or_8bit_operand" "rI") + (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") + (const_int -1)) (const_int 7)) (const_int 3)))))] "! WORDS_BIG_ENDIAN" @@ -1895,10 +1898,11 @@ (ashift:DI (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") (const_int 2147483647)) - (minus:DI (const_int 64) + (minus:DI (const_int 56) (ashift:DI (and:DI - (match_operand:DI 2 "reg_or_8bit_operand" "rI") + (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") + (const_int -1)) (const_int 7)) (const_int 3)))))] "! WORDS_BIG_ENDIAN" @@ -1927,10 +1931,11 @@ (ashift:DI (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") (const_int 65535)) - (minus:DI (const_int 64) + (minus:DI (const_int 56) (ashift:DI (and:DI - (match_operand:DI 2 "reg_or_8bit_operand" "rI") + (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") + (const_int -1)) (const_int 7)) (const_int 3)))))] "! WORDS_BIG_ENDIAN" -- cgit v1.2.3