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