| !sum | |
| # GetElem VSMOV (SMOV, signed narrow lanes): sign-extending extract | |
| - go: GetElem | |
| asm: "VSMOV" | |
| ssaVariant: "extr" | |
| specialLower: !string |- | |
| match (MOV%rreg x:(VSMOV%sextr [i] _)) => x | |
| match (MOV%rreg (VMOV%sextr [i] x)) => (VSMOV%sextr [i] x) | |
| match (MOV%rUreg x:(VMOV%sextr [i] _)) => x | |
| match (MOV%rUreg (VSMOV%sextr [i] x)) => (VMOV%sextr [i] x) | |
| in: | |
| - &immIndex | |
| class: immediate | |
| go: Immediate | |
| name: index | |
| - go: $t | |
| base: int | |
| elemBits: 8|16|32 | |
| out: | |
| - &scalar | |
| class: greg | |
| # GetElem VMOV (UMOV, unsigned lanes) | |
| - go: GetElem | |
| asm: "VMOV" | |
| ssaVariant: "extr" | |
| in: | |
| - *immIndex | |
| - go: $t | |
| base: uint | |
| out: | |
| - *scalar | |
| # GetElem VMOV (UMOV, D lanes) | |
| - go: GetElem | |
| asm: "VMOV" | |
| ssaVariant: "extr" | |
| in: | |
| - *immIndex | |
| - go: $t | |
| base: int | |
| elemBits: 64 | |
| out: | |
| - *scalar | |
| # GetElem VDUP (duplicate element into scalar float in vreg) | |
| - go: GetElem | |
| asm: "VDUP" | |
| ssaVariant: "extr" | |
| in: | |
| - *immIndex | |
| - &fvector | |
| go: $t | |
| base: float | |
| out: | |
| - &fscalarOut | |
| class: vreg | |
| treatLikeAScalarOfSize: 0 | |
| overwriteClass: greg | |
| overwriteBase: float | |
| # SetElem VMOV (INS, integer) | |
| - go: SetElem | |
| asm: "VMOV" | |
| ssaVariant: "ins" | |
| in: | |
| - *immIndex | |
| - &vector | |
| go: $t | |
| base: int|uint | |
| - *scalar | |
| out: | |
| - *vector | |
| # SetElem VMOV (float: INS from the lane 0 of the source) | |
| - go: SetElem | |
| asm: "VMOV" | |
| ssaVariant: "ins0" | |
| specialLower: !string "match (%h [0] (VMOVI16B [0]) y:(VDUP%sextr [i] _)) => y" | |
| in: | |
| - *immIndex | |
| - &imm0 | |
| class: immediate | |
| go: Immediate | |
| const: 0 # imm+vreg with treatLikeAScalarOfSize are treated as scalar in lane 0 | |
| - *fvector | |
| - &fscalarIn | |
| class: vreg | |
| treatLikeAScalarOfSize: 0 | |
| name: y | |
| out: | |
| - *fvector | |
| # broadcast1To16 VDUP (duplicate element 0 to all 16 byte lanes) | |
| - go: broadcast1To16 | |
| asm: "VDUP" | |
| ssaVariant: "bcast" | |
| constImm: 0 | |
| specialLower: !string "match (%h [i] (VMOV%sins [j] _ (MOVDconst [c]))) && i == j && c>=-128 && c<=255 => (VMOVI%a [uint8(c)])" | |
| in: | |
| - &immLane0 | |
| name: "@" # tag "fully constant" (no aux field needed) | |
| const: 0 | |
| class: immediate | |
| go: Immediate | |
| - &bcast8 | |
| go: $t | |
| bits: 128 | |
| elemBits: 8 | |
| out: | |
| - *bcast8 | |
| # broadcast1To8 VDUP (duplicate element 0 to all 8 halfword lanes) | |
| - go: broadcast1To8 | |
| asm: "VDUP" | |
| ssaVariant: "bcast" | |
| constImm: 0 | |
| in: | |
| - *immLane0 | |
| - &bcast16 | |
| go: $t | |
| bits: 128 | |
| elemBits: 16 | |
| out: | |
| - *bcast16 | |
| # broadcast1To4 VDUP (duplicate element 0 to all 4 word lanes) | |
| - go: broadcast1To4 | |
| asm: "VDUP" | |
| ssaVariant: "bcast" | |
| constImm: 0 | |
| in: | |
| - *immLane0 | |
| - &bcast32 | |
| go: $t | |
| bits: 128 | |
| elemBits: 32 | |
| out: | |
| - *bcast32 | |
| # broadcast1To2 VDUP (duplicate element 0 to both doubleword lanes) | |
| - go: broadcast1To2 | |
| asm: "VDUP" | |
| ssaVariant: "bcast" | |
| constImm: 0 | |
| in: | |
| - *immLane0 | |
| - &bcast64 | |
| go: $t | |
| bits: 128 | |
| elemBits: 64 | |
| out: | |
| - *bcast64 | |
| # bitSelect — VBIF (bit insert if false, internal) | |
| # Only Int8x16 is needed since VBIF operates on the full 128-bit register. | |
| # Other types cast to Int8x16 before calling bitSelect. | |
| - go: bitSelect | |
| asm: "VBIF" | |
| specialLower: !string "match (%h x y (VNOT16B mask)) => (VBIT16B x y mask)" | |
| in: | |
| - &v8 | |
| go: $t | |
| class: vreg | |
| base: int | |
| elemBits: 8 | |
| - *v8 | |
| - &maskReg | |
| class: vreg | |
| base: int | |
| name: mask | |
| out: | |
| - *v8 | |
| # bitSelectNot — VBIT (bit insert if true, internal) | |
| - go: bitSelectNot | |
| asm: "VBIT" | |
| specialLower: !string "match (%h x y (VNOT16B mask)) => (VBIF16B x y mask)" | |
| in: | |
| - *v8 | |
| - *v8 | |
| - *maskReg | |
| out: | |
| - *v8 | |
| # LookupOrZero — TBL (table lookup, zeros for out-of-range indices) | |
| - go: LookupOrZero | |
| regexpTag: "move" | |
| asm: "VTBL" | |
| in: | |
| - &bytesTable | |
| go: $t | |
| base: int|uint | |
| elemBits: 8 | |
| name: table | |
| - &byteIndices | |
| go: $t | |
| base: int|uint | |
| elemBits: 8 | |
| name: indices | |
| out: | |
| - &bytes | |
| go: $t | |
| base: int|uint | |
| elemBits: 8 | |
| # LookupOrKeep — TBX (table lookup extended, keeps original for out-of-range) | |
| - go: lookupOrKeep | |
| noGenericOps: "true" | |
| regexpTag: "move" | |
| asm: "VTBX" | |
| in: | |
| - &bytesKeep | |
| go: $t | |
| base: int|uint | |
| elemBits: 8 | |
| name: keep | |
| - *bytesTable | |
| - *byteIndices | |
| out: | |
| - *bytes | |
| # ConcatShiftBytesRight — EXT (extract bytes from concatenated pair) | |
| - go: ConcatShiftBytesRight | |
| asm: "VEXT" | |
| operandOrder: 2I | |
| in: | |
| - class: immediate | |
| immOffset: 0 | |
| name: shift | |
| - &uint8x128 | |
| go: $t | |
| base: uint | |
| bits: 128 | |
| elemBits: 8 | |
| - *uint8x128 | |
| out: | |
| - *uint8x128 | |
| # InterleaveLo — ZIP1 (interleave low halves) | |
| - go: InterleaveLo | |
| asm: "VZIP1" | |
| in: | |
| - &any128 | |
| go: $t | |
| bits: 128 | |
| - *any128 | |
| out: | |
| - *any128 | |
| # InterleaveHi — ZIP2 (interleave high halves) | |
| - go: InterleaveHi | |
| asm: "VZIP2" | |
| in: | |
| - *any128 | |
| - *any128 | |
| out: | |
| - *any128 | |
| # ConcatEven — UZP1 (extract even-indexed elements) | |
| - go: ConcatEven | |
| asm: "VUZP1" | |
| in: | |
| - *any128 | |
| - *any128 | |
| out: | |
| - *any128 | |
| # ConcatOdd — UZP2 (extract odd-indexed elements) | |
| - go: ConcatOdd | |
| asm: "VUZP2" | |
| in: | |
| - *any128 | |
| - *any128 | |
| out: | |
| - *any128 | |
| # InterleaveEven — TRN1 (transpose even-position pairs) | |
| - go: InterleaveEven | |
| asm: "VTRN1" | |
| in: | |
| - *any128 | |
| - *any128 | |
| out: | |
| - *any128 | |
| # InterleaveOdd — TRN2 (transpose odd-position pairs) | |
| - go: InterleaveOdd | |
| asm: "VTRN2" | |
| in: | |
| - *any128 | |
| - *any128 | |
| out: | |
| - *any128 |