Old buggy hardware incorrectly executes the shift-left-K
then shift-right-K idiom for clearing K leftmost bits.
Use a right rotate instead of shift to avoid triggering the
bug.
Fixes #19809.
Change-Id: I6dc646b183c29e9d01aef944729f34388dcc687d
Reviewed-on: https://go-review.googlesource.com/39310
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
( ORshiftRL <t> [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 -> (RORWconst [ c] x)
(XORshiftRL <t> [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 -> (RORWconst [ c] x)
+// Replace SRL-of-SLL with ROR-of-SLL to avoid hardware bug.
+(SRLconst [c] y:(SLLconst [c] _)) && c <= 8 -> (RORconst [c] y)
+
// do combined loads
// little endian loads
// b[0] | b[1]<<8 -> load 16-bit
v.AuxInt = int64(uint64(d) >> uint64(c))
return true
}
+ // match: (SRLconst [c] y:(SLLconst [c] _))
+ // cond: c <= 8
+ // result: (RORconst [c] y)
+ for {
+ c := v.AuxInt
+ y := v.Args[0]
+ if y.Op != OpARM64SLLconst {
+ break
+ }
+ if y.AuxInt != c {
+ break
+ }
+ if !(c <= 8) {
+ break
+ }
+ v.reset(OpARM64RORconst)
+ v.AuxInt = c
+ v.AddArg(y)
+ return true
+ }
return false
}
func rewriteValueARM64_OpARM64SUB(v *Value) bool {