1
2
3
4
5 package main
6
7 import "strings"
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 var regNamesS390X = []string{
51 "R0",
52 "R1",
53 "R2",
54 "R3",
55 "R4",
56 "R5",
57 "R6",
58 "R7",
59 "R8",
60 "R9",
61 "R10",
62 "R11",
63 "R12",
64 "g",
65 "R14",
66 "SP",
67 "F0",
68 "F1",
69 "F2",
70 "F3",
71 "F4",
72 "F5",
73 "F6",
74 "F7",
75 "F8",
76 "F9",
77 "F10",
78 "F11",
79 "F12",
80 "F13",
81 "F14",
82 "F15",
83
84
85
86
87 "SB",
88 }
89
90 func init() {
91
92 if len(regNamesS390X) > 64 {
93 panic("too many registers")
94 }
95 num := map[string]int{}
96 for i, name := range regNamesS390X {
97 num[name] = i
98 }
99 buildReg := func(s string) regMask {
100 m := regMask(0)
101 for _, r := range strings.Split(s, " ") {
102 if n, ok := num[r]; ok {
103 m |= regMask(1) << uint(n)
104 continue
105 }
106 panic("register " + r + " not found")
107 }
108 return m
109 }
110
111
112 var (
113 sp = buildReg("SP")
114 sb = buildReg("SB")
115 r0 = buildReg("R0")
116 tmp = buildReg("R11")
117
118
119 gp = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14")
120 gpg = gp | buildReg("g")
121 gpsp = gp | sp
122
123
124 ptr = gp &^ r0
125 ptrsp = ptr | sp
126 ptrspsb = ptrsp | sb
127
128 fp = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
129 callerSave = gp | fp | buildReg("g")
130 r1 = buildReg("R1")
131 r2 = buildReg("R2")
132 r3 = buildReg("R3")
133 r9 = buildReg("R9")
134 )
135
136 var (
137 gponly = []regMask{gp}
138 fponly = []regMask{fp}
139 )
140
141
142 var (
143 gp01 = regInfo{inputs: []regMask{}, outputs: gponly}
144 gp11 = regInfo{inputs: []regMask{gp}, outputs: gponly}
145 gp11sp = regInfo{inputs: []regMask{gpsp}, outputs: gponly}
146 gp21 = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
147 gp21sp = regInfo{inputs: []regMask{gpsp, gp}, outputs: gponly}
148 gp21tmp = regInfo{inputs: []regMask{gp &^ tmp, gp &^ tmp}, outputs: []regMask{gp &^ tmp}, clobbers: tmp}
149
150
151
152 sh21 = regInfo{inputs: []regMask{gp, ptr}, outputs: gponly}
153
154 addr = regInfo{inputs: []regMask{sp | sb}, outputs: gponly}
155 addridx = regInfo{inputs: []regMask{sp | sb, ptrsp}, outputs: gponly}
156
157 gp2flags = regInfo{inputs: []regMask{gpsp, gpsp}}
158 gp1flags = regInfo{inputs: []regMask{gpsp}}
159 gp2flags1 = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
160 gp11flags = regInfo{inputs: []regMask{gp}, outputs: gponly}
161 gp21flags = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
162 gp2flags1flags = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
163
164 gpload = regInfo{inputs: []regMask{ptrspsb, 0}, outputs: gponly}
165 gploadidx = regInfo{inputs: []regMask{ptrspsb, ptrsp, 0}, outputs: gponly}
166 gpopload = regInfo{inputs: []regMask{gp, ptrsp, 0}, outputs: gponly}
167 gpstore = regInfo{inputs: []regMask{ptrspsb, gpsp, 0}}
168 gpstoreconst = regInfo{inputs: []regMask{ptrspsb, 0}}
169 gpstoreidx = regInfo{inputs: []regMask{ptrsp, ptrsp, gpsp, 0}}
170 gpstorebr = regInfo{inputs: []regMask{ptrsp, gpsp, 0}}
171 gpstorelaa = regInfo{inputs: []regMask{ptrspsb, gpsp, 0}, outputs: gponly}
172 gpstorelab = regInfo{inputs: []regMask{r1, gpsp, 0}, clobbers: r1}
173
174 gpmvc = regInfo{inputs: []regMask{ptrsp, ptrsp, 0}}
175
176 fp01 = regInfo{inputs: []regMask{}, outputs: fponly}
177 fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
178 fp31 = regInfo{inputs: []regMask{fp, fp, fp}, outputs: fponly}
179 fp21clobber = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
180 fpgp = regInfo{inputs: fponly, outputs: gponly}
181 gpfp = regInfo{inputs: gponly, outputs: fponly}
182 fp11 = regInfo{inputs: fponly, outputs: fponly}
183 fp1flags = regInfo{inputs: []regMask{fp}}
184 fp11clobber = regInfo{inputs: fponly, outputs: fponly}
185 fp2flags = regInfo{inputs: []regMask{fp, fp}}
186
187 fpload = regInfo{inputs: []regMask{ptrspsb, 0}, outputs: fponly}
188 fploadidx = regInfo{inputs: []regMask{ptrsp, ptrsp, 0}, outputs: fponly}
189
190 fpstore = regInfo{inputs: []regMask{ptrspsb, fp, 0}}
191 fpstoreidx = regInfo{inputs: []regMask{ptrsp, ptrsp, fp, 0}}
192
193 sync = regInfo{inputs: []regMask{0}}
194
195
196 cas = regInfo{inputs: []regMask{ptrsp, r0, gpsp, 0}, outputs: []regMask{gp, 0}, clobbers: r0}
197
198
199
200
201
202 exchange = regInfo{inputs: []regMask{ptrsp, gpsp &^ r0, 0}, outputs: []regMask{r0, 0}}
203 )
204
205 var S390Xops = []opData{
206
207 {name: "FADDS", argLength: 2, reg: fp21clobber, typ: "(Float32,Flags)", asm: "FADDS", commutative: true, resultInArg0: true},
208 {name: "FADD", argLength: 2, reg: fp21clobber, typ: "(Float64,Flags)", asm: "FADD", commutative: true, resultInArg0: true},
209 {name: "FSUBS", argLength: 2, reg: fp21clobber, typ: "(Float32,Flags)", asm: "FSUBS", resultInArg0: true},
210 {name: "FSUB", argLength: 2, reg: fp21clobber, typ: "(Float64,Flags)", asm: "FSUB", resultInArg0: true},
211 {name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true, resultInArg0: true},
212 {name: "FMUL", argLength: 2, reg: fp21, asm: "FMUL", commutative: true, resultInArg0: true},
213 {name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS", resultInArg0: true},
214 {name: "FDIV", argLength: 2, reg: fp21, asm: "FDIV", resultInArg0: true},
215 {name: "FNEGS", argLength: 1, reg: fp11clobber, asm: "FNEGS", clobberFlags: true},
216 {name: "FNEG", argLength: 1, reg: fp11clobber, asm: "FNEG", clobberFlags: true},
217 {name: "FMADDS", argLength: 3, reg: fp31, asm: "FMADDS", resultInArg0: true},
218 {name: "FMADD", argLength: 3, reg: fp31, asm: "FMADD", resultInArg0: true},
219 {name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS", resultInArg0: true},
220 {name: "FMSUB", argLength: 3, reg: fp31, asm: "FMSUB", resultInArg0: true},
221 {name: "LPDFR", argLength: 1, reg: fp11, asm: "LPDFR"},
222 {name: "LNDFR", argLength: 1, reg: fp11, asm: "LNDFR"},
223 {name: "CPSDR", argLength: 2, reg: fp21, asm: "CPSDR"},
224
225
226
227
228
229
230
231
232
233
234 {name: "FIDBR", argLength: 1, reg: fp11, asm: "FIDBR", aux: "Int8"},
235
236 {name: "FMOVSload", argLength: 2, reg: fpload, asm: "FMOVS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
237 {name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
238 {name: "FMOVSconst", reg: fp01, asm: "FMOVS", aux: "Float32", rematerializeable: true},
239 {name: "FMOVDconst", reg: fp01, asm: "FMOVD", aux: "Float64", rematerializeable: true},
240 {name: "FMOVSloadidx", argLength: 3, reg: fploadidx, asm: "FMOVS", aux: "SymOff", symEffect: "Read"},
241 {name: "FMOVDloadidx", argLength: 3, reg: fploadidx, asm: "FMOVD", aux: "SymOff", symEffect: "Read"},
242
243 {name: "FMOVSstore", argLength: 3, reg: fpstore, asm: "FMOVS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"},
244 {name: "FMOVDstore", argLength: 3, reg: fpstore, asm: "FMOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"},
245 {name: "FMOVSstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVS", aux: "SymOff", symEffect: "Write"},
246 {name: "FMOVDstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVD", aux: "SymOff", symEffect: "Write"},
247
248
249 {name: "ADD", argLength: 2, reg: gp21sp, asm: "ADD", commutative: true, clobberFlags: true},
250 {name: "ADDW", argLength: 2, reg: gp21sp, asm: "ADDW", commutative: true, clobberFlags: true},
251 {name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADD", aux: "Int32", typ: "UInt64", clobberFlags: true},
252 {name: "ADDWconst", argLength: 1, reg: gp11sp, asm: "ADDW", aux: "Int32", clobberFlags: true},
253 {name: "ADDload", argLength: 3, reg: gpopload, asm: "ADD", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
254 {name: "ADDWload", argLength: 3, reg: gpopload, asm: "ADDW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
255
256 {name: "SUB", argLength: 2, reg: gp21, asm: "SUB", clobberFlags: true},
257 {name: "SUBW", argLength: 2, reg: gp21, asm: "SUBW", clobberFlags: true},
258 {name: "SUBconst", argLength: 1, reg: gp11, asm: "SUB", aux: "Int32", resultInArg0: true, clobberFlags: true},
259 {name: "SUBWconst", argLength: 1, reg: gp11, asm: "SUBW", aux: "Int32", resultInArg0: true, clobberFlags: true},
260 {name: "SUBload", argLength: 3, reg: gpopload, asm: "SUB", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
261 {name: "SUBWload", argLength: 3, reg: gpopload, asm: "SUBW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
262
263 {name: "MULLD", argLength: 2, reg: gp21, asm: "MULLD", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true},
264 {name: "MULLW", argLength: 2, reg: gp21, asm: "MULLW", typ: "Int32", commutative: true, resultInArg0: true, clobberFlags: true},
265 {name: "MULLDconst", argLength: 1, reg: gp11, asm: "MULLD", aux: "Int32", typ: "Int64", resultInArg0: true, clobberFlags: true},
266 {name: "MULLWconst", argLength: 1, reg: gp11, asm: "MULLW", aux: "Int32", typ: "Int32", resultInArg0: true, clobberFlags: true},
267 {name: "MULLDload", argLength: 3, reg: gpopload, asm: "MULLD", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
268 {name: "MULLWload", argLength: 3, reg: gpopload, asm: "MULLW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
269
270 {name: "MULHD", argLength: 2, reg: gp21tmp, asm: "MULHD", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true},
271 {name: "MULHDU", argLength: 2, reg: gp21tmp, asm: "MULHDU", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true},
272
273 {name: "DIVD", argLength: 2, reg: gp21tmp, asm: "DIVD", resultInArg0: true, clobberFlags: true},
274 {name: "DIVW", argLength: 2, reg: gp21tmp, asm: "DIVW", resultInArg0: true, clobberFlags: true},
275 {name: "DIVDU", argLength: 2, reg: gp21tmp, asm: "DIVDU", resultInArg0: true, clobberFlags: true},
276 {name: "DIVWU", argLength: 2, reg: gp21tmp, asm: "DIVWU", resultInArg0: true, clobberFlags: true},
277
278 {name: "MODD", argLength: 2, reg: gp21tmp, asm: "MODD", resultInArg0: true, clobberFlags: true},
279 {name: "MODW", argLength: 2, reg: gp21tmp, asm: "MODW", resultInArg0: true, clobberFlags: true},
280
281 {name: "MODDU", argLength: 2, reg: gp21tmp, asm: "MODDU", resultInArg0: true, clobberFlags: true},
282 {name: "MODWU", argLength: 2, reg: gp21tmp, asm: "MODWU", resultInArg0: true, clobberFlags: true},
283
284 {name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true},
285 {name: "ANDW", argLength: 2, reg: gp21, asm: "ANDW", commutative: true, clobberFlags: true},
286 {name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64", resultInArg0: true, clobberFlags: true},
287 {name: "ANDWconst", argLength: 1, reg: gp11, asm: "ANDW", aux: "Int32", resultInArg0: true, clobberFlags: true},
288 {name: "ANDload", argLength: 3, reg: gpopload, asm: "AND", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
289 {name: "ANDWload", argLength: 3, reg: gpopload, asm: "ANDW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
290
291 {name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true, clobberFlags: true},
292 {name: "ORW", argLength: 2, reg: gp21, asm: "ORW", commutative: true, clobberFlags: true},
293 {name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64", resultInArg0: true, clobberFlags: true},
294 {name: "ORWconst", argLength: 1, reg: gp11, asm: "ORW", aux: "Int32", resultInArg0: true, clobberFlags: true},
295 {name: "ORload", argLength: 3, reg: gpopload, asm: "OR", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
296 {name: "ORWload", argLength: 3, reg: gpopload, asm: "ORW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
297
298 {name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, clobberFlags: true},
299 {name: "XORW", argLength: 2, reg: gp21, asm: "XORW", commutative: true, clobberFlags: true},
300 {name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", resultInArg0: true, clobberFlags: true},
301 {name: "XORWconst", argLength: 1, reg: gp11, asm: "XORW", aux: "Int32", resultInArg0: true, clobberFlags: true},
302 {name: "XORload", argLength: 3, reg: gpopload, asm: "XOR", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
303 {name: "XORWload", argLength: 3, reg: gpopload, asm: "XORW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
304
305
306
307
308
309 {name: "ADDC", argLength: 2, reg: gp21flags, asm: "ADDC", typ: "(UInt64,Flags)", commutative: true},
310 {name: "ADDCconst", argLength: 1, reg: gp11flags, asm: "ADDC", typ: "(UInt64,Flags)", aux: "Int16"},
311 {name: "ADDE", argLength: 3, reg: gp2flags1flags, asm: "ADDE", typ: "(UInt64,Flags)", commutative: true, resultInArg0: true},
312 {name: "SUBC", argLength: 2, reg: gp21flags, asm: "SUBC", typ: "(UInt64,Flags)"},
313 {name: "SUBE", argLength: 3, reg: gp2flags1flags, asm: "SUBE", typ: "(UInt64,Flags)", resultInArg0: true},
314
315
316 {name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},
317 {name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"},
318
319 {name: "CMPU", argLength: 2, reg: gp2flags, asm: "CMPU", typ: "Flags"},
320 {name: "CMPWU", argLength: 2, reg: gp2flags, asm: "CMPWU", typ: "Flags"},
321
322 {name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", typ: "Flags", aux: "Int32"},
323 {name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", typ: "Flags", aux: "Int32"},
324 {name: "CMPUconst", argLength: 1, reg: gp1flags, asm: "CMPU", typ: "Flags", aux: "Int32"},
325 {name: "CMPWUconst", argLength: 1, reg: gp1flags, asm: "CMPWU", typ: "Flags", aux: "Int32"},
326
327 {name: "FCMPS", argLength: 2, reg: fp2flags, asm: "CEBR", typ: "Flags"},
328 {name: "FCMP", argLength: 2, reg: fp2flags, asm: "FCMPU", typ: "Flags"},
329 {name: "LTDBR", argLength: 1, reg: fp1flags, asm: "LTDBR", typ: "Flags"},
330 {name: "LTEBR", argLength: 1, reg: fp1flags, asm: "LTEBR", typ: "Flags"},
331
332 {name: "SLD", argLength: 2, reg: sh21, asm: "SLD"},
333 {name: "SLW", argLength: 2, reg: sh21, asm: "SLW"},
334 {name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "UInt8"},
335 {name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "UInt8"},
336
337 {name: "SRD", argLength: 2, reg: sh21, asm: "SRD"},
338 {name: "SRW", argLength: 2, reg: sh21, asm: "SRW"},
339 {name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "UInt8"},
340 {name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "UInt8"},
341
342
343 {name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true},
344 {name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true},
345 {name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "UInt8", clobberFlags: true},
346 {name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "UInt8", clobberFlags: true},
347
348
349
350 {name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"},
351 {name: "RLL", argLength: 2, reg: sh21, asm: "RLL"},
352 {name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "UInt8"},
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373 {name: "RXSBG", argLength: 2, reg: gp21, asm: "RXSBG", resultInArg0: true, aux: "S390XRotateParams", clobberFlags: true},
374 {name: "RISBGZ", argLength: 1, reg: gp11, asm: "RISBGZ", aux: "S390XRotateParams", clobberFlags: true},
375
376
377 {name: "NEG", argLength: 1, reg: gp11, asm: "NEG", clobberFlags: true},
378 {name: "NEGW", argLength: 1, reg: gp11, asm: "NEGW", clobberFlags: true},
379
380 {name: "NOT", argLength: 1, reg: gp11, resultInArg0: true, clobberFlags: true},
381 {name: "NOTW", argLength: 1, reg: gp11, resultInArg0: true, clobberFlags: true},
382
383 {name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"},
384 {name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"},
385
386
387
388 {name: "LOCGR", argLength: 3, reg: gp2flags1, resultInArg0: true, asm: "LOCGR", aux: "S390XCCMask"},
389
390 {name: "MOVBreg", argLength: 1, reg: gp11sp, asm: "MOVB", typ: "Int64"},
391 {name: "MOVBZreg", argLength: 1, reg: gp11sp, asm: "MOVBZ", typ: "UInt64"},
392 {name: "MOVHreg", argLength: 1, reg: gp11sp, asm: "MOVH", typ: "Int64"},
393 {name: "MOVHZreg", argLength: 1, reg: gp11sp, asm: "MOVHZ", typ: "UInt64"},
394 {name: "MOVWreg", argLength: 1, reg: gp11sp, asm: "MOVW", typ: "Int64"},
395 {name: "MOVWZreg", argLength: 1, reg: gp11sp, asm: "MOVWZ", typ: "UInt64"},
396
397 {name: "MOVDconst", reg: gp01, asm: "MOVD", typ: "UInt64", aux: "Int64", rematerializeable: true},
398
399 {name: "LDGR", argLength: 1, reg: gpfp, asm: "LDGR"},
400 {name: "LGDR", argLength: 1, reg: fpgp, asm: "LGDR"},
401
402 {name: "CFDBRA", argLength: 1, reg: fpgp, asm: "CFDBRA", clobberFlags: true},
403 {name: "CGDBRA", argLength: 1, reg: fpgp, asm: "CGDBRA", clobberFlags: true},
404 {name: "CFEBRA", argLength: 1, reg: fpgp, asm: "CFEBRA", clobberFlags: true},
405 {name: "CGEBRA", argLength: 1, reg: fpgp, asm: "CGEBRA", clobberFlags: true},
406 {name: "CEFBRA", argLength: 1, reg: gpfp, asm: "CEFBRA", clobberFlags: true},
407 {name: "CDFBRA", argLength: 1, reg: gpfp, asm: "CDFBRA", clobberFlags: true},
408 {name: "CEGBRA", argLength: 1, reg: gpfp, asm: "CEGBRA", clobberFlags: true},
409 {name: "CDGBRA", argLength: 1, reg: gpfp, asm: "CDGBRA", clobberFlags: true},
410 {name: "CLFEBR", argLength: 1, reg: fpgp, asm: "CLFEBR", clobberFlags: true},
411 {name: "CLFDBR", argLength: 1, reg: fpgp, asm: "CLFDBR", clobberFlags: true},
412 {name: "CLGEBR", argLength: 1, reg: fpgp, asm: "CLGEBR", clobberFlags: true},
413 {name: "CLGDBR", argLength: 1, reg: fpgp, asm: "CLGDBR", clobberFlags: true},
414 {name: "CELFBR", argLength: 1, reg: gpfp, asm: "CELFBR", clobberFlags: true},
415 {name: "CDLFBR", argLength: 1, reg: gpfp, asm: "CDLFBR", clobberFlags: true},
416 {name: "CELGBR", argLength: 1, reg: gpfp, asm: "CELGBR", clobberFlags: true},
417 {name: "CDLGBR", argLength: 1, reg: gpfp, asm: "CDLGBR", clobberFlags: true},
418
419 {name: "LEDBR", argLength: 1, reg: fp11, asm: "LEDBR"},
420 {name: "LDEBR", argLength: 1, reg: fp11, asm: "LDEBR"},
421
422 {name: "MOVDaddr", argLength: 1, reg: addr, aux: "SymOff", rematerializeable: true, symEffect: "Addr"},
423 {name: "MOVDaddridx", argLength: 2, reg: addridx, aux: "SymOff", symEffect: "Addr"},
424
425
426 {name: "MOVBZload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},
427 {name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
428 {name: "MOVHZload", argLength: 2, reg: gpload, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"},
429 {name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
430 {name: "MOVWZload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},
431 {name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
432 {name: "MOVDload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},
433
434 {name: "MOVWBR", argLength: 1, reg: gp11, asm: "MOVWBR"},
435 {name: "MOVDBR", argLength: 1, reg: gp11, asm: "MOVDBR"},
436
437 {name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"},
438 {name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},
439 {name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},
440
441 {name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
442 {name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
443 {name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
444 {name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
445 {name: "MOVHBRstore", argLength: 3, reg: gpstorebr, asm: "MOVHBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
446 {name: "MOVWBRstore", argLength: 3, reg: gpstorebr, asm: "MOVWBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
447 {name: "MOVDBRstore", argLength: 3, reg: gpstorebr, asm: "MOVDBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
448
449 {name: "MVC", argLength: 3, reg: gpmvc, asm: "MVC", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, faultOnNilArg1: true, symEffect: "None"},
450
451
452 {name: "MOVBZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", symEffect: "Read"},
453 {name: "MOVBloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVB", aux: "SymOff", typ: "Int8", symEffect: "Read"},
454 {name: "MOVHZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", symEffect: "Read"},
455 {name: "MOVHloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVH", aux: "SymOff", typ: "Int16", symEffect: "Read"},
456 {name: "MOVWZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", symEffect: "Read"},
457 {name: "MOVWloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVW", aux: "SymOff", typ: "Int32", symEffect: "Read"},
458 {name: "MOVDloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVD", aux: "SymOff", typ: "UInt64", symEffect: "Read"},
459 {name: "MOVHBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHBR", aux: "SymOff", typ: "Int16", symEffect: "Read"},
460 {name: "MOVWBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWBR", aux: "SymOff", typ: "Int32", symEffect: "Read"},
461 {name: "MOVDBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVDBR", aux: "SymOff", typ: "Int64", symEffect: "Read"},
462 {name: "MOVBstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVB", aux: "SymOff", symEffect: "Write"},
463 {name: "MOVHstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVH", aux: "SymOff", symEffect: "Write"},
464 {name: "MOVWstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVW", aux: "SymOff", symEffect: "Write"},
465 {name: "MOVDstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVD", aux: "SymOff", symEffect: "Write"},
466 {name: "MOVHBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVHBR", aux: "SymOff", symEffect: "Write"},
467 {name: "MOVWBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVWBR", aux: "SymOff", symEffect: "Write"},
468 {name: "MOVDBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVDBR", aux: "SymOff", symEffect: "Write"},
469
470
471
472
473 {name: "MOVBstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVB", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
474 {name: "MOVHstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVH", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
475 {name: "MOVWstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
476 {name: "MOVDstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVD", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
477
478 {name: "CLEAR", argLength: 2, reg: regInfo{inputs: []regMask{ptr, 0}}, asm: "CLEAR", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"},
479
480 {name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},
481 {name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},
482 {name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{ptrsp, buildReg("R12"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},
483 {name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{ptr}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},
484
485
486
487 {name: "InvertFlags", argLength: 1},
488
489
490 {name: "LoweredGetG", argLength: 1, reg: gp01},
491
492
493
494 {name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}, zeroWidth: true},
495
496
497 {name: "LoweredGetCallerSP", argLength: 1, reg: gp01, rematerializeable: true},
498
499
500
501
502 {name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
503 {name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{ptrsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
504
505 {name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
506 {name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
507
508
509
510
511
512
513 {name: "LoweredWB", argLength: 1, reg: regInfo{clobbers: (callerSave &^ gpg) | buildReg("R14") | r1, outputs: []regMask{r9}}, clobberFlags: true, aux: "Int64"},
514
515
516
517
518 {name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true},
519 {name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true},
520 {name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem", call: true},
521
522
523 {name: "FlagEQ"},
524 {name: "FlagLT"},
525 {name: "FlagGT"},
526 {name: "FlagOV"},
527
528
529 {name: "SYNC", argLength: 1, reg: sync, asm: "SYNC", typ: "Mem"},
530
531
532
533
534 {name: "MOVBZatomicload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
535 {name: "MOVWZatomicload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
536 {name: "MOVDatomicload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
537
538
539
540 {name: "MOVBatomicstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
541 {name: "MOVWatomicstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
542 {name: "MOVDatomicstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
543
544
545
546
547 {name: "LAA", argLength: 3, reg: gpstorelaa, asm: "LAA", typ: "(UInt32,Mem)", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
548 {name: "LAAG", argLength: 3, reg: gpstorelaa, asm: "LAAG", typ: "(UInt64,Mem)", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
549 {name: "AddTupleFirst32", argLength: 2},
550 {name: "AddTupleFirst64", argLength: 2},
551
552
553
554
555 {name: "LAN", argLength: 3, reg: gpstore, asm: "LAN", typ: "Mem", clobberFlags: true, hasSideEffects: true},
556 {name: "LANfloor", argLength: 3, reg: gpstorelab, asm: "LAN", typ: "Mem", clobberFlags: true, hasSideEffects: true},
557 {name: "LAO", argLength: 3, reg: gpstore, asm: "LAO", typ: "Mem", clobberFlags: true, hasSideEffects: true},
558 {name: "LAOfloor", argLength: 3, reg: gpstorelab, asm: "LAO", typ: "Mem", clobberFlags: true, hasSideEffects: true},
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581 {name: "LoweredAtomicCas32", argLength: 4, reg: cas, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
582 {name: "LoweredAtomicCas64", argLength: 4, reg: cas, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
583
584
585
586 {name: "LoweredAtomicExchange32", argLength: 3, reg: exchange, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
587 {name: "LoweredAtomicExchange64", argLength: 3, reg: exchange, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
588
589
590 {
591 name: "FLOGR",
592 argLength: 1,
593 reg: regInfo{inputs: gponly, outputs: []regMask{buildReg("R0")}, clobbers: buildReg("R1")},
594 asm: "FLOGR",
595 typ: "UInt64",
596 clobberFlags: true,
597 },
598
599
600
601
602
603
604 {
605 name: "POPCNT",
606 argLength: 1,
607 reg: gp11,
608 asm: "POPCNT",
609 typ: "UInt64",
610 clobberFlags: true,
611 },
612
613
614
615
616
617
618
619 {
620 name: "MLGR",
621 argLength: 2,
622 reg: regInfo{inputs: []regMask{gp, r3}, outputs: []regMask{r2, r3}},
623 asm: "MLGR",
624 },
625
626
627 {name: "SumBytes2", argLength: 1, typ: "UInt8"},
628 {name: "SumBytes4", argLength: 1, typ: "UInt8"},
629 {name: "SumBytes8", argLength: 1, typ: "UInt8"},
630
631
632 {
633 name: "STMG2",
634 argLength: 4,
635 reg: regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), 0}},
636 aux: "SymOff",
637 typ: "Mem",
638 asm: "STMG",
639 faultOnNilArg0: true,
640 symEffect: "Write",
641 clobberFlags: true,
642 },
643 {
644 name: "STMG3",
645 argLength: 5,
646 reg: regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), buildReg("R3"), 0}},
647 aux: "SymOff",
648 typ: "Mem",
649 asm: "STMG",
650 faultOnNilArg0: true,
651 symEffect: "Write",
652 clobberFlags: true,
653 },
654 {
655 name: "STMG4",
656 argLength: 6,
657 reg: regInfo{inputs: []regMask{
658 ptrsp,
659 buildReg("R1"),
660 buildReg("R2"),
661 buildReg("R3"),
662 buildReg("R4"),
663 0,
664 }},
665 aux: "SymOff",
666 typ: "Mem",
667 asm: "STMG",
668 faultOnNilArg0: true,
669 symEffect: "Write",
670 clobberFlags: true,
671 },
672 {
673 name: "STM2",
674 argLength: 4,
675 reg: regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), 0}},
676 aux: "SymOff",
677 typ: "Mem",
678 asm: "STMY",
679 faultOnNilArg0: true,
680 symEffect: "Write",
681 clobberFlags: true,
682 },
683 {
684 name: "STM3",
685 argLength: 5,
686 reg: regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), buildReg("R3"), 0}},
687 aux: "SymOff",
688 typ: "Mem",
689 asm: "STMY",
690 faultOnNilArg0: true,
691 symEffect: "Write",
692 clobberFlags: true,
693 },
694 {
695 name: "STM4",
696 argLength: 6,
697 reg: regInfo{inputs: []regMask{
698 ptrsp,
699 buildReg("R1"),
700 buildReg("R2"),
701 buildReg("R3"),
702 buildReg("R4"),
703 0,
704 }},
705 aux: "SymOff",
706 typ: "Mem",
707 asm: "STMY",
708 faultOnNilArg0: true,
709 symEffect: "Write",
710 clobberFlags: true,
711 },
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727 {
728 name: "LoweredMove",
729 aux: "Int64",
730 argLength: 4,
731 reg: regInfo{
732 inputs: []regMask{buildReg("R1"), buildReg("R2"), gpsp},
733 clobbers: buildReg("R1 R2"),
734 },
735 clobberFlags: true,
736 typ: "Mem",
737 faultOnNilArg0: true,
738 faultOnNilArg1: true,
739 },
740
741
742
743
744
745
746
747
748
749
750
751
752
753 {
754 name: "LoweredZero",
755 aux: "Int64",
756 argLength: 3,
757 reg: regInfo{
758 inputs: []regMask{buildReg("R1"), gpsp},
759 clobbers: buildReg("R1"),
760 },
761 clobberFlags: true,
762 typ: "Mem",
763 faultOnNilArg0: true,
764 },
765 }
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781 var S390Xblocks = []blockData{
782
783 {name: "BRC", controls: 1, aux: "S390XCCMask"},
784
785
786
787
788 {name: "CRJ", controls: 2, aux: "S390XCCMask"},
789 {name: "CGRJ", controls: 2, aux: "S390XCCMask"},
790 {name: "CLRJ", controls: 2, aux: "S390XCCMask"},
791 {name: "CLGRJ", controls: 2, aux: "S390XCCMask"},
792
793
794
795
796
797
798 {name: "CIJ", controls: 1, aux: "S390XCCMaskInt8"},
799 {name: "CGIJ", controls: 1, aux: "S390XCCMaskInt8"},
800 {name: "CLIJ", controls: 1, aux: "S390XCCMaskUint8"},
801 {name: "CLGIJ", controls: 1, aux: "S390XCCMaskUint8"},
802 }
803
804 archs = append(archs, arch{
805 name: "S390X",
806 pkg: "cmd/internal/obj/s390x",
807 genfile: "../../s390x/ssa.go",
808 ops: S390Xops,
809 blocks: S390Xblocks,
810 regnames: regNamesS390X,
811 gpregmask: gp,
812 fpregmask: fp,
813 framepointerreg: -1,
814 linkreg: int8(num["R14"]),
815 imports: []string{
816 "cmd/internal/obj/s390x",
817 },
818 })
819 }
820
View as plain text