summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartynas Venckus <martynas@cvs.openbsd.org>2012-12-10 18:06:13 +0000
committerMartynas Venckus <martynas@cvs.openbsd.org>2012-12-10 18:06:13 +0000
commitb0df29af882c4d620b5f6e88a55df70741281ad7 (patch)
treed0c12eb6a7c4a80fa0316cadf39c44c8a49852d1
parent8a035085bc3ae8fafd05f43d62117d440347efe8 (diff)
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@.
-rw-r--r--gnu/gcc/gcc/config/alpha/alpha.md25
1 files 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"