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