}
var linuxAMD64Tests = []*asmTest{
+ // multiplication by powers of two
{
fn: `
- func f0(x int) int {
- return x * 64
+ func $(n int) int {
+ return n * 64
}
`,
pos: []string{"\tSHLQ\t\\$6,"},
+ neg: []string{"IMULQ"},
},
{
fn: `
- func f1(x int) int {
+ func $(n int) int {
+ return -128*n
+ }
+ `,
+ pos: []string{"SHLQ"},
+ neg: []string{"IMULQ"},
+ },
+
+ {
+ fn: `
+ func $(x int) int {
return x * 96
}
`,
pos: []string{"\tMOVL\t\\(.*\\)\\(.*\\*1\\),"},
},
+ // multiplication by powers of two
+ {
+ fn: `
+ func $(n int) int {
+ return 32*n
+ }
+ `,
+ pos: []string{"SHLL"},
+ neg: []string{"IMULL"},
+ },
+ {
+ fn: `
+ func $(n int) int {
+ return -64*n
+ }
+ `,
+ pos: []string{"SHLL"},
+ neg: []string{"IMULL"},
+ },
+
// multiplication merging tests
{
fn: `
(MULLconst [41] x) -> (LEAL8 x (LEAL4 <v.Type> x x))
(MULLconst [73] x) -> (LEAL8 x (LEAL8 <v.Type> x x))
-(MULLconst [c] x) && isPowerOfTwo(c) -> (SHLLconst [log2(c)] x)
(MULLconst [c] x) && isPowerOfTwo(c+1) && c >= 15 -> (SUBL (SHLLconst <v.Type> [log2(c+1)] x) x)
(MULLconst [c] x) && isPowerOfTwo(c-1) && c >= 17 -> (LEAL1 (SHLLconst <v.Type> [log2(c-1)] x) x)
(MULLconst [c] x) && isPowerOfTwo(c-2) && c >= 34 -> (LEAL2 (SHLLconst <v.Type> [log2(c-2)] x) x)
(MULQconst [41] x) -> (LEAQ8 x (LEAQ4 <v.Type> x x))
(MULQconst [73] x) -> (LEAQ8 x (LEAQ8 <v.Type> x x))
-(MULQconst [c] x) && isPowerOfTwo(c) -> (SHLQconst [log2(c)] x)
(MULQconst [c] x) && isPowerOfTwo(c+1) && c >= 15 -> (SUBQ (SHLQconst <v.Type> [log2(c+1)] x) x)
(MULQconst [c] x) && isPowerOfTwo(c-1) && c >= 17 -> (LEAQ1 (SHLQconst <v.Type> [log2(c-1)] x) x)
(MULQconst [c] x) && isPowerOfTwo(c-2) && c >= 34 -> (LEAQ2 (SHLQconst <v.Type> [log2(c-2)] x) x)
return true
}
// match: (MULLconst [c] x)
- // cond: isPowerOfTwo(c)
- // result: (SHLLconst [log2(c)] x)
- for {
- c := v.AuxInt
- x := v.Args[0]
- if !(isPowerOfTwo(c)) {
- break
- }
- v.reset(Op386SHLLconst)
- v.AuxInt = log2(c)
- v.AddArg(x)
- return true
- }
- // match: (MULLconst [c] x)
// cond: isPowerOfTwo(c+1) && c >= 15
// result: (SUBL (SHLLconst <v.Type> [log2(c+1)] x) x)
for {
v.AddArg(x)
return true
}
- return false
-}
-func rewriteValue386_Op386MULLconst_20(v *Value) bool {
- b := v.Block
- _ = b
// match: (MULLconst [c] x)
// cond: isPowerOfTwo(c-8) && c >= 136
// result: (LEAL8 (SHLLconst <v.Type> [log2(c-8)] x) x)
v.AddArg(x)
return true
}
+ return false
+}
+func rewriteValue386_Op386MULLconst_20(v *Value) bool {
+ b := v.Block
+ _ = b
// match: (MULLconst [c] x)
// cond: c%3 == 0 && isPowerOfTwo(c/3)
// result: (SHLLconst [log2(c/3)] (LEAL2 <v.Type> x x))
return true
}
// match: (MULQconst [c] x)
- // cond: isPowerOfTwo(c)
- // result: (SHLQconst [log2(c)] x)
- for {
- c := v.AuxInt
- x := v.Args[0]
- if !(isPowerOfTwo(c)) {
- break
- }
- v.reset(OpAMD64SHLQconst)
- v.AuxInt = log2(c)
- v.AddArg(x)
- return true
- }
- // match: (MULQconst [c] x)
// cond: isPowerOfTwo(c+1) && c >= 15
// result: (SUBQ (SHLQconst <v.Type> [log2(c+1)] x) x)
for {
v.AddArg(x)
return true
}
- return false
-}
-func rewriteValueAMD64_OpAMD64MULQconst_20(v *Value) bool {
- b := v.Block
- _ = b
// match: (MULQconst [c] x)
// cond: isPowerOfTwo(c-8) && c >= 136
// result: (LEAQ8 (SHLQconst <v.Type> [log2(c-8)] x) x)
v.AddArg(x)
return true
}
+ return false
+}
+func rewriteValueAMD64_OpAMD64MULQconst_20(v *Value) bool {
+ b := v.Block
+ _ = b
// match: (MULQconst [c] x)
// cond: c%3 == 0 && isPowerOfTwo(c/3)
// result: (SHLQconst [log2(c/3)] (LEAQ2 <v.Type> x x))