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