xref: /openbmc/linux/arch/s390/include/asm/vx-insn.h (revision a8fe58ce)
1 /*
2  * Support for Vector Instructions
3  *
4  * Assembler macros to generate .byte/.word code for particular
5  * vector instructions that are supported by recent binutils (>= 2.26) only.
6  *
7  * Copyright IBM Corp. 2015
8  * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
9  */
10 
11 #ifndef __ASM_S390_VX_INSN_H
12 #define __ASM_S390_VX_INSN_H
13 
14 #ifdef __ASSEMBLY__
15 
16 
17 /* Macros to generate vector instruction byte code */
18 
19 #define REG_NUM_INVALID	       255
20 
21 /* GR_NUM - Retrieve general-purpose register number
22  *
23  * @opd:	Operand to store register number
24  * @r64:	String designation register in the format "%rN"
25  */
26 .macro	GR_NUM	opd gr
27 	\opd = REG_NUM_INVALID
28 	.ifc \gr,%r0
29 		\opd = 0
30 	.endif
31 	.ifc \gr,%r1
32 		\opd = 1
33 	.endif
34 	.ifc \gr,%r2
35 		\opd = 2
36 	.endif
37 	.ifc \gr,%r3
38 		\opd = 3
39 	.endif
40 	.ifc \gr,%r4
41 		\opd = 4
42 	.endif
43 	.ifc \gr,%r5
44 		\opd = 5
45 	.endif
46 	.ifc \gr,%r6
47 		\opd = 6
48 	.endif
49 	.ifc \gr,%r7
50 		\opd = 7
51 	.endif
52 	.ifc \gr,%r8
53 		\opd = 8
54 	.endif
55 	.ifc \gr,%r9
56 		\opd = 9
57 	.endif
58 	.ifc \gr,%r10
59 		\opd = 10
60 	.endif
61 	.ifc \gr,%r11
62 		\opd = 11
63 	.endif
64 	.ifc \gr,%r12
65 		\opd = 12
66 	.endif
67 	.ifc \gr,%r13
68 		\opd = 13
69 	.endif
70 	.ifc \gr,%r14
71 		\opd = 14
72 	.endif
73 	.ifc \gr,%r15
74 		\opd = 15
75 	.endif
76 	.if \opd == REG_NUM_INVALID
77 		.error "Invalid general-purpose register designation: \gr"
78 	.endif
79 .endm
80 
81 /* VX_R() - Macro to encode the VX_NUM into the instruction */
82 #define VX_R(v)		(v & 0x0F)
83 
84 /* VX_NUM - Retrieve vector register number
85  *
86  * @opd:	Operand to store register number
87  * @vxr:	String designation register in the format "%vN"
88  *
89  * The vector register number is used for as input number to the
90  * instruction and, as well as, to compute the RXB field of the
91  * instruction.  To encode the particular vector register number,
92  * use the VX_R(v) macro to extract the instruction opcode.
93  */
94 .macro	VX_NUM	opd vxr
95 	\opd = REG_NUM_INVALID
96 	.ifc \vxr,%v0
97 		\opd = 0
98 	.endif
99 	.ifc \vxr,%v1
100 		\opd = 1
101 	.endif
102 	.ifc \vxr,%v2
103 		\opd = 2
104 	.endif
105 	.ifc \vxr,%v3
106 		\opd = 3
107 	.endif
108 	.ifc \vxr,%v4
109 		\opd = 4
110 	.endif
111 	.ifc \vxr,%v5
112 		\opd = 5
113 	.endif
114 	.ifc \vxr,%v6
115 		\opd = 6
116 	.endif
117 	.ifc \vxr,%v7
118 		\opd = 7
119 	.endif
120 	.ifc \vxr,%v8
121 		\opd = 8
122 	.endif
123 	.ifc \vxr,%v9
124 		\opd = 9
125 	.endif
126 	.ifc \vxr,%v10
127 		\opd = 10
128 	.endif
129 	.ifc \vxr,%v11
130 		\opd = 11
131 	.endif
132 	.ifc \vxr,%v12
133 		\opd = 12
134 	.endif
135 	.ifc \vxr,%v13
136 		\opd = 13
137 	.endif
138 	.ifc \vxr,%v14
139 		\opd = 14
140 	.endif
141 	.ifc \vxr,%v15
142 		\opd = 15
143 	.endif
144 	.ifc \vxr,%v16
145 		\opd = 16
146 	.endif
147 	.ifc \vxr,%v17
148 		\opd = 17
149 	.endif
150 	.ifc \vxr,%v18
151 		\opd = 18
152 	.endif
153 	.ifc \vxr,%v19
154 		\opd = 19
155 	.endif
156 	.ifc \vxr,%v20
157 		\opd = 20
158 	.endif
159 	.ifc \vxr,%v21
160 		\opd = 21
161 	.endif
162 	.ifc \vxr,%v22
163 		\opd = 22
164 	.endif
165 	.ifc \vxr,%v23
166 		\opd = 23
167 	.endif
168 	.ifc \vxr,%v24
169 		\opd = 24
170 	.endif
171 	.ifc \vxr,%v25
172 		\opd = 25
173 	.endif
174 	.ifc \vxr,%v26
175 		\opd = 26
176 	.endif
177 	.ifc \vxr,%v27
178 		\opd = 27
179 	.endif
180 	.ifc \vxr,%v28
181 		\opd = 28
182 	.endif
183 	.ifc \vxr,%v29
184 		\opd = 29
185 	.endif
186 	.ifc \vxr,%v30
187 		\opd = 30
188 	.endif
189 	.ifc \vxr,%v31
190 		\opd = 31
191 	.endif
192 	.if \opd == REG_NUM_INVALID
193 		.error "Invalid vector register designation: \vxr"
194 	.endif
195 .endm
196 
197 /* RXB - Compute most significant bit used vector registers
198  *
199  * @rxb:	Operand to store computed RXB value
200  * @v1:		First vector register designated operand
201  * @v2:		Second vector register designated operand
202  * @v3:		Third vector register designated operand
203  * @v4:		Fourth vector register designated operand
204  */
205 .macro	RXB	rxb v1 v2=0 v3=0 v4=0
206 	\rxb = 0
207 	.if \v1 & 0x10
208 		\rxb = \rxb | 0x08
209 	.endif
210 	.if \v2 & 0x10
211 		\rxb = \rxb | 0x04
212 	.endif
213 	.if \v3 & 0x10
214 		\rxb = \rxb | 0x02
215 	.endif
216 	.if \v4 & 0x10
217 		\rxb = \rxb | 0x01
218 	.endif
219 .endm
220 
221 /* MRXB - Generate Element Size Control and RXB value
222  *
223  * @m:		Element size control
224  * @v1:		First vector register designated operand (for RXB)
225  * @v2:		Second vector register designated operand (for RXB)
226  * @v3:		Third vector register designated operand (for RXB)
227  * @v4:		Fourth vector register designated operand (for RXB)
228  */
229 .macro	MRXB	m v1 v2=0 v3=0 v4=0
230 	rxb = 0
231 	RXB	rxb, \v1, \v2, \v3, \v4
232 	.byte	(\m << 4) | rxb
233 .endm
234 
235 /* MRXBOPC - Generate Element Size Control, RXB, and final Opcode fields
236  *
237  * @m:		Element size control
238  * @opc:	Opcode
239  * @v1:		First vector register designated operand (for RXB)
240  * @v2:		Second vector register designated operand (for RXB)
241  * @v3:		Third vector register designated operand (for RXB)
242  * @v4:		Fourth vector register designated operand (for RXB)
243  */
244 .macro	MRXBOPC	m opc v1 v2=0 v3=0 v4=0
245 	MRXB	\m, \v1, \v2, \v3, \v4
246 	.byte	\opc
247 .endm
248 
249 /* Vector support instructions */
250 
251 /* VECTOR GENERATE BYTE MASK */
252 .macro	VGBM	vr imm2
253 	VX_NUM	v1, \vr
254 	.word	(0xE700 | (VX_R(v1) << 4))
255 	.word	\imm2
256 	MRXBOPC	0, 0x44, v1
257 .endm
258 .macro	VZERO	vxr
259 	VGBM	\vxr, 0
260 .endm
261 .macro	VONE	vxr
262 	VGBM	\vxr, 0xFFFF
263 .endm
264 
265 /* VECTOR LOAD VR ELEMENT FROM GR */
266 .macro	VLVG	v, gr, disp, m
267 	VX_NUM	v1, \v
268 	GR_NUM	b2, "%r0"
269 	GR_NUM	r3, \gr
270 	.word	0xE700 | (VX_R(v1) << 4) | r3
271 	.word	(b2 << 12) | (\disp)
272 	MRXBOPC	\m, 0x22, v1
273 .endm
274 .macro	VLVGB	v, gr, index, base
275 	VLVG	\v, \gr, \index, \base, 0
276 .endm
277 .macro	VLVGH	v, gr, index
278 	VLVG	\v, \gr, \index, 1
279 .endm
280 .macro	VLVGF	v, gr, index
281 	VLVG	\v, \gr, \index, 2
282 .endm
283 .macro	VLVGG	v, gr, index
284 	VLVG	\v, \gr, \index, 3
285 .endm
286 
287 /* VECTOR LOAD */
288 .macro	VL	v, disp, index="%r0", base
289 	VX_NUM	v1, \v
290 	GR_NUM	x2, \index
291 	GR_NUM	b2, \base
292 	.word	0xE700 | (VX_R(v1) << 4) | x2
293 	.word	(b2 << 12) | (\disp)
294 	MRXBOPC 0, 0x06, v1
295 .endm
296 
297 /* VECTOR LOAD ELEMENT */
298 .macro	VLEx	vr1, disp, index="%r0", base, m3, opc
299 	VX_NUM	v1, \vr1
300 	GR_NUM	x2, \index
301 	GR_NUM	b2, \base
302 	.word	0xE700 | (VX_R(v1) << 4) | x2
303 	.word	(b2 << 12) | (\disp)
304 	MRXBOPC	\m3, \opc, v1
305 .endm
306 .macro	VLEB	vr1, disp, index="%r0", base, m3
307 	VLEx	\vr1, \disp, \index, \base, \m3, 0x00
308 .endm
309 .macro	VLEH	vr1, disp, index="%r0", base, m3
310 	VLEx	\vr1, \disp, \index, \base, \m3, 0x01
311 .endm
312 .macro	VLEF	vr1, disp, index="%r0", base, m3
313 	VLEx	\vr1, \disp, \index, \base, \m3, 0x03
314 .endm
315 .macro	VLEG	vr1, disp, index="%r0", base, m3
316 	VLEx	\vr1, \disp, \index, \base, \m3, 0x02
317 .endm
318 
319 /* VECTOR LOAD ELEMENT IMMEDIATE */
320 .macro	VLEIx	vr1, imm2, m3, opc
321 	VX_NUM	v1, \vr1
322 	.word	0xE700 | (VX_R(v1) << 4)
323 	.word	\imm2
324 	MRXBOPC	\m3, \opc, v1
325 .endm
326 .macro	VLEIB	vr1, imm2, index
327 	VLEIx	\vr1, \imm2, \index, 0x40
328 .endm
329 .macro	VLEIH	vr1, imm2, index
330 	VLEIx	\vr1, \imm2, \index, 0x41
331 .endm
332 .macro	VLEIF	vr1, imm2, index
333 	VLEIx	\vr1, \imm2, \index, 0x43
334 .endm
335 .macro	VLEIG	vr1, imm2, index
336 	VLEIx	\vr1, \imm2, \index, 0x42
337 .endm
338 
339 /* VECTOR LOAD GR FROM VR ELEMENT */
340 .macro	VLGV	gr, vr, disp, base="%r0", m
341 	GR_NUM	r1, \gr
342 	GR_NUM	b2, \base
343 	VX_NUM	v3, \vr
344 	.word	0xE700 | (r1 << 4) | VX_R(v3)
345 	.word	(b2 << 12) | (\disp)
346 	MRXBOPC	\m, 0x21, v3
347 .endm
348 .macro	VLGVB	gr, vr, disp, base="%r0"
349 	VLGV	\gr, \vr, \disp, \base, 0
350 .endm
351 .macro	VLGVH	gr, vr, disp, base="%r0"
352 	VLGV	\gr, \vr, \disp, \base, 1
353 .endm
354 .macro	VLGVF	gr, vr, disp, base="%r0"
355 	VLGV	\gr, \vr, \disp, \base, 2
356 .endm
357 .macro	VLGVG	gr, vr, disp, base="%r0"
358 	VLGV	\gr, \vr, \disp, \base, 3
359 .endm
360 
361 /* VECTOR LOAD MULTIPLE */
362 .macro	VLM	vfrom, vto, disp, base
363 	VX_NUM	v1, \vfrom
364 	VX_NUM	v3, \vto
365 	GR_NUM	b2, \base	    /* Base register */
366 	.word	0xE700 | (VX_R(v1) << 4) | VX_R(v3)
367 	.word	(b2 << 12) | (\disp)
368 	MRXBOPC	0, 0x36, v1, v3
369 .endm
370 
371 /* VECTOR STORE MULTIPLE */
372 .macro	VSTM	vfrom, vto, disp, base
373 	VX_NUM	v1, \vfrom
374 	VX_NUM	v3, \vto
375 	GR_NUM	b2, \base	    /* Base register */
376 	.word	0xE700 | (VX_R(v1) << 4) | VX_R(v3)
377 	.word	(b2 << 12) | (\disp)
378 	MRXBOPC	0, 0x3E, v1, v3
379 .endm
380 
381 /* VECTOR PERMUTE */
382 .macro	VPERM	vr1, vr2, vr3, vr4
383 	VX_NUM	v1, \vr1
384 	VX_NUM	v2, \vr2
385 	VX_NUM	v3, \vr3
386 	VX_NUM	v4, \vr4
387 	.word	0xE700 | (VX_R(v1) << 4) | VX_R(v2)
388 	.word	(VX_R(v3) << 12)
389 	MRXBOPC	VX_R(v4), 0x8C, v1, v2, v3, v4
390 .endm
391 
392 /* VECTOR UNPACK LOGICAL LOW */
393 .macro	VUPLL	vr1, vr2, m3
394 	VX_NUM	v1, \vr1
395 	VX_NUM	v2, \vr2
396 	.word	0xE700 | (VX_R(v1) << 4) | VX_R(v2)
397 	.word	0x0000
398 	MRXBOPC	\m3, 0xD4, v1, v2
399 .endm
400 .macro	VUPLLB	vr1, vr2
401 	VUPLL	\vr1, \vr2, 0
402 .endm
403 .macro	VUPLLH	vr1, vr2
404 	VUPLL	\vr1, \vr2, 1
405 .endm
406 .macro	VUPLLF	vr1, vr2
407 	VUPLL	\vr1, \vr2, 2
408 .endm
409 
410 
411 /* Vector integer instructions */
412 
413 /* VECTOR EXCLUSIVE OR */
414 .macro	VX	vr1, vr2, vr3
415 	VX_NUM	v1, \vr1
416 	VX_NUM	v2, \vr2
417 	VX_NUM	v3, \vr3
418 	.word	0xE700 | (VX_R(v1) << 4) | VX_R(v2)
419 	.word	(VX_R(v3) << 12)
420 	MRXBOPC	0, 0x6D, v1, v2, v3
421 .endm
422 
423 /* VECTOR GALOIS FIELD MULTIPLY SUM */
424 .macro	VGFM	vr1, vr2, vr3, m4
425 	VX_NUM	v1, \vr1
426 	VX_NUM	v2, \vr2
427 	VX_NUM	v3, \vr3
428 	.word	0xE700 | (VX_R(v1) << 4) | VX_R(v2)
429 	.word	(VX_R(v3) << 12)
430 	MRXBOPC	\m4, 0xB4, v1, v2, v3
431 .endm
432 .macro	VGFMB	vr1, vr2, vr3
433 	VGFM	\vr1, \vr2, \vr3, 0
434 .endm
435 .macro	VGFMH	vr1, vr2, vr3
436 	VGFM	\vr1, \vr2, \vr3, 1
437 .endm
438 .macro	VGFMF	vr1, vr2, vr3
439 	VGFM	\vr1, \vr2, \vr3, 2
440 .endm
441 .macro	VGFMG	vr1, vr2, vr3
442 	VGFM	\vr1, \vr2, \vr3, 3
443 .endm
444 
445 /* VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE */
446 .macro	VGFMA	vr1, vr2, vr3, vr4, m5
447 	VX_NUM	v1, \vr1
448 	VX_NUM	v2, \vr2
449 	VX_NUM	v3, \vr3
450 	VX_NUM	v4, \vr4
451 	.word	0xE700 | (VX_R(v1) << 4) | VX_R(v2)
452 	.word	(VX_R(v3) << 12) | (\m5 << 8)
453 	MRXBOPC	VX_R(v4), 0xBC, v1, v2, v3, v4
454 .endm
455 .macro	VGFMAB	vr1, vr2, vr3, vr4
456 	VGFMA	\vr1, \vr2, \vr3, \vr4, 0
457 .endm
458 .macro	VGFMAH	vr1, vr2, vr3, vr4
459 	VGFMA	\vr1, \vr2, \vr3, \vr4, 1
460 .endm
461 .macro	VGFMAF	vr1, vr2, vr3, vr4
462 	VGFMA	\vr1, \vr2, \vr3, \vr4, 2
463 .endm
464 .macro	VGFMAG	vr1, vr2, vr3, vr4
465 	VGFMA	\vr1, \vr2, \vr3, \vr4, 3
466 .endm
467 
468 /* VECTOR SHIFT RIGHT LOGICAL BY BYTE */
469 .macro	VSRLB	vr1, vr2, vr3
470 	VX_NUM	v1, \vr1
471 	VX_NUM	v2, \vr2
472 	VX_NUM	v3, \vr3
473 	.word	0xE700 | (VX_R(v1) << 4) | VX_R(v2)
474 	.word	(VX_R(v3) << 12)
475 	MRXBOPC	0, 0x7D, v1, v2, v3
476 .endm
477 
478 
479 #endif	/* __ASSEMBLY__ */
480 #endif	/* __ASM_S390_VX_INSN_H */
481