1
2
3
4
5 package ssacompile
6
7 import (
8 "testing"
9
10 "cmd/compile/internal/ssa"
11 "cmd/compile/internal/ssa/ssaop"
12 "cmd/compile/internal/types"
13 )
14
15 func TestShiftConstAMD64(t *testing.T) {
16 c := testConfig(t)
17 fun := makeConstShiftFunc(c, 18, ssaop.OpLsh64x64, c.config.Types.UInt64)
18 checkOpcodeCounts(t, fun.f, map[ssaop.Op]int{ssaop.OpAMD64SHLQconst: 1, ssaop.OpAMD64CMPQconst: 0, ssaop.OpAMD64ANDQconst: 0})
19
20 fun = makeConstShiftFunc(c, 66, ssaop.OpLsh64x64, c.config.Types.UInt64)
21 checkOpcodeCounts(t, fun.f, map[ssaop.Op]int{ssaop.OpAMD64SHLQconst: 0, ssaop.OpAMD64CMPQconst: 0, ssaop.OpAMD64ANDQconst: 0})
22
23 fun = makeConstShiftFunc(c, 18, ssaop.OpRsh64Ux64, c.config.Types.UInt64)
24 checkOpcodeCounts(t, fun.f, map[ssaop.Op]int{ssaop.OpAMD64SHRQconst: 1, ssaop.OpAMD64CMPQconst: 0, ssaop.OpAMD64ANDQconst: 0})
25
26 fun = makeConstShiftFunc(c, 66, ssaop.OpRsh64Ux64, c.config.Types.UInt64)
27 checkOpcodeCounts(t, fun.f, map[ssaop.Op]int{ssaop.OpAMD64SHRQconst: 0, ssaop.OpAMD64CMPQconst: 0, ssaop.OpAMD64ANDQconst: 0})
28
29 fun = makeConstShiftFunc(c, 18, ssaop.OpRsh64x64, c.config.Types.Int64)
30 checkOpcodeCounts(t, fun.f, map[ssaop.Op]int{ssaop.OpAMD64SARQconst: 1, ssaop.OpAMD64CMPQconst: 0})
31
32 fun = makeConstShiftFunc(c, 66, ssaop.OpRsh64x64, c.config.Types.Int64)
33 checkOpcodeCounts(t, fun.f, map[ssaop.Op]int{ssaop.OpAMD64SARQconst: 1, ssaop.OpAMD64CMPQconst: 0})
34 }
35
36 func makeConstShiftFunc(c *Conf, amount int64, op ssaop.Op, typ *types.Type) fun {
37 ptyp := c.config.Types.BytePtr
38 fun := c.Fun("entry",
39 Bloc("entry",
40 Valu("mem", ssaop.OpInitMem, types.TypeMem, 0, nil),
41 Valu("SP", ssaop.OpSP, c.config.Types.Uintptr, 0, nil),
42 Valu("argptr", ssaop.OpOffPtr, ptyp, 8, nil, "SP"),
43 Valu("resptr", ssaop.OpOffPtr, ptyp, 16, nil, "SP"),
44 Valu("load", ssaop.OpLoad, typ, 0, nil, "argptr", "mem"),
45 Valu("c", ssaop.OpConst64, c.config.Types.UInt64, amount, nil),
46 Valu("shift", op, typ, 0, nil, "load", "c"),
47 Valu("store", ssaop.OpStore, types.TypeMem, 0, c.config.Types.UInt64, "resptr", "shift", "mem"),
48 Exit("store")))
49 runPasses(fun.f)
50 return fun
51 }
52
53 func TestShiftToExtensionAMD64(t *testing.T) {
54 c := testConfig(t)
55
56
57
58 ops := map[ssaop.Op]int{
59 ssaop.OpAMD64SHLQconst: 0, ssaop.OpAMD64SHLLconst: 0,
60 ssaop.OpAMD64SHRQconst: 0, ssaop.OpAMD64SHRLconst: 0,
61 ssaop.OpAMD64SARQconst: 0, ssaop.OpAMD64SARLconst: 0,
62 }
63 tests := [...]struct {
64 amount int64
65 left, right ssaop.Op
66 typ *types.Type
67 }{
68
69 {56, ssaop.OpLsh64x64, ssaop.OpRsh64Ux64, c.config.Types.UInt64},
70 {48, ssaop.OpLsh64x64, ssaop.OpRsh64Ux64, c.config.Types.UInt64},
71 {32, ssaop.OpLsh64x64, ssaop.OpRsh64Ux64, c.config.Types.UInt64},
72 {24, ssaop.OpLsh32x64, ssaop.OpRsh32Ux64, c.config.Types.UInt32},
73 {16, ssaop.OpLsh32x64, ssaop.OpRsh32Ux64, c.config.Types.UInt32},
74 {8, ssaop.OpLsh16x64, ssaop.OpRsh16Ux64, c.config.Types.UInt16},
75
76 {56, ssaop.OpLsh64x64, ssaop.OpRsh64x64, c.config.Types.Int64},
77 {48, ssaop.OpLsh64x64, ssaop.OpRsh64x64, c.config.Types.Int64},
78 {32, ssaop.OpLsh64x64, ssaop.OpRsh64x64, c.config.Types.Int64},
79 {24, ssaop.OpLsh32x64, ssaop.OpRsh32x64, c.config.Types.Int32},
80 {16, ssaop.OpLsh32x64, ssaop.OpRsh32x64, c.config.Types.Int32},
81 {8, ssaop.OpLsh16x64, ssaop.OpRsh16x64, c.config.Types.Int16},
82 }
83 for _, tc := range tests {
84 fun := makeShiftExtensionFunc(c, tc.amount, tc.left, tc.right, tc.typ)
85 checkOpcodeCounts(t, fun.f, ops)
86 }
87 }
88
89
90
91
92
93
94 func makeShiftExtensionFunc(c *Conf, amount int64, lshift, rshift ssaop.Op, typ *types.Type) fun {
95 ptyp := c.config.Types.BytePtr
96 fun := c.Fun("entry",
97 Bloc("entry",
98 Valu("mem", ssaop.OpInitMem, types.TypeMem, 0, nil),
99 Valu("SP", ssaop.OpSP, c.config.Types.Uintptr, 0, nil),
100 Valu("argptr", ssaop.OpOffPtr, ptyp, 8, nil, "SP"),
101 Valu("resptr", ssaop.OpOffPtr, ptyp, 16, nil, "SP"),
102 Valu("load", ssaop.OpLoad, typ, 0, nil, "argptr", "mem"),
103 Valu("c", ssaop.OpConst64, c.config.Types.UInt64, amount, nil),
104 Valu("lshift", lshift, typ, 0, nil, "load", "c"),
105 Valu("rshift", rshift, typ, 0, nil, "lshift", "c"),
106 Valu("store", ssaop.OpStore, types.TypeMem, 0, c.config.Types.UInt64, "resptr", "rshift", "mem"),
107 Exit("store")))
108 runPasses(fun.f)
109 return fun
110 }
111
112
113
114 func runPasses(f *ssa.Func) {
115 for i := range passes {
116 p := &passes[i]
117 if !f.Config.Optimize && !p.Required || p.Disabled {
118 continue
119 }
120 f.Pass = p
121 p.Fn(f)
122 }
123 }
124
View as plain text