Source file src/pkg/cmd/compile/internal/ssa/gen/WasmOps.go
1
2
3
4
5
6
7 package main
8
9 import "strings"
10
11 var regNamesWasm = []string{
12 "R0",
13 "R1",
14 "R2",
15 "R3",
16 "R4",
17 "R5",
18 "R6",
19 "R7",
20 "R8",
21 "R9",
22 "R10",
23 "R11",
24 "R12",
25 "R13",
26 "R14",
27 "R15",
28
29 "F0",
30 "F1",
31 "F2",
32 "F3",
33 "F4",
34 "F5",
35 "F6",
36 "F7",
37 "F8",
38 "F9",
39 "F10",
40 "F11",
41 "F12",
42 "F13",
43 "F14",
44 "F15",
45
46 "SP",
47 "g",
48
49
50 "SB",
51 }
52
53 func init() {
54
55 if len(regNamesWasm) > 64 {
56 panic("too many registers")
57 }
58 num := map[string]int{}
59 for i, name := range regNamesWasm {
60 num[name] = i
61 }
62 buildReg := func(s string) regMask {
63 m := regMask(0)
64 for _, r := range strings.Split(s, " ") {
65 if n, ok := num[r]; ok {
66 m |= regMask(1) << uint(n)
67 continue
68 }
69 panic("register " + r + " not found")
70 }
71 return m
72 }
73
74 var (
75 gp = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15")
76 fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
77 gpsp = gp | buildReg("SP")
78 gpspsb = gpsp | buildReg("SB")
79
80
81 callerSave = gp | fp | buildReg("g")
82 )
83
84
85 var (
86 gp01 = regInfo{inputs: nil, outputs: []regMask{gp}}
87 gp11 = regInfo{inputs: []regMask{gpsp}, outputs: []regMask{gp}}
88 gp21 = regInfo{inputs: []regMask{gpsp, gpsp}, outputs: []regMask{gp}}
89 gp31 = regInfo{inputs: []regMask{gpsp, gpsp, gpsp}, outputs: []regMask{gp}}
90 fp01 = regInfo{inputs: nil, outputs: []regMask{fp}}
91 fp11 = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
92 fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
93 fp21gp = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{gp}}
94 gpload = regInfo{inputs: []regMask{gpspsb, 0}, outputs: []regMask{gp}}
95 gpstore = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
96 fpload = regInfo{inputs: []regMask{gpspsb, 0}, outputs: []regMask{fp}}
97 fpstore = regInfo{inputs: []regMask{gpspsb, fp, 0}}
98
99 )
100
101 var WasmOps = []opData{
102 {name: "LoweredStaticCall", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", call: true, symEffect: "None"},
103 {name: "LoweredClosureCall", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp, 0}, clobbers: callerSave}, aux: "Int64", call: true},
104 {name: "LoweredInterCall", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", call: true},
105
106 {name: "LoweredAddr", argLength: 1, reg: gp11, aux: "SymOff", rematerializeable: true, symEffect: "Addr"},
107 {name: "LoweredMove", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp}}, aux: "Int64"},
108 {name: "LoweredZero", argLength: 2, reg: regInfo{inputs: []regMask{gp}}, aux: "Int64"},
109
110 {name: "LoweredGetClosurePtr", reg: gp01},
111 {name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
112 {name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
113 {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp}}, nilCheck: true, faultOnNilArg0: true},
114 {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp}}, aux: "Sym", symEffect: "None"},
115 {name: "LoweredRound32F", argLength: 1, reg: fp11, typ: "Float32"},
116
117
118
119
120
121
122
123
124 {name: "LoweredConvert", argLength: 2, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}},
125
126
127
128 {name: "Select", asm: "Select", argLength: 3, reg: gp31},
129
130 {name: "I64Load8U", asm: "I64Load8U", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt8"},
131 {name: "I64Load8S", asm: "I64Load8S", argLength: 2, reg: gpload, aux: "Int64", typ: "Int8"},
132 {name: "I64Load16U", asm: "I64Load16U", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt16"},
133 {name: "I64Load16S", asm: "I64Load16S", argLength: 2, reg: gpload, aux: "Int64", typ: "Int16"},
134 {name: "I64Load32U", asm: "I64Load32U", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt32"},
135 {name: "I64Load32S", asm: "I64Load32S", argLength: 2, reg: gpload, aux: "Int64", typ: "Int32"},
136 {name: "I64Load", asm: "I64Load", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt64"},
137 {name: "I64Store8", asm: "I64Store8", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},
138 {name: "I64Store16", asm: "I64Store16", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},
139 {name: "I64Store32", asm: "I64Store32", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},
140 {name: "I64Store", asm: "I64Store", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},
141
142 {name: "F32Load", asm: "F32Load", argLength: 2, reg: fpload, aux: "Int64", typ: "Float64"},
143 {name: "F64Load", asm: "F64Load", argLength: 2, reg: fpload, aux: "Int64", typ: "Float64"},
144 {name: "F32Store", asm: "F32Store", argLength: 3, reg: fpstore, aux: "Int64", typ: "Mem"},
145 {name: "F64Store", asm: "F64Store", argLength: 3, reg: fpstore, aux: "Int64", typ: "Mem"},
146
147 {name: "I64Const", reg: gp01, aux: "Int64", rematerializeable: true, typ: "Int64"},
148 {name: "F64Const", reg: fp01, aux: "Float64", rematerializeable: true, typ: "Float64"},
149
150 {name: "I64Eqz", asm: "I64Eqz", argLength: 1, reg: gp11, typ: "Bool"},
151 {name: "I64Eq", asm: "I64Eq", argLength: 2, reg: gp21, typ: "Bool"},
152 {name: "I64Ne", asm: "I64Ne", argLength: 2, reg: gp21, typ: "Bool"},
153 {name: "I64LtS", asm: "I64LtS", argLength: 2, reg: gp21, typ: "Bool"},
154 {name: "I64LtU", asm: "I64LtU", argLength: 2, reg: gp21, typ: "Bool"},
155 {name: "I64GtS", asm: "I64GtS", argLength: 2, reg: gp21, typ: "Bool"},
156 {name: "I64GtU", asm: "I64GtU", argLength: 2, reg: gp21, typ: "Bool"},
157 {name: "I64LeS", asm: "I64LeS", argLength: 2, reg: gp21, typ: "Bool"},
158 {name: "I64LeU", asm: "I64LeU", argLength: 2, reg: gp21, typ: "Bool"},
159 {name: "I64GeS", asm: "I64GeS", argLength: 2, reg: gp21, typ: "Bool"},
160 {name: "I64GeU", asm: "I64GeU", argLength: 2, reg: gp21, typ: "Bool"},
161
162 {name: "F64Eq", asm: "F64Eq", argLength: 2, reg: fp21gp, typ: "Bool"},
163 {name: "F64Ne", asm: "F64Ne", argLength: 2, reg: fp21gp, typ: "Bool"},
164 {name: "F64Lt", asm: "F64Lt", argLength: 2, reg: fp21gp, typ: "Bool"},
165 {name: "F64Gt", asm: "F64Gt", argLength: 2, reg: fp21gp, typ: "Bool"},
166 {name: "F64Le", asm: "F64Le", argLength: 2, reg: fp21gp, typ: "Bool"},
167 {name: "F64Ge", asm: "F64Ge", argLength: 2, reg: fp21gp, typ: "Bool"},
168
169 {name: "I64Add", asm: "I64Add", argLength: 2, reg: gp21, typ: "Int64"},
170 {name: "I64AddConst", asm: "I64Add", argLength: 1, reg: gp11, aux: "Int64", typ: "Int64"},
171 {name: "I64Sub", asm: "I64Sub", argLength: 2, reg: gp21, typ: "Int64"},
172 {name: "I64Mul", asm: "I64Mul", argLength: 2, reg: gp21, typ: "Int64"},
173 {name: "I64DivS", asm: "I64DivS", argLength: 2, reg: gp21, typ: "Int64"},
174 {name: "I64DivU", asm: "I64DivU", argLength: 2, reg: gp21, typ: "Int64"},
175 {name: "I64RemS", asm: "I64RemS", argLength: 2, reg: gp21, typ: "Int64"},
176 {name: "I64RemU", asm: "I64RemU", argLength: 2, reg: gp21, typ: "Int64"},
177 {name: "I64And", asm: "I64And", argLength: 2, reg: gp21, typ: "Int64"},
178 {name: "I64Or", asm: "I64Or", argLength: 2, reg: gp21, typ: "Int64"},
179 {name: "I64Xor", asm: "I64Xor", argLength: 2, reg: gp21, typ: "Int64"},
180 {name: "I64Shl", asm: "I64Shl", argLength: 2, reg: gp21, typ: "Int64"},
181 {name: "I64ShrS", asm: "I64ShrS", argLength: 2, reg: gp21, typ: "Int64"},
182 {name: "I64ShrU", asm: "I64ShrU", argLength: 2, reg: gp21, typ: "Int64"},
183
184 {name: "F64Neg", asm: "F64Neg", argLength: 1, reg: fp11, typ: "Float64"},
185 {name: "F64Add", asm: "F64Add", argLength: 2, reg: fp21, typ: "Float64"},
186 {name: "F64Sub", asm: "F64Sub", argLength: 2, reg: fp21, typ: "Float64"},
187 {name: "F64Mul", asm: "F64Mul", argLength: 2, reg: fp21, typ: "Float64"},
188 {name: "F64Div", asm: "F64Div", argLength: 2, reg: fp21, typ: "Float64"},
189
190 {name: "I64TruncSatF64S", asm: "I64TruncSatF64S", argLength: 1, reg: regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}, typ: "Int64"},
191 {name: "I64TruncSatF64U", asm: "I64TruncSatF64U", argLength: 1, reg: regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}, typ: "Int64"},
192 {name: "F64ConvertI64S", asm: "F64ConvertI64S", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}, typ: "Float64"},
193 {name: "F64ConvertI64U", asm: "F64ConvertI64U", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}, typ: "Float64"},
194
195 {name: "I64Extend8S", asm: "I64Extend8S", argLength: 1, reg: gp11, typ: "Int64"},
196 {name: "I64Extend16S", asm: "I64Extend16S", argLength: 1, reg: gp11, typ: "Int64"},
197 {name: "I64Extend32S", asm: "I64Extend32S", argLength: 1, reg: gp11, typ: "Int64"},
198
199 {name: "F64Sqrt", asm: "F64Sqrt", argLength: 1, reg: fp11, typ: "Float64"},
200 {name: "F64Trunc", asm: "F64Trunc", argLength: 1, reg: fp11, typ: "Float64"},
201 {name: "F64Ceil", asm: "F64Ceil", argLength: 1, reg: fp11, typ: "Float64"},
202 {name: "F64Floor", asm: "F64Floor", argLength: 1, reg: fp11, typ: "Float64"},
203 {name: "F64Nearest", asm: "F64Nearest", argLength: 1, reg: fp11, typ: "Float64"},
204 {name: "F64Abs", asm: "F64Abs", argLength: 1, reg: fp11, typ: "Float64"},
205 {name: "F64Copysign", asm: "F64Copysign", argLength: 2, reg: fp21, typ: "Float64"},
206
207 {name: "I64Ctz", asm: "I64Ctz", argLength: 1, reg: gp11, typ: "Int64"},
208 {name: "I64Clz", asm: "I64Clz", argLength: 1, reg: gp11, typ: "Int64"},
209 {name: "I64Rotl", asm: "I64Rotl", argLength: 2, reg: gp21, typ: "Int64"},
210 {name: "I64Popcnt", asm: "I64Popcnt", argLength: 1, reg: gp11, typ: "Int64"},
211 }
212
213 archs = append(archs, arch{
214 name: "Wasm",
215 pkg: "cmd/internal/obj/wasm",
216 genfile: "../../wasm/ssa.go",
217 ops: WasmOps,
218 blocks: nil,
219 regnames: regNamesWasm,
220 gpregmask: gp,
221 fpregmask: fp,
222 framepointerreg: -1,
223 linkreg: -1,
224 })
225 }
226
View as plain text