// Code generated by "mkasm_aarch64.py", DO NOT EDIT.

package aarch64

import (
    `github.com/cloudwego/iasm/asm`
)

// ABS instruction have 4 forms across 2 categories:
//
// 1. Absolute value
//
//    ABS  <Wd>, <Wn>
//    ABS  <Xd>, <Xn>
//
// Absolute value computes the absolute value of the signed integer value in the
// source register, and writes the result to the destination register.
//
// 2. Absolute value (vector)
//
//    ABS  <Vd>.<T>, <Vn>.<T>
//    ABS  <V><d>, <V><n>
//
// Absolute value (vector). This instruction calculates the absolute value of each
// vector element in the source SIMD&FP register, puts the result into a vector,
// and writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ABS(v0, v1 interface{}) *Instruction {
    p := self.alloc("ABS", 2, asm.Operands { v0, v1 })
    // ABS  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(0, 0, 0, 8, sa_wn, sa_wd))
    }
    // ABS  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 8, sa_xn, sa_xd))
    }
    // ABS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 11, sa_vn, sa_vd))
    }
    // ABS  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for ABS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(0, sa_v, 11, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ABS")
}

// ADC instruction have 2 forms across one single category:
//
// 1. Add with Carry
//
//    ADC  <Wd>, <Wn>, <Wm>
//    ADC  <Xd>, <Xn>, <Xm>
//
// Add with Carry adds two register values and the Carry flag value, and writes the
// result to the destination register.
//
func (self *Program) ADC(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ADC", 3, asm.Operands { v0, v1, v2 })
    // ADC  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(addsub_carry(0, 0, 0, sa_wm, sa_wn, sa_wd))
    }
    // ADC  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(addsub_carry(1, 0, 0, sa_xm, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ADC")
}

// ADCS instruction have 2 forms across one single category:
//
// 1. Add with Carry, setting flags
//
//    ADCS  <Wd>, <Wn>, <Wm>
//    ADCS  <Xd>, <Xn>, <Xm>
//
// Add with Carry, setting flags, adds two register values and the Carry flag
// value, and writes the result to the destination register. It updates the
// condition flags based on the result.
//
func (self *Program) ADCS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ADCS", 3, asm.Operands { v0, v1, v2 })
    // ADCS  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(addsub_carry(0, 0, 1, sa_wm, sa_wn, sa_wd))
    }
    // ADCS  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(addsub_carry(1, 0, 1, sa_xm, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ADCS")
}

// ADD instruction have 10 forms across 4 categories:
//
// 1. Add (extended register)
//
//    ADD  <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
//    ADD  <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}
//
// Add (extended register) adds a register value and a sign or zero-extended
// register value, followed by an optional left shift amount, and writes the result
// to the destination register. The argument that is extended from the <Rm>
// register can be a byte, halfword, word, or doubleword.
//
// 2. Add (immediate)
//
//    ADD  <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}
//    ADD  <Wd|WSP>, <Wn|WSP>, <label>{, <shift>}
//    ADD  <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}
//    ADD  <Xd|SP>, <Xn|SP>, <label>{, <shift>}
//
// Add (immediate) adds a register value and an optionally-shifted immediate value,
// and writes the result to the destination register.
//
// 3. Add (shifted register)
//
//    ADD  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    ADD  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Add (shifted register) adds a register value and an optionally-shifted register
// value, and writes the result to the destination register.
//
// 4. Add (vector)
//
//    ADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    ADD  <V><d>, <V><n>, <V><m>
//
// Add (vector). This instruction adds corresponding elements in the two source
// SIMD&FP registers, places the results into a vector, and writes the vector to
// the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ADD(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("ADD", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("ADD", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction ADD takes 3 or 4 operands")
    }
    // ADD  <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isWrOrWSP(v1) &&
       isWr(v2) &&
       (len(vv) == 0 && (v0 == WSP || v1 == WSP) || len(vv) == 1 && modt(vv[0]) == ModUXTW) &&
       (v0 == WSP || v1 == WSP) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend := uint32(0b010)
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend = 0b000
                case ModUXTH: sa_extend = 0b001
                case ModLSL: sa_extend = 0b010
                case ModUXTW: sa_extend = 0b010
                case ModUXTX: sa_extend = 0b011
                case ModSXTB: sa_extend = 0b100
                case ModSXTH: sa_extend = 0b101
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_ext(0, 0, 0, 0, sa_wm, sa_extend, sa_amount, sa_wn_wsp, sa_wd_wsp))
    }
    // ADD  <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isXrOrSP(v1) &&
       isWrOrXr(v2) &&
       (len(vv) == 0 && (v0 == SP || v1 == SP) || len(vv) == 1 && modt(vv[0]) == ModUXTX) &&
       (v0 == SP || v1 == SP) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend_1 := uint32(0b011)
        var sa_r [4]uint32
        var sa_r__bit_mask [4]uint32
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        switch true {
            case isWr(v2): sa_r = [4]uint32{0b000, 0b010, 0b100, 0b110}
            case isXr(v2): sa_r = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        switch true {
            case isWr(v2): sa_r__bit_mask = [4]uint32{0b110, 0b111, 0b110, 0b111}
            case isXr(v2): sa_r__bit_mask = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend_1 = 0b000
                case ModUXTH: sa_extend_1 = 0b001
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModUXTX: sa_extend_1 = 0b011
                case ModSXTB: sa_extend_1 = 0b100
                case ModSXTH: sa_extend_1 = 0b101
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        if !matchany(sa_extend_1, &sa_r[0], &sa_r__bit_mask[0], 4) {
            panic("aarch64: invalid combination of operands for ADD")
        }
        return p.setins(addsub_ext(1, 0, 0, 0, sa_m, sa_extend_1, sa_amount, sa_xn_sp, sa_xd_sp))
    }
    // ADD  <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isWrOrWSP(v1) &&
       isInRange(v2, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) &&
       (v0 == WSP || v1 == WSP) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_imm := asImm12(v2)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(0, 0, 0, sa_shift, sa_imm, sa_wn_wsp, sa_wd_wsp))
    }
    // ADD  <Wd|WSP>, <Wn|WSP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isWrOrWSP(v1) &&
       isLabel(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) &&
       (v0 == WSP || v1 == WSP) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_label := v2.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(0, 0, 0, sa_shift, abs12(sa_label), sa_wn_wsp, sa_wd_wsp)
        })
    }
    // ADD  <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isXrOrSP(v1) &&
       isInRange(v2, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) &&
       (v0 == SP || v1 == SP) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_imm := asImm12(v2)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(1, 0, 0, sa_shift, sa_imm, sa_xn_sp, sa_xd_sp))
    }
    // ADD  <Xd|SP>, <Xn|SP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isXrOrSP(v1) &&
       isLabel(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) &&
       (v0 == SP || v1 == SP) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_label := v2.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(1, 0, 0, sa_shift, abs12(sa_label), sa_xn_sp, sa_xd_sp)
        })
    }
    // ADD  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(0, 0, 0, sa_shift, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // ADD  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(1, 0, 0, sa_shift, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // ADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 16, sa_vn, sa_vd))
    }
    // ADD  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for ADD")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 16, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ADD")
}

// ADDG instruction have one single form across one single category:
//
// 1. Add with Tag
//
//    ADDG  <Xd|SP>, <Xn|SP>, #<uimm6>, #<uimm4>
//
// Add with Tag adds an immediate value scaled by the Tag granule to the address in
// the source register, modifies the Logical Address Tag of the address using an
// immediate value, and writes the result to the destination register. Tags
// specified in GCR_EL1.Exclude are excluded from the possible outputs when
// modifying the Logical Address Tag.
//
func (self *Program) ADDG(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("ADDG", 4, asm.Operands { v0, v1, v2, v3 })
    if isXrOrSP(v0) &&
       isXrOrSP(v1) &&
       isInRange(v2, 0, 1008) && isMultipleOf(v2, 16) &&
       isInRange(v3, 0, 15) &&
       (v0 == SP || v1 == SP) {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_uimm6 := asUimm6(v2)
        sa_uimm4 := asUimm4(v3)
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rd := uint32(0b00000)
        Rd |= sa_xd_sp
        return p.setins(addsub_immtags(1, 0, 0, sa_uimm6, 0, sa_uimm4, Rn, Rd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ADDG")
}

// ADDHN instruction have one single form across one single category:
//
// 1. Add returning High Narrow
//
//    ADDHN  <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>
//
// Add returning High Narrow. This instruction adds each vector element in the
// first source SIMD&FP register to the corresponding vector element in the second
// source SIMD&FP register, places the most significant half of the result into a
// vector, and writes the vector to the lower or upper half of the destination
// SIMD&FP register.
//
// The results are truncated. For rounded results, see RADDHN .
//
// The ADDHN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the ADDHN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ADDHN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ADDHN", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8H, Vec4S, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for ADDHN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for ADDHN")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 4, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ADDHN")
}

// ADDHN2 instruction have one single form across one single category:
//
// 1. Add returning High Narrow
//
//    ADDHN2  <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>
//
// Add returning High Narrow. This instruction adds each vector element in the
// first source SIMD&FP register to the corresponding vector element in the second
// source SIMD&FP register, places the most significant half of the result into a
// vector, and writes the vector to the lower or upper half of the destination
// SIMD&FP register.
//
// The results are truncated. For rounded results, see RADDHN .
//
// The ADDHN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the ADDHN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ADDHN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ADDHN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8H, Vec4S, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for ADDHN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for ADDHN2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 4, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ADDHN2")
}

// ADDP instruction have 2 forms across 2 categories:
//
// 1. Add Pair of elements (scalar)
//
//    ADDP  <V><d>, <Vn>.<T>
//
// Add Pair of elements (scalar). This instruction adds two vector elements in the
// source SIMD&FP register and writes the scalar result into the destination
// SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Add Pairwise (vector)
//
//    ADDP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Add Pairwise (vector). This instruction creates a vector by concatenating the
// vector elements of the first source SIMD&FP register after the vector elements
// of the second source SIMD&FP register, reads each pair of adjacent vector
// elements from the concatenated vector, adds each pair of values together, places
// the result into a vector, and writes the vector to the destination SIMD&FP
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ADDP(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("ADDP", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("ADDP", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction ADDP takes 2 or 3 operands")
    }
    // ADDP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec2D {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for ADDP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        if sa_t != sa_v {
            panic("aarch64: invalid combination of operands for ADDP")
        }
        return p.setins(asisdpair(0, sa_t, 27, sa_vn, sa_d))
    }
    // ADDP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 23, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ADDP")
}

// ADDS instruction have 8 forms across 3 categories:
//
// 1. Add (extended register), setting flags
//
//    ADDS  <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
//    ADDS  <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}
//
// Add (extended register), setting flags, adds a register value and a sign or
// zero-extended register value, followed by an optional left shift amount, and
// writes the result to the destination register. The argument that is extended
// from the <Rm> register can be a byte, halfword, word, or doubleword. It updates
// the condition flags based on the result.
//
// 2. Add (immediate), setting flags
//
//    ADDS  <Wd>, <Wn|WSP>, #<imm>{, <shift>}
//    ADDS  <Wd>, <Wn|WSP>, <label>{, <shift>}
//    ADDS  <Xd>, <Xn|SP>, #<imm>{, <shift>}
//    ADDS  <Xd>, <Xn|SP>, <label>{, <shift>}
//
// Add (immediate), setting flags, adds a register value and an optionally-shifted
// immediate value, and writes the result to the destination register. It updates
// the condition flags based on the result.
//
// 3. Add (shifted register), setting flags
//
//    ADDS  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    ADDS  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Add (shifted register), setting flags, adds a register value and an optionally-
// shifted register value, and writes the result to the destination register. It
// updates the condition flags based on the result.
//
func (self *Program) ADDS(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("ADDS", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("ADDS", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction ADDS takes 3 or 4 operands")
    }
    // ADDS  <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWrOrWSP(v1) &&
       isWr(v2) &&
       (len(vv) == 0 && v1 == WSP || len(vv) == 1 && modt(vv[0]) == ModUXTW) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend := uint32(0b010)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend = 0b000
                case ModUXTH: sa_extend = 0b001
                case ModLSL: sa_extend = 0b010
                case ModUXTW: sa_extend = 0b010
                case ModUXTX: sa_extend = 0b011
                case ModSXTB: sa_extend = 0b100
                case ModSXTH: sa_extend = 0b101
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_ext(0, 0, 1, 0, sa_wm, sa_extend, sa_amount, sa_wn_wsp, sa_wd))
    }
    // ADDS  <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXrOrSP(v1) &&
       isWrOrXr(v2) &&
       (len(vv) == 0 && v1 == SP || len(vv) == 1 && modt(vv[0]) == ModUXTX) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend_1 := uint32(0b011)
        var sa_r [4]uint32
        var sa_r__bit_mask [4]uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        switch true {
            case isWr(v2): sa_r = [4]uint32{0b000, 0b010, 0b100, 0b110}
            case isXr(v2): sa_r = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        switch true {
            case isWr(v2): sa_r__bit_mask = [4]uint32{0b110, 0b111, 0b110, 0b111}
            case isXr(v2): sa_r__bit_mask = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend_1 = 0b000
                case ModUXTH: sa_extend_1 = 0b001
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModUXTX: sa_extend_1 = 0b011
                case ModSXTB: sa_extend_1 = 0b100
                case ModSXTH: sa_extend_1 = 0b101
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        if !matchany(sa_extend_1, &sa_r[0], &sa_r__bit_mask[0], 4) {
            panic("aarch64: invalid combination of operands for ADDS")
        }
        return p.setins(addsub_ext(1, 0, 1, 0, sa_m, sa_extend_1, sa_amount, sa_xn_sp, sa_xd))
    }
    // ADDS  <Wd>, <Wn|WSP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWrOrWSP(v1) &&
       isInRange(v2, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_imm := asImm12(v2)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(0, 0, 1, sa_shift, sa_imm, sa_wn_wsp, sa_wd))
    }
    // ADDS  <Wd>, <Wn|WSP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWrOrWSP(v1) &&
       isLabel(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_label := v2.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(0, 0, 1, sa_shift, abs12(sa_label), sa_wn_wsp, sa_wd)
        })
    }
    // ADDS  <Xd>, <Xn|SP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXrOrSP(v1) &&
       isInRange(v2, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_imm := asImm12(v2)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(1, 0, 1, sa_shift, sa_imm, sa_xn_sp, sa_xd))
    }
    // ADDS  <Xd>, <Xn|SP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXrOrSP(v1) &&
       isLabel(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_label := v2.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(1, 0, 1, sa_shift, abs12(sa_label), sa_xn_sp, sa_xd)
        })
    }
    // ADDS  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(0, 0, 1, sa_shift, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // ADDS  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(1, 0, 1, sa_shift, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ADDS")
}

// ADDV instruction have one single form across one single category:
//
// 1. Add across Vector
//
//    ADDV  <V><d>, <Vn>.<T>
//
// Add across Vector. This instruction adds every vector element in the source
// SIMD&FP register together, and writes the scalar result to the destination
// SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ADDV(v0, v1 interface{}) *Instruction {
    p := self.alloc("ADDV", 2, asm.Operands { v0, v1 })
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for ADDV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_t, 1, 2) != sa_v {
            panic("aarch64: invalid combination of operands for ADDV")
        }
        return p.setins(asimdall(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 27, sa_vn, sa_d))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ADDV")
}

// ADR instruction have 2 forms across one single category:
//
// 1. Form PC-relative address
//
//    ADR  <Xd>, <label>
//    ADR  <Xd>, .±<offs>
//
// Form PC-relative address adds an immediate value to the PC value to form a PC-
// relative address, and writes the result to the destination register.
//
func (self *Program) ADR(v0, v1 interface{}) *Instruction {
    p := self.alloc("ADR", 2, asm.Operands { v0, v1 })
    // ADR  <Xd>, <label>
    if isXr(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            ra_refs := adroffs(sa_label, pc, false)
            return pcreladdr(0, mask(ra_refs, 2), ubfx(ra_refs, 2, 19), sa_xd)
        })
    }
    // ADR  <Xd>, .±<offs>
    if isXr(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        ra_refs := adrrel(ra_pcrel, false)
        return p.setins(pcreladdr(0, mask(ra_refs, 2), ubfx(ra_refs, 2, 19), sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ADR")
}

// ADRP instruction have 2 forms across one single category:
//
// 1. Form PC-relative address to 4KB page
//
//    ADRP  <Xd>, <label>
//    ADRP  <Xd>, .±<offs>
//
// Form PC-relative address to 4KB page adds an immediate value that is shifted
// left by 12 bits, to the PC value to form a PC-relative address, with the bottom
// 12 bits masked out, and writes the result to the destination register.
//
func (self *Program) ADRP(v0, v1 interface{}) *Instruction {
    p := self.alloc("ADRP", 2, asm.Operands { v0, v1 })
    // ADRP  <Xd>, <label>
    if isXr(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            ra_refs := adroffs(sa_label, pc, true)
            return pcreladdr(1, mask(ra_refs, 2), ubfx(ra_refs, 2, 19), sa_xd)
        })
    }
    // ADRP  <Xd>, .±<offs>
    if isXr(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        ra_refs := adrrel(ra_pcrel, true)
        return p.setins(pcreladdr(1, mask(ra_refs, 2), ubfx(ra_refs, 2, 19), sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ADRP")
}

// AESD instruction have one single form across one single category:
//
// 1. AES single round decryption
//
//    AESD  <Vd>.16B, <Vn>.16B
//
// AES single round decryption.
//
func (self *Program) AESD(v0, v1 interface{}) *Instruction {
    p := self.alloc("AESD", 2, asm.Operands { v0, v1 })
    if isVr(v0) && vfmt(v0) == Vec16B && isVr(v1) && vfmt(v1) == Vec16B {
        self.Arch.Require(FEAT_AES)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(cryptoaes(0, 5, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AESD")
}

// AESE instruction have one single form across one single category:
//
// 1. AES single round encryption
//
//    AESE  <Vd>.16B, <Vn>.16B
//
// AES single round encryption.
//
func (self *Program) AESE(v0, v1 interface{}) *Instruction {
    p := self.alloc("AESE", 2, asm.Operands { v0, v1 })
    if isVr(v0) && vfmt(v0) == Vec16B && isVr(v1) && vfmt(v1) == Vec16B {
        self.Arch.Require(FEAT_AES)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(cryptoaes(0, 4, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AESE")
}

// AESIMC instruction have one single form across one single category:
//
// 1. AES inverse mix columns
//
//    AESIMC  <Vd>.16B, <Vn>.16B
//
// AES inverse mix columns.
//
func (self *Program) AESIMC(v0, v1 interface{}) *Instruction {
    p := self.alloc("AESIMC", 2, asm.Operands { v0, v1 })
    if isVr(v0) && vfmt(v0) == Vec16B && isVr(v1) && vfmt(v1) == Vec16B {
        self.Arch.Require(FEAT_AES)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(cryptoaes(0, 7, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AESIMC")
}

// AESMC instruction have one single form across one single category:
//
// 1. AES mix columns
//
//    AESMC  <Vd>.16B, <Vn>.16B
//
// AES mix columns.
//
func (self *Program) AESMC(v0, v1 interface{}) *Instruction {
    p := self.alloc("AESMC", 2, asm.Operands { v0, v1 })
    if isVr(v0) && vfmt(v0) == Vec16B && isVr(v1) && vfmt(v1) == Vec16B {
        self.Arch.Require(FEAT_AES)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(cryptoaes(0, 6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AESMC")
}

// AND instruction have 5 forms across 3 categories:
//
// 1. Bitwise AND (vector)
//
//    AND  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Bitwise AND (vector). This instruction performs a bitwise AND between the two
// source SIMD&FP registers, and writes the result to the destination SIMD&FP
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Bitwise AND (immediate)
//
//    AND  <Wd|WSP>, <Wn>, #<imm>
//    AND  <Xd|SP>, <Xn>, #<imm>
//
// Bitwise AND (immediate) performs a bitwise AND of a register value and an
// immediate value, and writes the result to the destination register.
//
// 3. Bitwise AND (shifted register)
//
//    AND  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    AND  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Bitwise AND (shifted register) performs a bitwise AND of a register value and an
// optionally-shifted register value, and writes the result to the destination
// register.
//
func (self *Program) AND(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("AND", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("AND", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction AND takes 3 or 4 operands")
    }
    // AND  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(sa_t, 0, 0, sa_vm, 3, sa_vn, sa_vd))
    }
    // AND  <Wd|WSP>, <Wn>, #<imm>
    if isWrOrWSP(v0) && isWr(v1) && isMask32(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_imm := asMaskOp(v2)
        return p.setins(log_imm(0, 0, 0, ubfx(sa_imm, 6, 6), mask(sa_imm, 6), sa_wn, sa_wd_wsp))
    }
    // AND  <Xd|SP>, <Xn>, #<imm>
    if isXrOrSP(v0) && isXr(v1) && isMask64(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_imm_1 := asMaskOp(v2)
        return p.setins(log_imm(1, 0, ubfx(sa_imm_1, 12, 1), ubfx(sa_imm_1, 6, 6), mask(sa_imm_1, 6), sa_xn, sa_xd_sp))
    }
    // AND  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 0, sa_shift, 0, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // AND  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 0, sa_shift, 0, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for AND")
}

// ANDS instruction have 4 forms across 2 categories:
//
// 1. Bitwise AND (immediate), setting flags
//
//    ANDS  <Wd>, <Wn>, #<imm>
//    ANDS  <Xd>, <Xn>, #<imm>
//
// Bitwise AND (immediate), setting flags, performs a bitwise AND of a register
// value and an immediate value, and writes the result to the destination register.
// It updates the condition flags based on the result.
//
// 2. Bitwise AND (shifted register), setting flags
//
//    ANDS  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    ANDS  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Bitwise AND (shifted register), setting flags, performs a bitwise AND of a
// register value and an optionally-shifted register value, and writes the result
// to the destination register. It updates the condition flags based on the result.
//
func (self *Program) ANDS(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("ANDS", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("ANDS", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction ANDS takes 3 or 4 operands")
    }
    // ANDS  <Wd>, <Wn>, #<imm>
    if isWr(v0) && isWr(v1) && isMask32(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_imm := asMaskOp(v2)
        return p.setins(log_imm(0, 3, 0, ubfx(sa_imm, 6, 6), mask(sa_imm, 6), sa_wn, sa_wd))
    }
    // ANDS  <Xd>, <Xn>, #<imm>
    if isXr(v0) && isXr(v1) && isMask64(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_imm_1 := asMaskOp(v2)
        return p.setins(log_imm(1, 3, ubfx(sa_imm_1, 12, 1), ubfx(sa_imm_1, 6, 6), mask(sa_imm_1, 6), sa_xn, sa_xd))
    }
    // ANDS  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 3, sa_shift, 0, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // ANDS  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 3, sa_shift, 0, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ANDS")
}

// ASR instruction have 4 forms across 2 categories:
//
// 1. Arithmetic Shift Right (register)
//
//    ASR  <Wd>, <Wn>, <Wm>
//    ASR  <Xd>, <Xn>, <Xm>
//
// Arithmetic Shift Right (register) shifts a register value right by a variable
// number of bits, shifting in copies of its sign bit, and writes the result to the
// destination register. The remainder obtained by dividing the second source
// register by the data size defines the number of bits by which the first source
// register is right-shifted.
//
// 2. Arithmetic Shift Right (immediate)
//
//    ASR  <Wd>, <Wn>, #<shift>
//    ASR  <Xd>, <Xn>, #<shift>
//
// Arithmetic Shift Right (immediate) shifts a register value right by an immediate
// number of bits, shifting in copies of the sign bit in the upper bits and zeros
// in the lower bits, and writes the result to the destination register.
//
func (self *Program) ASR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ASR", 3, asm.Operands { v0, v1, v2 })
    // ASR  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 10, sa_wn, sa_wd))
    }
    // ASR  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 10, sa_xn, sa_xd))
    }
    // ASR  <Wd>, <Wn>, #<shift>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_shift := asUimm6(v2)
        return p.setins(bitfield(0, 0, 0, sa_shift, 31, sa_wn, sa_wd))
    }
    // ASR  <Xd>, <Xn>, #<shift>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_shift_1 := asUimm6(v2)
        return p.setins(bitfield(1, 0, 1, sa_shift_1, 63, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ASR")
}

// ASRV instruction have 2 forms across one single category:
//
// 1. Arithmetic Shift Right Variable
//
//    ASRV  <Wd>, <Wn>, <Wm>
//    ASRV  <Xd>, <Xn>, <Xm>
//
// Arithmetic Shift Right Variable shifts a register value right by a variable
// number of bits, shifting in copies of its sign bit, and writes the result to the
// destination register. The remainder obtained by dividing the second source
// register by the data size defines the number of bits by which the first source
// register is right-shifted.
//
func (self *Program) ASRV(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ASRV", 3, asm.Operands { v0, v1, v2 })
    // ASRV  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 10, sa_wn, sa_wd))
    }
    // ASRV  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 10, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ASRV")
}

// AT instruction have one single form across one single category:
//
// 1. Address Translate
//
//    AT  <at_op>, <Xt>
//
// Address Translate. For more information, see op0==0b01, cache maintenance, TLB
// maintenance, and address translation instructions .
//
func (self *Program) AT(v0, v1 interface{}) *Instruction {
    p := self.alloc("AT", 2, asm.Operands { v0, v1 })
    if isATOption(v0) && isXr(v1) {
        p.Domain = DomainSystem
        sa_at_op := uint32(v0.(ATOption))
        sa_xt_1 := uint32(v1.(asm.Register).ID())
        return p.setins(systeminstrs(0, ubfx(sa_at_op, 7, 3), 7, ubfx(sa_at_op, 3, 4), mask(sa_at_op, 3), sa_xt_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AT")
}

// AUTDA instruction have one single form across one single category:
//
// 1. Authenticate Data address, using key A
//
//    AUTDA  <Xd>, <Xn|SP>
//
// Authenticate Data address, using key A. This instruction authenticates a data
// address, using a modifier and key A.
//
// The address is in the general-purpose register that is specified by <Xd> .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTDA .
//     * The value zero, for AUTDZA .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTDA(v0, v1 interface{}) *Instruction {
    p := self.alloc("AUTDA", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 6, sa_xn_sp, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AUTDA")
}

// AUTDB instruction have one single form across one single category:
//
// 1. Authenticate Data address, using key B
//
//    AUTDB  <Xd>, <Xn|SP>
//
// Authenticate Data address, using key B. This instruction authenticates a data
// address, using a modifier and key B.
//
// The address is in the general-purpose register that is specified by <Xd> .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTDB .
//     * The value zero, for AUTDZB .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTDB(v0, v1 interface{}) *Instruction {
    p := self.alloc("AUTDB", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 7, sa_xn_sp, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AUTDB")
}

// AUTDZA instruction have one single form across one single category:
//
// 1. Authenticate Data address, using key A
//
//    AUTDZA  <Xd>
//
// Authenticate Data address, using key A. This instruction authenticates a data
// address, using a modifier and key A.
//
// The address is in the general-purpose register that is specified by <Xd> .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTDA .
//     * The value zero, for AUTDZA .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTDZA(v0 interface{}) *Instruction {
    p := self.alloc("AUTDZA", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 14, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AUTDZA")
}

// AUTDZB instruction have one single form across one single category:
//
// 1. Authenticate Data address, using key B
//
//    AUTDZB  <Xd>
//
// Authenticate Data address, using key B. This instruction authenticates a data
// address, using a modifier and key B.
//
// The address is in the general-purpose register that is specified by <Xd> .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTDB .
//     * The value zero, for AUTDZB .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTDZB(v0 interface{}) *Instruction {
    p := self.alloc("AUTDZB", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 15, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AUTDZB")
}

// AUTIA instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key A
//
//    AUTIA  <Xd>, <Xn|SP>
//
// Authenticate Instruction address, using key A. This instruction authenticates an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIA
//       and AUTIZA .
//     * In X17, for AUTIA1716 .
//     * In X30, for AUTIASP and AUTIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIA .
//     * The value zero, for AUTIZA and AUTIAZ .
//     * In X16, for AUTIA1716 .
//     * In SP, for AUTIASP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIA(v0, v1 interface{}) *Instruction {
    p := self.alloc("AUTIA", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 4, sa_xn_sp, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AUTIA")
}

// AUTIA1716 instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key A
//
//    AUTIA1716
//
// Authenticate Instruction address, using key A. This instruction authenticates an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIA
//       and AUTIZA .
//     * In X17, for AUTIA1716 .
//     * In X30, for AUTIASP and AUTIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIA .
//     * The value zero, for AUTIZA and AUTIAZ .
//     * In X16, for AUTIA1716 .
//     * In SP, for AUTIASP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIA1716() *Instruction {
    p := self.alloc("AUTIA1716", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(1, 4))
}

// AUTIASP instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key A
//
//    AUTIASP
//
// Authenticate Instruction address, using key A. This instruction authenticates an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIA
//       and AUTIZA .
//     * In X17, for AUTIA1716 .
//     * In X30, for AUTIASP and AUTIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIA .
//     * The value zero, for AUTIZA and AUTIAZ .
//     * In X16, for AUTIA1716 .
//     * In SP, for AUTIASP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIASP() *Instruction {
    p := self.alloc("AUTIASP", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(3, 5))
}

// AUTIAZ instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key A
//
//    AUTIAZ
//
// Authenticate Instruction address, using key A. This instruction authenticates an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIA
//       and AUTIZA .
//     * In X17, for AUTIA1716 .
//     * In X30, for AUTIASP and AUTIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIA .
//     * The value zero, for AUTIZA and AUTIAZ .
//     * In X16, for AUTIA1716 .
//     * In SP, for AUTIASP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIAZ() *Instruction {
    p := self.alloc("AUTIAZ", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(3, 4))
}

// AUTIB instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key B
//
//    AUTIB  <Xd>, <Xn|SP>
//
// Authenticate Instruction address, using key B. This instruction authenticates an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIB
//       and AUTIZB .
//     * In X17, for AUTIB1716 .
//     * In X30, for AUTIBSP and AUTIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIB .
//     * The value zero, for AUTIZB and AUTIBZ .
//     * In X16, for AUTIB1716 .
//     * In SP, for AUTIBSP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIB(v0, v1 interface{}) *Instruction {
    p := self.alloc("AUTIB", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 5, sa_xn_sp, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AUTIB")
}

// AUTIB1716 instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key B
//
//    AUTIB1716
//
// Authenticate Instruction address, using key B. This instruction authenticates an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIB
//       and AUTIZB .
//     * In X17, for AUTIB1716 .
//     * In X30, for AUTIBSP and AUTIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIB .
//     * The value zero, for AUTIZB and AUTIBZ .
//     * In X16, for AUTIB1716 .
//     * In SP, for AUTIBSP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIB1716() *Instruction {
    p := self.alloc("AUTIB1716", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(1, 6))
}

// AUTIBSP instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key B
//
//    AUTIBSP
//
// Authenticate Instruction address, using key B. This instruction authenticates an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIB
//       and AUTIZB .
//     * In X17, for AUTIB1716 .
//     * In X30, for AUTIBSP and AUTIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIB .
//     * The value zero, for AUTIZB and AUTIBZ .
//     * In X16, for AUTIB1716 .
//     * In SP, for AUTIBSP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIBSP() *Instruction {
    p := self.alloc("AUTIBSP", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(3, 7))
}

// AUTIBZ instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key B
//
//    AUTIBZ
//
// Authenticate Instruction address, using key B. This instruction authenticates an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIB
//       and AUTIZB .
//     * In X17, for AUTIB1716 .
//     * In X30, for AUTIBSP and AUTIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIB .
//     * The value zero, for AUTIZB and AUTIBZ .
//     * In X16, for AUTIB1716 .
//     * In SP, for AUTIBSP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIBZ() *Instruction {
    p := self.alloc("AUTIBZ", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(3, 6))
}

// AUTIZA instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key A
//
//    AUTIZA  <Xd>
//
// Authenticate Instruction address, using key A. This instruction authenticates an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIA
//       and AUTIZA .
//     * In X17, for AUTIA1716 .
//     * In X30, for AUTIASP and AUTIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIA .
//     * The value zero, for AUTIZA and AUTIAZ .
//     * In X16, for AUTIA1716 .
//     * In SP, for AUTIASP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIZA(v0 interface{}) *Instruction {
    p := self.alloc("AUTIZA", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 12, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AUTIZA")
}

// AUTIZB instruction have one single form across one single category:
//
// 1. Authenticate Instruction address, using key B
//
//    AUTIZB  <Xd>
//
// Authenticate Instruction address, using key B. This instruction authenticates an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for AUTIB
//       and AUTIZB .
//     * In X17, for AUTIB1716 .
//     * In X30, for AUTIBSP and AUTIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for AUTIB .
//     * The value zero, for AUTIZB and AUTIBZ .
//     * In X16, for AUTIB1716 .
//     * In SP, for AUTIBSP .
//
// If the authentication passes, the upper bits of the address are restored to
// enable subsequent use of the address. For information on behavior if the
// authentication fails, see Faulting on pointer authentication .
//
func (self *Program) AUTIZB(v0 interface{}) *Instruction {
    p := self.alloc("AUTIZB", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 13, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for AUTIZB")
}

// AXFLAG instruction have one single form across one single category:
//
// 1. Convert floating-point condition flags from Arm to external format
//
//    AXFLAG
//
// Convert floating-point condition flags from Arm to external format. This
// instruction converts the state of the PSTATE.{N,Z,C,V} flags from a form
// representing the result of an Arm floating-point scalar compare instruction to
// an alternative representation required by some software.
//
func (self *Program) AXFLAG() *Instruction {
    p := self.alloc("AXFLAG", 0, asm.Operands {})
    self.Arch.Require(FEAT_FlagM2)
    p.Domain = DomainSystem
    return p.setins(pstate(0, 0, 2, 31))
}

// B instruction have 2 forms across one single category:
//
// 1. Branch
//
//    B  <label>
//    B  .±<offs>
//
// Branch causes an unconditional branch to a label at a PC-relative offset, with a
// hint that this is not a subroutine call or return.
//
func (self *Program) B(v0 interface{}) *Instruction {
    p := self.alloc("B", 1, asm.Operands { v0 })
    // B  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return branch_imm(0, pcrel26(sa_label, pc))
        })
    }
    // B  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(branch_imm(0, rel26(ra_pcrel)))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for B")
}

// BEQ instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.eq  <label>
//    B.eq  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BEQ(v0 interface{}) *Instruction {
    p := self.alloc("BEQ", 1, asm.Operands { v0 })
    // B.eq  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 0)
        })
    }
    // B.eq  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 0))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BEQ")
}

// BNE instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.ne  <label>
//    B.ne  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BNE(v0 interface{}) *Instruction {
    p := self.alloc("BNE", 1, asm.Operands { v0 })
    // B.ne  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 1)
        })
    }
    // B.ne  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BNE")
}

// BCS instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.cs  <label>
//    B.cs  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BCS(v0 interface{}) *Instruction {
    p := self.alloc("BCS", 1, asm.Operands { v0 })
    // B.cs  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 2)
        })
    }
    // B.cs  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 2))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCS")
}

// BHS instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.hs  <label>
//    B.hs  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BHS(v0 interface{}) *Instruction {
    p := self.alloc("BHS", 1, asm.Operands { v0 })
    // B.hs  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 2)
        })
    }
    // B.hs  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 2))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BHS")
}

// BCC instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.cc  <label>
//    B.cc  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BCC(v0 interface{}) *Instruction {
    p := self.alloc("BCC", 1, asm.Operands { v0 })
    // B.cc  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 3)
        })
    }
    // B.cc  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 3))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCC")
}

// BLO instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.lo  <label>
//    B.lo  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BLO(v0 interface{}) *Instruction {
    p := self.alloc("BLO", 1, asm.Operands { v0 })
    // B.lo  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 3)
        })
    }
    // B.lo  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 3))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BLO")
}

// BMI instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.mi  <label>
//    B.mi  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BMI(v0 interface{}) *Instruction {
    p := self.alloc("BMI", 1, asm.Operands { v0 })
    // B.mi  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 4)
        })
    }
    // B.mi  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 4))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BMI")
}

// BPL instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.pl  <label>
//    B.pl  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BPL(v0 interface{}) *Instruction {
    p := self.alloc("BPL", 1, asm.Operands { v0 })
    // B.pl  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 5)
        })
    }
    // B.pl  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 5))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BPL")
}

// BVS instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.vs  <label>
//    B.vs  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BVS(v0 interface{}) *Instruction {
    p := self.alloc("BVS", 1, asm.Operands { v0 })
    // B.vs  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 6)
        })
    }
    // B.vs  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 6))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BVS")
}

// BVC instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.vc  <label>
//    B.vc  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BVC(v0 interface{}) *Instruction {
    p := self.alloc("BVC", 1, asm.Operands { v0 })
    // B.vc  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 7)
        })
    }
    // B.vc  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 7))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BVC")
}

// BHI instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.hi  <label>
//    B.hi  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BHI(v0 interface{}) *Instruction {
    p := self.alloc("BHI", 1, asm.Operands { v0 })
    // B.hi  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 8)
        })
    }
    // B.hi  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 8))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BHI")
}

// BLS instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.ls  <label>
//    B.ls  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BLS(v0 interface{}) *Instruction {
    p := self.alloc("BLS", 1, asm.Operands { v0 })
    // B.ls  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 9)
        })
    }
    // B.ls  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 9))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BLS")
}

// BGE instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.ge  <label>
//    B.ge  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BGE(v0 interface{}) *Instruction {
    p := self.alloc("BGE", 1, asm.Operands { v0 })
    // B.ge  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 10)
        })
    }
    // B.ge  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 10))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BGE")
}

// BLT instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.lt  <label>
//    B.lt  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BLT(v0 interface{}) *Instruction {
    p := self.alloc("BLT", 1, asm.Operands { v0 })
    // B.lt  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 11)
        })
    }
    // B.lt  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 11))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BLT")
}

// BGT instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.gt  <label>
//    B.gt  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BGT(v0 interface{}) *Instruction {
    p := self.alloc("BGT", 1, asm.Operands { v0 })
    // B.gt  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 12)
        })
    }
    // B.gt  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 12))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BGT")
}

// BLE instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.le  <label>
//    B.le  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BLE(v0 interface{}) *Instruction {
    p := self.alloc("BLE", 1, asm.Operands { v0 })
    // B.le  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 13)
        })
    }
    // B.le  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 13))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BLE")
}

// BAL instruction have 2 forms across one single category:
//
// 1. Branch conditionally
//
//    B.al  <label>
//    B.al  .±<offs>
//
// Branch conditionally to a label at a PC-relative offset, with a hint that this
// is not a subroutine call or return.
//
func (self *Program) BAL(v0 interface{}) *Instruction {
    p := self.alloc("BAL", 1, asm.Operands { v0 })
    // B.al  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 0, 14)
        })
    }
    // B.al  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 0, 14))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BAL")
}

// BCEQ instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.eq  <label>
//    BC.eq  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCEQ(v0 interface{}) *Instruction {
    p := self.alloc("BCEQ", 1, asm.Operands { v0 })
    // BC.eq  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 0)
        })
    }
    // BC.eq  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 0))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCEQ")
}

// BCNE instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.ne  <label>
//    BC.ne  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCNE(v0 interface{}) *Instruction {
    p := self.alloc("BCNE", 1, asm.Operands { v0 })
    // BC.ne  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 1)
        })
    }
    // BC.ne  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCNE")
}

// BCCS instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.cs  <label>
//    BC.cs  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCCS(v0 interface{}) *Instruction {
    p := self.alloc("BCCS", 1, asm.Operands { v0 })
    // BC.cs  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 2)
        })
    }
    // BC.cs  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 2))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCCS")
}

// BCHS instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.hs  <label>
//    BC.hs  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCHS(v0 interface{}) *Instruction {
    p := self.alloc("BCHS", 1, asm.Operands { v0 })
    // BC.hs  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 2)
        })
    }
    // BC.hs  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 2))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCHS")
}

// BCCC instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.cc  <label>
//    BC.cc  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCCC(v0 interface{}) *Instruction {
    p := self.alloc("BCCC", 1, asm.Operands { v0 })
    // BC.cc  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 3)
        })
    }
    // BC.cc  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 3))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCCC")
}

// BCLO instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.lo  <label>
//    BC.lo  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCLO(v0 interface{}) *Instruction {
    p := self.alloc("BCLO", 1, asm.Operands { v0 })
    // BC.lo  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 3)
        })
    }
    // BC.lo  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 3))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCLO")
}

// BCMI instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.mi  <label>
//    BC.mi  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCMI(v0 interface{}) *Instruction {
    p := self.alloc("BCMI", 1, asm.Operands { v0 })
    // BC.mi  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 4)
        })
    }
    // BC.mi  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 4))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCMI")
}

// BCPL instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.pl  <label>
//    BC.pl  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCPL(v0 interface{}) *Instruction {
    p := self.alloc("BCPL", 1, asm.Operands { v0 })
    // BC.pl  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 5)
        })
    }
    // BC.pl  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 5))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCPL")
}

// BCVS instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.vs  <label>
//    BC.vs  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCVS(v0 interface{}) *Instruction {
    p := self.alloc("BCVS", 1, asm.Operands { v0 })
    // BC.vs  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 6)
        })
    }
    // BC.vs  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 6))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCVS")
}

// BCVC instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.vc  <label>
//    BC.vc  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCVC(v0 interface{}) *Instruction {
    p := self.alloc("BCVC", 1, asm.Operands { v0 })
    // BC.vc  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 7)
        })
    }
    // BC.vc  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 7))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCVC")
}

// BCHI instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.hi  <label>
//    BC.hi  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCHI(v0 interface{}) *Instruction {
    p := self.alloc("BCHI", 1, asm.Operands { v0 })
    // BC.hi  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 8)
        })
    }
    // BC.hi  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 8))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCHI")
}

// BCLS instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.ls  <label>
//    BC.ls  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCLS(v0 interface{}) *Instruction {
    p := self.alloc("BCLS", 1, asm.Operands { v0 })
    // BC.ls  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 9)
        })
    }
    // BC.ls  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 9))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCLS")
}

// BCGE instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.ge  <label>
//    BC.ge  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCGE(v0 interface{}) *Instruction {
    p := self.alloc("BCGE", 1, asm.Operands { v0 })
    // BC.ge  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 10)
        })
    }
    // BC.ge  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 10))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCGE")
}

// BCLT instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.lt  <label>
//    BC.lt  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCLT(v0 interface{}) *Instruction {
    p := self.alloc("BCLT", 1, asm.Operands { v0 })
    // BC.lt  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 11)
        })
    }
    // BC.lt  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 11))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCLT")
}

// BCGT instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.gt  <label>
//    BC.gt  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCGT(v0 interface{}) *Instruction {
    p := self.alloc("BCGT", 1, asm.Operands { v0 })
    // BC.gt  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 12)
        })
    }
    // BC.gt  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 12))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCGT")
}

// BCLE instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.le  <label>
//    BC.le  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCLE(v0 interface{}) *Instruction {
    p := self.alloc("BCLE", 1, asm.Operands { v0 })
    // BC.le  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 13)
        })
    }
    // BC.le  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 13))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCLE")
}

// BCAL instruction have 2 forms across one single category:
//
// 1. Branch Consistent conditionally
//
//    BC.al  <label>
//    BC.al  .±<offs>
//
// Branch Consistent conditionally to a label at a PC-relative offset, with a hint
// that this branch will behave very consistently and is very unlikely to change
// direction.
//
func (self *Program) BCAL(v0 interface{}) *Instruction {
    p := self.alloc("BCAL", 1, asm.Operands { v0 })
    // BC.al  <label>
    if isLabel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return condbranch(0, pcrel19(sa_label, pc), 1, 14)
        })
    }
    // BC.al  .±<offs>
    if isPCrel(v0) {
        self.Arch.Require(FEAT_HBC)
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(condbranch(0, rel19(ra_pcrel), 1, 14))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BCAL")
}

// BCAX instruction have one single form across one single category:
//
// 1. Bit Clear and exclusive-OR
//
//    BCAX  <Vd>.16B, <Vn>.16B, <Vm>.16B, <Va>.16B
//
// Bit Clear and exclusive-OR performs a bitwise AND of the 128-bit vector in a
// source SIMD&FP register and the complement of the vector in another source
// SIMD&FP register, then performs a bitwise exclusive-OR of the resulting vector
// and the vector in a third source SIMD&FP register, and writes the result to the
// destination SIMD&FP register.
//
// This instruction is implemented only when FEAT_SHA3 is implemented.
//
func (self *Program) BCAX(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("BCAX", 4, asm.Operands { v0, v1, v2, v3 })
    if isVr(v0) &&
       vfmt(v0) == Vec16B &&
       isVr(v1) &&
       vfmt(v1) == Vec16B &&
       isVr(v2) &&
       vfmt(v2) == Vec16B &&
       isVr(v3) &&
       vfmt(v3) == Vec16B {
        self.Arch.Require(FEAT_SHA3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        sa_va := uint32(v3.(asm.Register).ID())
        return p.setins(crypto4(1, sa_vm, sa_va, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BCAX")
}

// BFC instruction have 2 forms across one single category:
//
// 1. Bitfield Clear
//
//    BFC  <Wd>, #<lsb>, #<width>
//    BFC  <Xd>, #<lsb>, #<width>
//
// Bitfield Clear sets a bitfield of <width> bits at bit position <lsb> of the
// destination register to zero, leaving the other destination bits unchanged.
//
func (self *Program) BFC(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("BFC", 3, asm.Operands { v0, v1, v2 })
    // BFC  <Wd>, #<lsb>, #<width>
    if isWr(v0) && isInRange(v1, 0, 31) && isBFxWidth(v1, v2, 32) {
        self.Arch.Require(FEAT_ASMv8p2)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_lsb := -asUimm5(v1) % 32
        sa_width := asUimm5(v2) - 1
        return p.setins(bitfield(0, 1, 0, sa_lsb, sa_width, 31, sa_wd))
    }
    // BFC  <Xd>, #<lsb>, #<width>
    if isXr(v0) && isInRange(v1, 0, 63) && isBFxWidth(v1, v2, 64) {
        self.Arch.Require(FEAT_ASMv8p2)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_lsb_2 := -asUimm6(v1) % 64
        sa_width_1 := asUimm6(v2) - 1
        return p.setins(bitfield(1, 1, 1, sa_lsb_2, sa_width_1, 31, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BFC")
}

// BFCVT instruction have one single form across one single category:
//
// 1. Floating-point convert from single-precision to BFloat16 format (scalar)
//
//    BFCVT  <Hd>, <Sn>
//
// Floating-point convert from single-precision to BFloat16 format (scalar)
// converts the single-precision floating-point value in the 32-bit SIMD&FP source
// register to BFloat16 format and writes the result in the 16-bit SIMD&FP
// destination register.
//
// ID_AA64ISAR1_EL1 .BF16 indicates whether this instruction is supported.
//
func (self *Program) BFCVT(v0, v1 interface{}) *Instruction {
    p := self.alloc("BFCVT", 2, asm.Operands { v0, v1 })
    if isHr(v0) && isSr(v1) {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 6, sa_sn, sa_hd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BFCVT")
}

// BFCVTN instruction have one single form across one single category:
//
// 1. Floating-point convert from single-precision to BFloat16 format (vector)
//
//    BFCVTN  <Vd>.<Ta>, <Vn>.4S
//
// Floating-point convert from single-precision to BFloat16 format (vector) reads
// each single-precision element in the SIMD&FP source vector, converts each value
// to BFloat16 format, and writes the results in the lower or upper half of the
// SIMD&FP destination vector. The result elements are half the width of the source
// elements.
//
// The BFCVTN instruction writes the half-width results to the lower half of the
// destination vector and clears the upper half to zero, while the BFCVTN2
// instruction writes the results to the upper half of the destination vector
// without affecting the other bits in the register.
//
func (self *Program) BFCVTN(v0, v1 interface{}) *Instruction {
    p := self.alloc("BFCVTN", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && vfmt(v1) == Vec4S {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_ta = 0b0
            case Vec8H: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        if sa_ta != 0 {
            panic("aarch64: invalid combination of operands for BFCVTN")
        }
        return p.setins(asimdmisc(0, 0, 2, 22, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BFCVTN")
}

// BFCVTN2 instruction have one single form across one single category:
//
// 1. Floating-point convert from single-precision to BFloat16 format (vector)
//
//    BFCVTN2  <Vd>.<Ta>, <Vn>.4S
//
// Floating-point convert from single-precision to BFloat16 format (vector) reads
// each single-precision element in the SIMD&FP source vector, converts each value
// to BFloat16 format, and writes the results in the lower or upper half of the
// SIMD&FP destination vector. The result elements are half the width of the source
// elements.
//
// The BFCVTN instruction writes the half-width results to the lower half of the
// destination vector and clears the upper half to zero, while the BFCVTN2
// instruction writes the results to the upper half of the destination vector
// without affecting the other bits in the register.
//
func (self *Program) BFCVTN2(v0, v1 interface{}) *Instruction {
    p := self.alloc("BFCVTN2", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && vfmt(v1) == Vec4S {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_ta = 0b0
            case Vec8H: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        if sa_ta != 1 {
            panic("aarch64: invalid combination of operands for BFCVTN2")
        }
        return p.setins(asimdmisc(1, 0, 2, 22, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BFCVTN2")
}

// BFDOT instruction have 2 forms across 2 categories:
//
// 1. BFloat16 floating-point dot product (vector, by element)
//
//    BFDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.2H[<index>]
//
// BFloat16 floating-point dot product (vector, by element). This instruction
// delimits the source vectors into pairs of BFloat16 elements. The BFloat16 pair
// within the second source vector is specified using an immediate index. The index
// range is from 0 to 3 inclusive.
//
// If FEAT_EBF16 is not implemented or FPCR .EBF is 0, this instruction:
//
//     * Performs an unfused sum-of-products of each pair of adjacent BFloat16
//       elements in the first source vector with the specified pair of
//       elements in the second source vector. The intermediate single-
//       precision products are rounded before they are summed, and the
//       intermediate sum is rounded before accumulation into the single-
//       precision destination element that overlaps with the corresponding
//       pair of BFloat16 elements in the first source vector.
//     * Uses the non-IEEE 754 Round-to-Odd rounding mode, which forces bit 0
//       of an inexact result to 1, and rounds an overflow to an appropriately
//       signed Infinity.
//     * Flushes denormalized inputs and results to zero, as if FPCR .{FZ, FIZ}
//       is {1, 1}.
//     * Disables alternative floating point behaviors, as if FPCR .AH is 0.
//
// If FEAT_EBF16 is implemented and FPCR .EBF is 1, then this instruction:
//
//     * Performs a fused sum-of-products of each pair of adjacent BFloat16
//       elements in the first source vector with the specified pair of
//       elements in the second source vector. The intermediate single-
//       precision products are not rounded before they are summed, but the
//       intermediate sum is rounded before accumulation into the single-
//       precision destination element that overlaps with the corresponding
//       pair of BFloat16 elements in the first source vector.
//     * Follows all other floating-point behaviors that apply to single-
//       precision arithmetic, as governed by FPCR .RMode, FPCR .FZ, FPCR .AH,
//       and FPCR .FIZ.
//
// Irrespective of FEAT_EBF16 and FPCR .EBF, this instruction:
//
//     * Does not modify the cumulative FPSR exception bits (IDC, IXC, UFC,
//       OFC, DZC, and IOC).
//     * Disables trapped floating-point exceptions, as if the FPCR trap enable
//       bits (IDE, IXE, UFE, OFE, DZE, and IOE) are all zero.
//     * Generates only the default NaN, as if FPCR .DN is 1.
//
// ID_AA64ISAR1_EL1 .BF16 indicates whether this instruction is supported.
//
// 2. BFloat16 floating-point dot product (vector)
//
//    BFDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// BFloat16 floating-point dot product (vector). This instruction delimits the
// source vectors into pairs of BFloat16 elements.
//
// If FEAT_EBF16 is not implemented or FPCR .EBF is 0, this instruction:
//
//     * Performs an unfused sum-of-products of each pair of adjacent BFloat16
//       elements in the source vectors. The intermediate single-precision
//       products are rounded before they are summed, and the intermediate sum
//       is rounded before accumulation into the single-precision destination
//       element that overlaps with the corresponding pair of BFloat16 elements
//       in the source vectors.
//     * Uses the non-IEEE 754 Round-to-Odd rounding mode, which forces bit 0
//       of an inexact result to 1, and rounds an overflow to an appropriately
//       signed Infinity.
//     * Flushes denormalized inputs and results to zero, as if FPCR .{FZ, FIZ}
//       is {1, 1}.
//     * Disables alternative floating point behaviors, as if FPCR .AH is 0.
//
// If FEAT_EBF16 is implemented and FPCR .EBF is 1, then this instruction:
//
//     * Performs a fused sum-of-products of each pair of adjacent BFloat16
//       elements in the source vectors. The intermediate single-precision
//       products are not rounded before they are summed, but the intermediate
//       sum is rounded before accumulation into the single-precision
//       destination element that overlaps with the corresponding pair of
//       BFloat16 elements in the source vectors.
//     * Follows all other floating-point behaviors that apply to single-
//       precision arithmetic, as governed by FPCR .RMode, FPCR .FZ, FPCR .AH,
//       and FPCR .FIZ.
//
// Irrespective of FEAT_EBF16 and FPCR .EBF, this instruction:
//
//     * Does not modify the cumulative FPSR exception bits (IDC, IXC, UFC,
//       OFC, DZC, and IOC).
//     * Disables trapped floating-point exceptions, as if the FPCR trap enable
//       bits (IDE, IXE, UFE, OFE, DZE, and IOE) are all zero.
//     * Generates only the default NaN, as if FPCR .DN is 1.
//
// ID_AA64ISAR1_EL1 .BF16 indicates whether this instruction is supported.
//
func (self *Program) BFDOT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("BFDOT", 3, asm.Operands { v0, v1, v2 })
    // BFDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.2H[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVri(v2) &&
       vmoder(v2) == Mode2H {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b0
            case Vec8H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for BFDOT")
        }
        return p.setins(asimdelem(
            sa_ta,
            0,
            1,
            mask(sa_index, 1),
            ubfx(sa_vm, 4, 1),
            mask(sa_vm, 4),
            15,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // BFDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b0
            case Vec8H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for BFDOT")
        }
        return p.setins(asimdsame2(sa_ta, 1, 1, sa_vm, 15, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BFDOT")
}

// BFI instruction have 2 forms across one single category:
//
// 1. Bitfield Insert
//
//    BFI  <Wd>, <Wn>, #<lsb>, #<width>
//    BFI  <Xd>, <Xn>, #<lsb>, #<width>
//
// Bitfield Insert copies a bitfield of <width> bits from the least significant
// bits of the source register to bit position <lsb> of the destination register,
// leaving the other destination bits unchanged.
//
func (self *Program) BFI(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("BFI", 4, asm.Operands { v0, v1, v2, v3 })
    // BFI  <Wd>, <Wn>, #<lsb>, #<width>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) && isBFxWidth(v2, v3, 32) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_lsb := -asUimm5(v2) % 32
        sa_width := asUimm5(v3) - 1
        return p.setins(bitfield(0, 1, 0, sa_lsb, sa_width, sa_wn, sa_wd))
    }
    // BFI  <Xd>, <Xn>, #<lsb>, #<width>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) && isBFxWidth(v2, v3, 64) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_lsb_2 := -asUimm6(v2) % 64
        sa_width_1 := asUimm6(v3) - 1
        return p.setins(bitfield(1, 1, 1, sa_lsb_2, sa_width_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BFI")
}

// BFM instruction have 2 forms across one single category:
//
// 1. Bitfield Move
//
//    BFM  <Wd>, <Wn>, #<immr>, #<imms>
//    BFM  <Xd>, <Xn>, #<immr>, #<imms>
//
// Bitfield Move is usually accessed via one of its aliases, which are always
// preferred for disassembly.
//
// If <imms> is greater than or equal to <immr> , this copies a bitfield of (
// <imms> - <immr> +1) bits starting from bit position <immr> in the source
// register to the least significant bits of the destination register.
//
// If <imms> is less than <immr> , this copies a bitfield of ( <imms> +1) bits from
// the least significant bits of the source register to bit position (regsize-
// <immr> ) of the destination register, where regsize is the destination register
// size of 32 or 64 bits.
//
// In both cases the other bits of the destination register remain unchanged.
//
func (self *Program) BFM(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("BFM", 4, asm.Operands { v0, v1, v2, v3 })
    // BFM  <Wd>, <Wn>, #<immr>, #<imms>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) && isInRange(v3, 0, 31) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_immr := asUimm6(v2)
        sa_imms := asUimm6(v3)
        return p.setins(bitfield(0, 1, 0, sa_immr, sa_imms, sa_wn, sa_wd))
    }
    // BFM  <Xd>, <Xn>, #<immr>, #<imms>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) && isInRange(v3, 0, 63) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_immr_1 := asUimm6(v2)
        sa_imms_1 := asUimm6(v3)
        return p.setins(bitfield(1, 1, 1, sa_immr_1, sa_imms_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BFM")
}

// BFMLALB instruction have 2 forms across 2 categories:
//
// 1. BFloat16 floating-point widening multiply-add long (by element)
//
//    BFMLALB  <Vd>.4S, <Vn>.8H, <Vm>.H[<index>]
//
// BFloat16 floating-point widening multiply-add long (by element) widens the even-
// numbered (bottom) or odd-numbered (top) 16-bit elements in the first source
// vector, and the indexed element in the second source vector from Bfloat16 to
// single-precision format. The instruction then multiplies and adds these values
// without intermediate rounding to single-precision elements of the destination
// vector that overlap with the corresponding BFloat16 elements in the first source
// vector.
//
// ID_AA64ISAR1_EL1 .BF16 indicates whether this instruction is supported.
//
// 2. BFloat16 floating-point widening multiply-add long (vector)
//
//    BFMLALB  <Vd>.4S, <Vn>.8H, <Vm>.8H
//
// BFloat16 floating-point widening multiply-add long (vector) widens the even-
// numbered (bottom) or odd-numbered (top) 16-bit elements in the first and second
// source vectors from Bfloat16 to single-precision format. The instruction then
// multiplies and adds these values without intermediate rounding to the single-
// precision elements of the destination vector that overlap with the corresponding
// BFloat16 elements in the source vectors.
//
// ID_AA64ISAR1_EL1 .BF16 indicates whether this instruction is supported.
//
func (self *Program) BFMLALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("BFMLALB", 3, asm.Operands { v0, v1, v2 })
    // BFMLALB  <Vd>.4S, <Vn>.8H, <Vm>.H[<index>]
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec8H && isVri(v2) && vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asimdelem(
            0,
            0,
            3,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            15,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // BFMLALB  <Vd>.4S, <Vn>.8H, <Vm>.8H
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec8H && isVr(v2) && vfmt(v2) == Vec8H {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame2(0, 1, 3, sa_vm, 15, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BFMLALB")
}

// BFMLALT instruction have 2 forms across 2 categories:
//
// 1. BFloat16 floating-point widening multiply-add long (by element)
//
//    BFMLALT  <Vd>.4S, <Vn>.8H, <Vm>.H[<index>]
//
// BFloat16 floating-point widening multiply-add long (by element) widens the even-
// numbered (bottom) or odd-numbered (top) 16-bit elements in the first source
// vector, and the indexed element in the second source vector from Bfloat16 to
// single-precision format. The instruction then multiplies and adds these values
// without intermediate rounding to single-precision elements of the destination
// vector that overlap with the corresponding BFloat16 elements in the first source
// vector.
//
// ID_AA64ISAR1_EL1 .BF16 indicates whether this instruction is supported.
//
// 2. BFloat16 floating-point widening multiply-add long (vector)
//
//    BFMLALT  <Vd>.4S, <Vn>.8H, <Vm>.8H
//
// BFloat16 floating-point widening multiply-add long (vector) widens the even-
// numbered (bottom) or odd-numbered (top) 16-bit elements in the first and second
// source vectors from Bfloat16 to single-precision format. The instruction then
// multiplies and adds these values without intermediate rounding to the single-
// precision elements of the destination vector that overlap with the corresponding
// BFloat16 elements in the source vectors.
//
// ID_AA64ISAR1_EL1 .BF16 indicates whether this instruction is supported.
//
func (self *Program) BFMLALT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("BFMLALT", 3, asm.Operands { v0, v1, v2 })
    // BFMLALT  <Vd>.4S, <Vn>.8H, <Vm>.H[<index>]
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec8H && isVri(v2) && vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asimdelem(
            1,
            0,
            3,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            15,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // BFMLALT  <Vd>.4S, <Vn>.8H, <Vm>.8H
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec8H && isVr(v2) && vfmt(v2) == Vec8H {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame2(1, 1, 3, sa_vm, 15, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BFMLALT")
}

// BFMMLA instruction have one single form across one single category:
//
// 1. BFloat16 floating-point matrix multiply-accumulate into 2x2 matrix
//
//    BFMMLA  <Vd>.4S, <Vn>.8H, <Vm>.8H
//
// BFloat16 floating-point matrix multiply-accumulate into 2x2 matrix.
//
// If FEAT_EBF16 is not implemented or FPCR .EBF is 0, this instruction:
//
//     * Performs two unfused sums-of-products within each two pairs of
//       adjacent BFloat16 elements while multiplying the 2x4 matrix of
//       BFloat16 values in the first source vector with the 4x2 matrix of
//       BFloat16 values in the second source vector. The intermediate single-
//       precision products are rounded before they are summed and the
//       intermediate sum is rounded before accumulation into the 2x2 single-
//       precision matrix in the destination vector. This is equivalent to
//       accumulating two 2-way unfused dot products per destination element.
//     * Uses the non-IEEE 754 Round-to-Odd rounding mode, which forces bit 0
//       of an inexact result to 1, and rounds an overflow to an appropriately
//       signed Infinity.
//     * Flushes denormalized inputs and results to zero, as if FPCR .{FZ, FIZ}
//       is {1, 1}.
//     * Disables alternative floating point behaviors, as if FPCR .AH is 0.
//
// If FEAT_EBF16 is implemented and FPCR .EBF is 1, then this instruction:
//
//     * Performs two fused sums-of-products within each two pairs of adjacent
//       BFloat16 elements while multiplying the 2x4 matrix of BFloat16 values
//       in the first source vector with the 4x2 matrix of BFloat16 values in
//       the second source vector. The intermediate single-precision products
//       are not rounded before they are summed, but the intermediate sum is
//       rounded before accumulation into the 2x2 single-precision matrix in
//       the destination vector. This is equivalent to accumulating two 2-way
//       fused dot products per destination element.
//     * Follows all other floating-point behaviors that apply to single-
//       precision arithmetic, as governed by FPCR .RMode, FPCR .FZ, FPCR .AH,
//       and FPCR .FIZ.
//
// Irrespective of FEAT_EBF16 and FPCR .EBF, this instruction:
//
//     * Does not modify the cumulative FPSR exception bits (IDC, IXC, UFC,
//       OFC, DZC, and IOC).
//     * Disables trapped floating-point exceptions, as if the FPCR trap enable
//       bits (IDE, IXE, UFE, OFE, DZE, and IOE) are all zero.
//     * Generates only the default NaN, as if FPCR .DN is 1.
//
// ID_AA64ISAR1_EL1 .BF16 indicates whether this instruction is supported.
//
func (self *Program) BFMMLA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("BFMMLA", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec8H && isVr(v2) && vfmt(v2) == Vec8H {
        self.Arch.Require(FEAT_BF16)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame2(1, 1, 1, sa_vm, 13, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BFMMLA")
}

// BFXIL instruction have 2 forms across one single category:
//
// 1. Bitfield extract and insert at low end
//
//    BFXIL  <Wd>, <Wn>, #<lsb>, #<width>
//    BFXIL  <Xd>, <Xn>, #<lsb>, #<width>
//
// Bitfield Extract and Insert Low copies a bitfield of <width> bits starting from
// bit position <lsb> in the source register to the least significant bits of the
// destination register, leaving the other destination bits unchanged.
//
func (self *Program) BFXIL(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("BFXIL", 4, asm.Operands { v0, v1, v2, v3 })
    // BFXIL  <Wd>, <Wn>, #<lsb>, #<width>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) && isBFxWidth(v2, v3, 32) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_lsb_1 := asUimm5(v2)
        sa_width := sa_lsb_1 + asUimm5(v3) - 1
        return p.setins(bitfield(0, 1, 0, sa_lsb_1, sa_width, sa_wn, sa_wd))
    }
    // BFXIL  <Xd>, <Xn>, #<lsb>, #<width>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) && isBFxWidth(v2, v3, 64) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_lsb_3 := asUimm6(v2)
        sa_width_1 := sa_lsb_3 + asUimm6(v3) - 1
        return p.setins(bitfield(1, 1, 1, sa_lsb_3, sa_width_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BFXIL")
}

// BIC instruction have 5 forms across 3 categories:
//
// 1. Bitwise bit Clear (vector, immediate)
//
//    BIC  <Vd>.<T>, #<imm8>{, LSL #<amount>}
//    BIC  <Vd>.<T>, #<imm8>{, LSL #<amount>}
//
// Bitwise bit Clear (vector, immediate). This instruction reads each vector
// element from the destination SIMD&FP register, performs a bitwise AND between
// each result and the complement of an immediate constant, places the result into
// a vector, and writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Bitwise bit Clear (vector, register)
//
//    BIC  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Bitwise bit Clear (vector, register). This instruction performs a bitwise AND
// between the first source SIMD&FP register and the complement of the second
// source SIMD&FP register, and writes the result to the destination SIMD&FP
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 3. Bitwise Bit Clear (shifted register)
//
//    BIC  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    BIC  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Bitwise Bit Clear (shifted register) performs a bitwise AND of a register value
// and the complement of an optionally-shifted register value, and writes the
// result to the destination register.
//
func (self *Program) BIC(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("BIC", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("BIC", 3, asm.Operands { v0, v1, vv[0] })
        case 2  : p = self.alloc("BIC", 4, asm.Operands { v0, v1, vv[0], vv[1] })
        default : panic("aarch64: instruction BIC takes 2 or 3 or 4 operands")
    }
    // BIC  <Vd>.<T>, #<imm8>{, LSL #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isUimm8(v1) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = DomainAdvSimd
        sa_amount := uint32(0b0)
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 8: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b1001)
        switch sa_amount {
            case 0: cmode |= 0b0 << 1
            case 8: cmode |= 0b1 << 1
            default: panic("aarch64: invalid combination of operands for BIC")
        }
        return p.setins(asimdimm(
            sa_t,
            1,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // BIC  <Vd>.<T>, #<imm8>{, LSL #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isUimm8(v1) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = DomainAdvSimd
        sa_amount_1 := uint32(0b00)
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b0
            case Vec4S: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 0: sa_amount_1 = 0b00
            case 8: sa_amount_1 = 0b01
            case 16: sa_amount_1 = 0b10
            case 24: sa_amount_1 = 0b11
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b0001)
        switch sa_amount_1 {
            case 0: cmode |= 0b00 << 1
            case 8: cmode |= 0b01 << 1
            case 16: cmode |= 0b10 << 1
            case 24: cmode |= 0b11 << 1
            default: panic("aarch64: invalid combination of operands for BIC")
        }
        return p.setins(asimdimm(
            sa_t_1,
            1,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // BIC  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        return p.setins(asimdsame(sa_t, 0, 1, sa_vm, 3, sa_vn, sa_vd))
    }
    // BIC  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 1 || len(vv) == 2) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(vv[0]) &&
       (len(vv) < 2 || isMods(vv[1], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(vv[0].(asm.Register).ID())
        if len(vv) >= 2 {
            switch vv[1].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[1].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 0, sa_shift, 1, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // BIC  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 1 || len(vv) == 2) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(vv[0]) &&
       (len(vv) < 2 || isMods(vv[1], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(vv[0].(asm.Register).ID())
        if len(vv) >= 2 {
            switch vv[1].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[1].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 0, sa_shift, 1, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BIC")
}

// BICS instruction have 2 forms across one single category:
//
// 1. Bitwise Bit Clear (shifted register), setting flags
//
//    BICS  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    BICS  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Bitwise Bit Clear (shifted register), setting flags, performs a bitwise AND of a
// register value and the complement of an optionally-shifted register value, and
// writes the result to the destination register. It updates the condition flags
// based on the result.
//
func (self *Program) BICS(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("BICS", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("BICS", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction BICS takes 3 or 4 operands")
    }
    // BICS  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 3, sa_shift, 1, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // BICS  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 3, sa_shift, 1, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BICS")
}

// BIF instruction have one single form across one single category:
//
// 1. Bitwise Insert if False
//
//    BIF  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Bitwise Insert if False. This instruction inserts each bit from the first source
// SIMD&FP register into the destination SIMD&FP register if the corresponding bit
// of the second source SIMD&FP register is 0, otherwise leaves the bit in the
// destination register unchanged.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) BIF(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("BIF", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(sa_t, 1, 3, sa_vm, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BIF")
}

// BIT instruction have one single form across one single category:
//
// 1. Bitwise Insert if True
//
//    BIT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Bitwise Insert if True. This instruction inserts each bit from the first source
// SIMD&FP register into the SIMD&FP destination register if the corresponding bit
// of the second source SIMD&FP register is 1, otherwise leaves the bit in the
// destination register unchanged.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) BIT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("BIT", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(sa_t, 1, 2, sa_vm, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BIT")
}

// BL instruction have 2 forms across one single category:
//
// 1. Branch with Link
//
//    BL  <label>
//    BL  .±<offs>
//
// Branch with Link branches to a PC-relative offset, setting the register X30 to
// PC+4. It provides a hint that this is a subroutine call.
//
func (self *Program) BL(v0 interface{}) *Instruction {
    p := self.alloc("BL", 1, asm.Operands { v0 })
    // BL  <label>
    if isLabel(v0) {
        p.Domain = asm.DomainGeneric
        sa_label := v0.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return branch_imm(1, pcrel26(sa_label, pc))
        })
    }
    // BL  .±<offs>
    if isPCrel(v0) {
        p.Domain = asm.DomainGeneric
        ra_pcrel := v0.(asm.RelativeOffset)
        return p.setins(branch_imm(1, rel26(ra_pcrel)))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for BL")
}

// BLR instruction have one single form across one single category:
//
// 1. Branch with Link to Register
//
//    BLR  <Xn>
//
// Branch with Link to Register calls a subroutine at an address in a register,
// setting register X30 to PC+4.
//
func (self *Program) BLR(v0 interface{}) *Instruction {
    p := self.alloc("BLR", 1, asm.Operands { v0 })
    if isXr(v0) {
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        return p.setins(branch_reg(1, 31, 0, sa_xn, 0))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BLR")
}

// BLRAA instruction have one single form across one single category:
//
// 1. Branch with Link to Register, with pointer authentication
//
//    BLRAA  <Xn>, <Xm|SP>
//
// Branch with Link to Register, with pointer authentication. This instruction
// authenticates the address in the general-purpose register that is specified by
// <Xn> , using a modifier and the specified key, and calls a subroutine at the
// authenticated address, setting register X30 to PC+4.
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xm|SP> for BLRAA and BLRAB .
//     * The value zero, for BLRAAZ and BLRABZ .
//
// Key A is used for BLRAA and BLRAAZ . Key B is used for BLRAB and BLRABZ .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to the general-purpose register.
//
func (self *Program) BLRAA(v0, v1 interface{}) *Instruction {
    p := self.alloc("BLRAA", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_xm_sp := uint32(v1.(asm.Register).ID())
        op4 := uint32(0b00000)
        op4 |= sa_xm_sp
        return p.setins(branch_reg(9, 31, 2, sa_xn, op4))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BLRAA")
}

// BLRAAZ instruction have one single form across one single category:
//
// 1. Branch with Link to Register, with pointer authentication
//
//    BLRAAZ  <Xn>
//
// Branch with Link to Register, with pointer authentication. This instruction
// authenticates the address in the general-purpose register that is specified by
// <Xn> , using a modifier and the specified key, and calls a subroutine at the
// authenticated address, setting register X30 to PC+4.
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xm|SP> for BLRAA and BLRAB .
//     * The value zero, for BLRAAZ and BLRABZ .
//
// Key A is used for BLRAA and BLRAAZ . Key B is used for BLRAB and BLRABZ .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to the general-purpose register.
//
func (self *Program) BLRAAZ(v0 interface{}) *Instruction {
    p := self.alloc("BLRAAZ", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        return p.setins(branch_reg(1, 31, 2, sa_xn, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BLRAAZ")
}

// BLRAB instruction have one single form across one single category:
//
// 1. Branch with Link to Register, with pointer authentication
//
//    BLRAB  <Xn>, <Xm|SP>
//
// Branch with Link to Register, with pointer authentication. This instruction
// authenticates the address in the general-purpose register that is specified by
// <Xn> , using a modifier and the specified key, and calls a subroutine at the
// authenticated address, setting register X30 to PC+4.
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xm|SP> for BLRAA and BLRAB .
//     * The value zero, for BLRAAZ and BLRABZ .
//
// Key A is used for BLRAA and BLRAAZ . Key B is used for BLRAB and BLRABZ .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to the general-purpose register.
//
func (self *Program) BLRAB(v0, v1 interface{}) *Instruction {
    p := self.alloc("BLRAB", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_xm_sp := uint32(v1.(asm.Register).ID())
        op4 := uint32(0b00000)
        op4 |= sa_xm_sp
        return p.setins(branch_reg(9, 31, 3, sa_xn, op4))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BLRAB")
}

// BLRABZ instruction have one single form across one single category:
//
// 1. Branch with Link to Register, with pointer authentication
//
//    BLRABZ  <Xn>
//
// Branch with Link to Register, with pointer authentication. This instruction
// authenticates the address in the general-purpose register that is specified by
// <Xn> , using a modifier and the specified key, and calls a subroutine at the
// authenticated address, setting register X30 to PC+4.
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xm|SP> for BLRAA and BLRAB .
//     * The value zero, for BLRAAZ and BLRABZ .
//
// Key A is used for BLRAA and BLRAAZ . Key B is used for BLRAB and BLRABZ .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to the general-purpose register.
//
func (self *Program) BLRABZ(v0 interface{}) *Instruction {
    p := self.alloc("BLRABZ", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        return p.setins(branch_reg(1, 31, 3, sa_xn, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BLRABZ")
}

// BR instruction have one single form across one single category:
//
// 1. Branch to Register
//
//    BR  <Xn>
//
// Branch to Register branches unconditionally to an address in a register, with a
// hint that this is not a subroutine return.
//
func (self *Program) BR(v0 interface{}) *Instruction {
    p := self.alloc("BR", 1, asm.Operands { v0 })
    if isXr(v0) {
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        return p.setins(branch_reg(0, 31, 0, sa_xn, 0))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BR")
}

// BRAA instruction have one single form across one single category:
//
// 1. Branch to Register, with pointer authentication
//
//    BRAA  <Xn>, <Xm|SP>
//
// Branch to Register, with pointer authentication. This instruction authenticates
// the address in the general-purpose register that is specified by <Xn> , using a
// modifier and the specified key, and branches to the authenticated address.
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xm|SP> for BRAA and BRAB .
//     * The value zero, for BRAAZ and BRABZ .
//
// Key A is used for BRAA and BRAAZ . Key B is used for BRAB and BRABZ .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to the general-purpose register.
//
func (self *Program) BRAA(v0, v1 interface{}) *Instruction {
    p := self.alloc("BRAA", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_xm_sp := uint32(v1.(asm.Register).ID())
        op4 := uint32(0b00000)
        op4 |= sa_xm_sp
        return p.setins(branch_reg(8, 31, 2, sa_xn, op4))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BRAA")
}

// BRAAZ instruction have one single form across one single category:
//
// 1. Branch to Register, with pointer authentication
//
//    BRAAZ  <Xn>
//
// Branch to Register, with pointer authentication. This instruction authenticates
// the address in the general-purpose register that is specified by <Xn> , using a
// modifier and the specified key, and branches to the authenticated address.
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xm|SP> for BRAA and BRAB .
//     * The value zero, for BRAAZ and BRABZ .
//
// Key A is used for BRAA and BRAAZ . Key B is used for BRAB and BRABZ .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to the general-purpose register.
//
func (self *Program) BRAAZ(v0 interface{}) *Instruction {
    p := self.alloc("BRAAZ", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        return p.setins(branch_reg(0, 31, 2, sa_xn, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BRAAZ")
}

// BRAB instruction have one single form across one single category:
//
// 1. Branch to Register, with pointer authentication
//
//    BRAB  <Xn>, <Xm|SP>
//
// Branch to Register, with pointer authentication. This instruction authenticates
// the address in the general-purpose register that is specified by <Xn> , using a
// modifier and the specified key, and branches to the authenticated address.
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xm|SP> for BRAA and BRAB .
//     * The value zero, for BRAAZ and BRABZ .
//
// Key A is used for BRAA and BRAAZ . Key B is used for BRAB and BRABZ .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to the general-purpose register.
//
func (self *Program) BRAB(v0, v1 interface{}) *Instruction {
    p := self.alloc("BRAB", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_xm_sp := uint32(v1.(asm.Register).ID())
        op4 := uint32(0b00000)
        op4 |= sa_xm_sp
        return p.setins(branch_reg(8, 31, 3, sa_xn, op4))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BRAB")
}

// BRABZ instruction have one single form across one single category:
//
// 1. Branch to Register, with pointer authentication
//
//    BRABZ  <Xn>
//
// Branch to Register, with pointer authentication. This instruction authenticates
// the address in the general-purpose register that is specified by <Xn> , using a
// modifier and the specified key, and branches to the authenticated address.
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xm|SP> for BRAA and BRAB .
//     * The value zero, for BRAAZ and BRABZ .
//
// Key A is used for BRAA and BRAAZ . Key B is used for BRAB and BRABZ .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to the general-purpose register.
//
func (self *Program) BRABZ(v0 interface{}) *Instruction {
    p := self.alloc("BRABZ", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        return p.setins(branch_reg(0, 31, 3, sa_xn, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BRABZ")
}

// BRB instruction have one single form across one single category:
//
// 1. Branch Record Buffer
//
//    BRB  <brb_op>{, <Xt>}
//
// Branch Record Buffer. For more information, see op0==0b01, cache maintenance,
// TLB maintenance, and address translation instructions .
//
func (self *Program) BRB(v0 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("BRB", 1, asm.Operands { v0 })
        case 1  : p = self.alloc("BRB", 2, asm.Operands { v0, vv[0] })
        default : panic("aarch64: instruction BRB takes 1 or 2 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && isBRBOption(v0) && (len(vv) == 0 || isXr(vv[0])) {
        self.Arch.Require(FEAT_BRBE)
        p.Domain = DomainSystem
        sa_xt := uint32(0b11111)
        sa_brb_op := uint32(v0.(BRBOption))
        if len(vv) >= 1 {
            sa_xt = uint32(vv[0].(asm.Register).ID())
        }
        return p.setins(systeminstrs(0, 1, 7, 2, sa_brb_op, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BRB")
}

// BRK instruction have one single form across one single category:
//
// 1. Breakpoint instruction
//
//    BRK  #<imm>
//
// Breakpoint instruction. A BRK instruction generates a Breakpoint Instruction
// exception. The PE records the exception in ESR_ELx , using the EC value 0x3c ,
// and captures the value of the immediate argument in ESR_ELx .ISS.
//
func (self *Program) BRK(v0 interface{}) *Instruction {
    p := self.alloc("BRK", 1, asm.Operands { v0 })
    if isInRange(v0, 0, 65535) {
        p.Domain = DomainSystem
        sa_imm := asUimm16(v0)
        return p.setins(exception(1, sa_imm, 0, 0))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BRK")
}

// BSL instruction have one single form across one single category:
//
// 1. Bitwise Select
//
//    BSL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Bitwise Select. This instruction sets each bit in the destination SIMD&FP
// register to the corresponding bit from the first source SIMD&FP register when
// the original destination bit was 1, otherwise from the second source SIMD&FP
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) BSL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("BSL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(sa_t, 1, 1, sa_vm, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BSL")
}

// BTI instruction have one single form across one single category:
//
// 1. Branch Target Identification
//
//    BTI  {<targets>}
//
// Branch Target Identification. A BTI instruction is used to guard against the
// execution of instructions which are not the intended target of a branch.
//
// Outside of a guarded memory region, a BTI instruction executes as a NOP . Within
// a guarded memory region while PSTATE .BTYPE != 0b00 , a BTI instruction
// compatible with the current value of PSTATE.BTYPE will not generate a Branch
// Target Exception and will allow execution of subsequent instructions within the
// memory region.
//
// The operand <targets> passed to a BTI instruction determines the values of
// PSTATE .BTYPE which the BTI instruction is compatible with.
//
// NOTE: 
//     Within a guarded memory region, when PSTATE .BTYPE != 0b00 , all
//     instructions will generate a Branch Target Exception, other than BRK ,
//     BTI , HLT , PACIASP , and PACIBSP , which might not. See the individual
//     instructions for more information.
//
func (self *Program) BTI(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("BTI", 0, asm.Operands {})
        case 1  : p = self.alloc("BTI", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction BTI takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isTargets(vv[0])) {
        self.Arch.Require(FEAT_BTI)
        p.Domain = DomainSystem
        sa_targets := _BrOmitted
        if len(vv) >= 1 {
            sa_targets = vv[0].(BranchTarget)
        }
        op2 := uint32(0b000)
        switch sa_targets {
            case _BrOmitted: op2 |= 0b00 << 1
            case BrC: op2 |= 0b01 << 1
            case BrJ: op2 |= 0b10 << 1
            case BrJC: op2 |= 0b11 << 1
            default: panic("aarch64: invalid combination of operands for BTI")
        }
        return p.setins(hints(4, op2))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for BTI")
}

// CAS instruction have 2 forms across one single category:
//
// 1. Compare and Swap word or doubleword in memory
//
//    CAS  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//    CAS  <Xs>, <Xt>, [<Xn|SP>{,#0}]
//
// Compare and Swap word or doubleword in memory reads a 32-bit word or 64-bit
// doubleword from memory, and compares it against the value held in a first
// register. If the comparison is equal, the value in a second register is written
// to memory. If the write is performed, the read and write occur atomically such
// that no other modification of the memory location can take place between the
// read and write.
//
//     * CASA and CASAL load from memory with acquire semantics.
//     * CASL and CASAL store to memory with release semantics.
//     * CAS has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , or <Xs> , is restored to the value held in
// the register before the instruction was executed.
//
func (self *Program) CAS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CAS", 3, asm.Operands { v0, v1, v2 })
    // CAS  <Ws>, <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(2, 0, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    // CAS  <Xs>, <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(3, 0, sa_xs, 0, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CAS")
}

// CASA instruction have 2 forms across one single category:
//
// 1. Compare and Swap word or doubleword in memory
//
//    CASA  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//    CASA  <Xs>, <Xt>, [<Xn|SP>{,#0}]
//
// Compare and Swap word or doubleword in memory reads a 32-bit word or 64-bit
// doubleword from memory, and compares it against the value held in a first
// register. If the comparison is equal, the value in a second register is written
// to memory. If the write is performed, the read and write occur atomically such
// that no other modification of the memory location can take place between the
// read and write.
//
//     * CASA and CASAL load from memory with acquire semantics.
//     * CASL and CASAL store to memory with release semantics.
//     * CAS has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , or <Xs> , is restored to the value held in
// the register before the instruction was executed.
//
func (self *Program) CASA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASA", 3, asm.Operands { v0, v1, v2 })
    // CASA  <Ws>, <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(2, 1, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    // CASA  <Xs>, <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(3, 1, sa_xs, 0, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CASA")
}

// CASAB instruction have one single form across one single category:
//
// 1. Compare and Swap byte in memory
//
//    CASAB  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Compare and Swap byte in memory reads an 8-bit byte from memory, and compares it
// against the value held in a first register. If the comparison is equal, the
// value in a second register is written to memory. If the write is performed, the
// read and write occur atomically such that no other modification of the memory
// location can take place between the read and write.
//
//     * CASAB and CASALB load from memory with acquire semantics.
//     * CASLB and CASALB store to memory with release semantics.
//     * CASB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , is restored to the values held in the
// register before the instruction was executed.
//
func (self *Program) CASAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(0, 1, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CASAB")
}

// CASAH instruction have one single form across one single category:
//
// 1. Compare and Swap halfword in memory
//
//    CASAH  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Compare and Swap halfword in memory reads a 16-bit halfword from memory, and
// compares it against the value held in a first register. If the comparison is
// equal, the value in a second register is written to memory. If the write is
// performed, the read and write occur atomically such that no other modification
// of the memory location can take place between the read and write.
//
//     * CASAH and CASALH load from memory with acquire semantics.
//     * CASLH and CASALH store to memory with release semantics.
//     * CASH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , is restored to the values held in the
// register before the instruction was executed.
//
func (self *Program) CASAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(1, 1, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CASAH")
}

// CASAL instruction have 2 forms across one single category:
//
// 1. Compare and Swap word or doubleword in memory
//
//    CASAL  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//    CASAL  <Xs>, <Xt>, [<Xn|SP>{,#0}]
//
// Compare and Swap word or doubleword in memory reads a 32-bit word or 64-bit
// doubleword from memory, and compares it against the value held in a first
// register. If the comparison is equal, the value in a second register is written
// to memory. If the write is performed, the read and write occur atomically such
// that no other modification of the memory location can take place between the
// read and write.
//
//     * CASA and CASAL load from memory with acquire semantics.
//     * CASL and CASAL store to memory with release semantics.
//     * CAS has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , or <Xs> , is restored to the value held in
// the register before the instruction was executed.
//
func (self *Program) CASAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASAL", 3, asm.Operands { v0, v1, v2 })
    // CASAL  <Ws>, <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(2, 1, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    // CASAL  <Xs>, <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(3, 1, sa_xs, 1, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CASAL")
}

// CASALB instruction have one single form across one single category:
//
// 1. Compare and Swap byte in memory
//
//    CASALB  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Compare and Swap byte in memory reads an 8-bit byte from memory, and compares it
// against the value held in a first register. If the comparison is equal, the
// value in a second register is written to memory. If the write is performed, the
// read and write occur atomically such that no other modification of the memory
// location can take place between the read and write.
//
//     * CASAB and CASALB load from memory with acquire semantics.
//     * CASLB and CASALB store to memory with release semantics.
//     * CASB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , is restored to the values held in the
// register before the instruction was executed.
//
func (self *Program) CASALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(0, 1, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CASALB")
}

// CASALH instruction have one single form across one single category:
//
// 1. Compare and Swap halfword in memory
//
//    CASALH  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Compare and Swap halfword in memory reads a 16-bit halfword from memory, and
// compares it against the value held in a first register. If the comparison is
// equal, the value in a second register is written to memory. If the write is
// performed, the read and write occur atomically such that no other modification
// of the memory location can take place between the read and write.
//
//     * CASAH and CASALH load from memory with acquire semantics.
//     * CASLH and CASALH store to memory with release semantics.
//     * CASH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , is restored to the values held in the
// register before the instruction was executed.
//
func (self *Program) CASALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(1, 1, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CASALH")
}

// CASB instruction have one single form across one single category:
//
// 1. Compare and Swap byte in memory
//
//    CASB  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Compare and Swap byte in memory reads an 8-bit byte from memory, and compares it
// against the value held in a first register. If the comparison is equal, the
// value in a second register is written to memory. If the write is performed, the
// read and write occur atomically such that no other modification of the memory
// location can take place between the read and write.
//
//     * CASAB and CASALB load from memory with acquire semantics.
//     * CASLB and CASALB store to memory with release semantics.
//     * CASB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , is restored to the values held in the
// register before the instruction was executed.
//
func (self *Program) CASB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(0, 0, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CASB")
}

// CASH instruction have one single form across one single category:
//
// 1. Compare and Swap halfword in memory
//
//    CASH  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Compare and Swap halfword in memory reads a 16-bit halfword from memory, and
// compares it against the value held in a first register. If the comparison is
// equal, the value in a second register is written to memory. If the write is
// performed, the read and write occur atomically such that no other modification
// of the memory location can take place between the read and write.
//
//     * CASAH and CASALH load from memory with acquire semantics.
//     * CASLH and CASALH store to memory with release semantics.
//     * CASH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , is restored to the values held in the
// register before the instruction was executed.
//
func (self *Program) CASH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(1, 0, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CASH")
}

// CASL instruction have 2 forms across one single category:
//
// 1. Compare and Swap word or doubleword in memory
//
//    CASL  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//    CASL  <Xs>, <Xt>, [<Xn|SP>{,#0}]
//
// Compare and Swap word or doubleword in memory reads a 32-bit word or 64-bit
// doubleword from memory, and compares it against the value held in a first
// register. If the comparison is equal, the value in a second register is written
// to memory. If the write is performed, the read and write occur atomically such
// that no other modification of the memory location can take place between the
// read and write.
//
//     * CASA and CASAL load from memory with acquire semantics.
//     * CASL and CASAL store to memory with release semantics.
//     * CAS has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , or <Xs> , is restored to the value held in
// the register before the instruction was executed.
//
func (self *Program) CASL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASL", 3, asm.Operands { v0, v1, v2 })
    // CASL  <Ws>, <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(2, 0, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    // CASL  <Xs>, <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(3, 0, sa_xs, 1, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CASL")
}

// CASLB instruction have one single form across one single category:
//
// 1. Compare and Swap byte in memory
//
//    CASLB  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Compare and Swap byte in memory reads an 8-bit byte from memory, and compares it
// against the value held in a first register. If the comparison is equal, the
// value in a second register is written to memory. If the write is performed, the
// read and write occur atomically such that no other modification of the memory
// location can take place between the read and write.
//
//     * CASAB and CASALB load from memory with acquire semantics.
//     * CASLB and CASALB store to memory with release semantics.
//     * CASB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , is restored to the values held in the
// register before the instruction was executed.
//
func (self *Program) CASLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(0, 0, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CASLB")
}

// CASLH instruction have one single form across one single category:
//
// 1. Compare and Swap halfword in memory
//
//    CASLH  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Compare and Swap halfword in memory reads a 16-bit halfword from memory, and
// compares it against the value held in a first register. If the comparison is
// equal, the value in a second register is written to memory. If the write is
// performed, the read and write occur atomically such that no other modification
// of the memory location can take place between the read and write.
//
//     * CASAH and CASALH load from memory with acquire semantics.
//     * CASLH and CASALH store to memory with release semantics.
//     * CASH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the register which is
// compared and loaded, that is <Ws> , is restored to the values held in the
// register before the instruction was executed.
//
func (self *Program) CASLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CASLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(comswap(1, 0, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CASLH")
}

// CASP instruction have 2 forms across one single category:
//
// 1. Compare and Swap Pair of words or doublewords in memory
//
//    CASP  <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]
//    CASP  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]
//
// Compare and Swap Pair of words or doublewords in memory reads a pair of 32-bit
// words or 64-bit doublewords from memory, and compares them against the values
// held in the first pair of registers. If the comparison is equal, the values in
// the second pair of registers are written to memory. If the writes are performed,
// the reads and writes occur atomically such that no other modification of the
// memory location can take place between the reads and writes.
//
//     * CASPA and CASPAL load from memory with acquire semantics.
//     * CASPL and CASPAL store to memory with release semantics.
//     * CASP has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the registers which are
// compared and loaded, that is <Ws> and <W(s+1)> , or <Xs> and <X(s+1)> , are
// restored to the values held in the registers before the instruction was
// executed.
//
func (self *Program) CASP(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("CASP", 5, asm.Operands { v0, v1, v2, v3, v4 })
    // CASP  <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isNextReg(v1, v0, 1) &&
       isWr(v2) &&
       isWr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       (moffs(v4) == 0 || moffs(v4) == 0) &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(comswappr(0, 0, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    // CASP  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       (moffs(v4) == 0 || moffs(v4) == 0) &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(comswappr(1, 0, sa_xs, 0, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CASP")
}

// CASPA instruction have 2 forms across one single category:
//
// 1. Compare and Swap Pair of words or doublewords in memory
//
//    CASPA  <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]
//    CASPA  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]
//
// Compare and Swap Pair of words or doublewords in memory reads a pair of 32-bit
// words or 64-bit doublewords from memory, and compares them against the values
// held in the first pair of registers. If the comparison is equal, the values in
// the second pair of registers are written to memory. If the writes are performed,
// the reads and writes occur atomically such that no other modification of the
// memory location can take place between the reads and writes.
//
//     * CASPA and CASPAL load from memory with acquire semantics.
//     * CASPL and CASPAL store to memory with release semantics.
//     * CASP has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the registers which are
// compared and loaded, that is <Ws> and <W(s+1)> , or <Xs> and <X(s+1)> , are
// restored to the values held in the registers before the instruction was
// executed.
//
func (self *Program) CASPA(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("CASPA", 5, asm.Operands { v0, v1, v2, v3, v4 })
    // CASPA  <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isNextReg(v1, v0, 1) &&
       isWr(v2) &&
       isWr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       (moffs(v4) == 0 || moffs(v4) == 0) &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(comswappr(0, 1, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    // CASPA  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       (moffs(v4) == 0 || moffs(v4) == 0) &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(comswappr(1, 1, sa_xs, 0, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CASPA")
}

// CASPAL instruction have 2 forms across one single category:
//
// 1. Compare and Swap Pair of words or doublewords in memory
//
//    CASPAL  <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]
//    CASPAL  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]
//
// Compare and Swap Pair of words or doublewords in memory reads a pair of 32-bit
// words or 64-bit doublewords from memory, and compares them against the values
// held in the first pair of registers. If the comparison is equal, the values in
// the second pair of registers are written to memory. If the writes are performed,
// the reads and writes occur atomically such that no other modification of the
// memory location can take place between the reads and writes.
//
//     * CASPA and CASPAL load from memory with acquire semantics.
//     * CASPL and CASPAL store to memory with release semantics.
//     * CASP has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the registers which are
// compared and loaded, that is <Ws> and <W(s+1)> , or <Xs> and <X(s+1)> , are
// restored to the values held in the registers before the instruction was
// executed.
//
func (self *Program) CASPAL(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("CASPAL", 5, asm.Operands { v0, v1, v2, v3, v4 })
    // CASPAL  <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isNextReg(v1, v0, 1) &&
       isWr(v2) &&
       isWr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       (moffs(v4) == 0 || moffs(v4) == 0) &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(comswappr(0, 1, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    // CASPAL  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       (moffs(v4) == 0 || moffs(v4) == 0) &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(comswappr(1, 1, sa_xs, 1, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CASPAL")
}

// CASPL instruction have 2 forms across one single category:
//
// 1. Compare and Swap Pair of words or doublewords in memory
//
//    CASPL  <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]
//    CASPL  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]
//
// Compare and Swap Pair of words or doublewords in memory reads a pair of 32-bit
// words or 64-bit doublewords from memory, and compares them against the values
// held in the first pair of registers. If the comparison is equal, the values in
// the second pair of registers are written to memory. If the writes are performed,
// the reads and writes occur atomically such that no other modification of the
// memory location can take place between the reads and writes.
//
//     * CASPA and CASPAL load from memory with acquire semantics.
//     * CASPL and CASPAL store to memory with release semantics.
//     * CASP has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// The architecture permits that the data read clears any exclusive monitors
// associated with that location, even if the compare subsequently fails.
//
// If the instruction generates a synchronous Data Abort, the registers which are
// compared and loaded, that is <Ws> and <W(s+1)> , or <Xs> and <X(s+1)> , are
// restored to the values held in the registers before the instruction was
// executed.
//
func (self *Program) CASPL(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("CASPL", 5, asm.Operands { v0, v1, v2, v3, v4 })
    // CASPL  <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isNextReg(v1, v0, 1) &&
       isWr(v2) &&
       isWr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       (moffs(v4) == 0 || moffs(v4) == 0) &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(comswappr(0, 0, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    // CASPL  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       (moffs(v4) == 0 || moffs(v4) == 0) &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(comswappr(1, 0, sa_xs, 1, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CASPL")
}

// CBNZ instruction have 4 forms across one single category:
//
// 1. Compare and Branch on Nonzero
//
//    CBNZ  <Wt>, <label>
//    CBNZ  <Wt>, .±<offs>
//    CBNZ  <Xt>, <label>
//    CBNZ  <Xt>, .±<offs>
//
// Compare and Branch on Nonzero compares the value in a register with zero, and
// conditionally branches to a label at a PC-relative offset if the comparison is
// not equal. It provides a hint that this is not a subroutine call or return. This
// instruction does not affect the condition flags.
//
func (self *Program) CBNZ(v0, v1 interface{}) *Instruction {
    p := self.alloc("CBNZ", 2, asm.Operands { v0, v1 })
    // CBNZ  <Wt>, <label>
    if isWr(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return compbranch(0, 1, pcrel19(sa_label, pc), sa_wt)
        })
    }
    // CBNZ  <Wt>, .±<offs>
    if isWr(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(compbranch(0, 1, rel19(ra_pcrel), sa_wt))
    }
    // CBNZ  <Xt>, <label>
    if isXr(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return compbranch(1, 1, pcrel19(sa_label, pc), sa_xt)
        })
    }
    // CBNZ  <Xt>, .±<offs>
    if isXr(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(compbranch(1, 1, rel19(ra_pcrel), sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CBNZ")
}

// CBZ instruction have 4 forms across one single category:
//
// 1. Compare and Branch on Zero
//
//    CBZ  <Wt>, <label>
//    CBZ  <Wt>, .±<offs>
//    CBZ  <Xt>, <label>
//    CBZ  <Xt>, .±<offs>
//
// Compare and Branch on Zero compares the value in a register with zero, and
// conditionally branches to a label at a PC-relative offset if the comparison is
// equal. It provides a hint that this is not a subroutine call or return. This
// instruction does not affect condition flags.
//
func (self *Program) CBZ(v0, v1 interface{}) *Instruction {
    p := self.alloc("CBZ", 2, asm.Operands { v0, v1 })
    // CBZ  <Wt>, <label>
    if isWr(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return compbranch(0, 0, pcrel19(sa_label, pc), sa_wt)
        })
    }
    // CBZ  <Wt>, .±<offs>
    if isWr(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(compbranch(0, 0, rel19(ra_pcrel), sa_wt))
    }
    // CBZ  <Xt>, <label>
    if isXr(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return compbranch(1, 0, pcrel19(sa_label, pc), sa_xt)
        })
    }
    // CBZ  <Xt>, .±<offs>
    if isXr(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(compbranch(1, 0, rel19(ra_pcrel), sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CBZ")
}

// CCMN instruction have 4 forms across 2 categories:
//
// 1. Conditional Compare Negative (immediate)
//
//    CCMN  <Wn>, #<imm>, #<nzcv>, <cond>
//    CCMN  <Xn>, #<imm>, #<nzcv>, <cond>
//
// Conditional Compare Negative (immediate) sets the value of the condition flags
// to the result of the comparison of a register value and a negated immediate
// value if the condition is TRUE, and an immediate value otherwise.
//
// 2. Conditional Compare Negative (register)
//
//    CCMN  <Wn>, <Wm>, #<nzcv>, <cond>
//    CCMN  <Xn>, <Xm>, #<nzcv>, <cond>
//
// Conditional Compare Negative (register) sets the value of the condition flags to
// the result of the comparison of a register value and the inverse of another
// register value if the condition is TRUE, and an immediate value otherwise.
//
func (self *Program) CCMN(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("CCMN", 4, asm.Operands { v0, v1, v2, v3 })
    // CCMN  <Wn>, #<imm>, #<nzcv>, <cond>
    if isWr(v0) && isUimm5(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_wn := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm5(v1)
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condcmp_imm(0, 0, 1, sa_imm, sa_cond, 0, sa_wn, 0, sa_nzcv))
    }
    // CCMN  <Xn>, #<imm>, #<nzcv>, <cond>
    if isXr(v0) && isUimm5(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm5(v1)
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condcmp_imm(1, 0, 1, sa_imm, sa_cond, 0, sa_xn, 0, sa_nzcv))
    }
    // CCMN  <Wn>, <Wm>, #<nzcv>, <cond>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_wn := uint32(v0.(asm.Register).ID())
        sa_wm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condcmp_reg(0, 0, 1, sa_wm, sa_cond, 0, sa_wn, 0, sa_nzcv))
    }
    // CCMN  <Xn>, <Xm>, #<nzcv>, <cond>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_xm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condcmp_reg(1, 0, 1, sa_xm, sa_cond, 0, sa_xn, 0, sa_nzcv))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CCMN")
}

// CCMP instruction have 4 forms across 2 categories:
//
// 1. Conditional Compare (immediate)
//
//    CCMP  <Wn>, #<imm>, #<nzcv>, <cond>
//    CCMP  <Xn>, #<imm>, #<nzcv>, <cond>
//
// Conditional Compare (immediate) sets the value of the condition flags to the
// result of the comparison of a register value and an immediate value if the
// condition is TRUE, and an immediate value otherwise.
//
// 2. Conditional Compare (register)
//
//    CCMP  <Wn>, <Wm>, #<nzcv>, <cond>
//    CCMP  <Xn>, <Xm>, #<nzcv>, <cond>
//
// Conditional Compare (register) sets the value of the condition flags to the
// result of the comparison of two registers if the condition is TRUE, and an
// immediate value otherwise.
//
func (self *Program) CCMP(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("CCMP", 4, asm.Operands { v0, v1, v2, v3 })
    // CCMP  <Wn>, #<imm>, #<nzcv>, <cond>
    if isWr(v0) && isUimm5(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_wn := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm5(v1)
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condcmp_imm(0, 1, 1, sa_imm, sa_cond, 0, sa_wn, 0, sa_nzcv))
    }
    // CCMP  <Xn>, #<imm>, #<nzcv>, <cond>
    if isXr(v0) && isUimm5(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm5(v1)
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condcmp_imm(1, 1, 1, sa_imm, sa_cond, 0, sa_xn, 0, sa_nzcv))
    }
    // CCMP  <Wn>, <Wm>, #<nzcv>, <cond>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_wn := uint32(v0.(asm.Register).ID())
        sa_wm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condcmp_reg(0, 1, 1, sa_wm, sa_cond, 0, sa_wn, 0, sa_nzcv))
    }
    // CCMP  <Xn>, <Xm>, #<nzcv>, <cond>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_xm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condcmp_reg(1, 1, 1, sa_xm, sa_cond, 0, sa_xn, 0, sa_nzcv))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CCMP")
}

// CFINV instruction have one single form across one single category:
//
// 1. Invert Carry Flag
//
//    CFINV
//
// Invert Carry Flag. This instruction inverts the value of the PSTATE.C flag.
//
func (self *Program) CFINV() *Instruction {
    p := self.alloc("CFINV", 0, asm.Operands {})
    self.Arch.Require(FEAT_FlagM)
    p.Domain = DomainSystem
    return p.setins(pstate(0, 0, 0, 31))
}

// CFP instruction have one single form across one single category:
//
// 1. Control Flow Prediction Restriction by Context
//
//    CFP  RCTX, <Xt>
//
// Control Flow Prediction Restriction by Context prevents control flow predictions
// that predict execution addresses based on information gathered from earlier
// execution within a particular execution context. Control flow predictions
// determined by the actions of code in the target execution context or contexts
// appearing in program order before the instruction cannot be used to
// exploitatively control speculative execution occurring after the instruction is
// complete and synchronized.
//
// For more information, see CFP RCTX, Control Flow Prediction Restriction by
// Context .
//
func (self *Program) CFP(v0, v1 interface{}) *Instruction {
    p := self.alloc("CFP", 2, asm.Operands { v0, v1 })
    if v0 == RCTX && isXr(v1) {
        self.Arch.Require(FEAT_SPECRES)
        p.Domain = DomainSystem
        sa_xt_1 := uint32(v1.(asm.Register).ID())
        return p.setins(systeminstrs(0, 3, 7, 3, 4, sa_xt_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CFP")
}

// CHKFEAT instruction have one single form across one single category:
//
// 1. Check feature status
//
//    CHKFEAT X16
//
// Check feature status. This instruction indicates the status of features.
//
// If FEAT_CHK is not implemented, this instruction executes as a NOP .
//
func (self *Program) CHKFEAT(v0 interface{}) *Instruction {
    p := self.alloc("CHKFEAT", 1, asm.Operands { v0 })
    if v0 == X16 {
        self.Arch.Require(FEAT_CHK)
        p.Domain = DomainSystem
        return p.setins(hints(5, 0))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CHKFEAT")
}

// CINC instruction have 2 forms across one single category:
//
// 1. Conditional Increment
//
//    CINC  <Wd>, <Wn>, <cond>
//    CINC  <Xd>, <Xn>, <cond>
//
// Conditional Increment returns, in the destination register, the value of the
// source register incremented by 1 if the condition is TRUE, and otherwise returns
// the value of the source register.
//
func (self *Program) CINC(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CINC", 3, asm.Operands { v0, v1, v2 })
    // CINC  <Wd>, <Wn>, <cond>
    if isWr(v0) && isWr(v1) && isBrCond(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn_1 := uint32(v1.(asm.Register).ID())
        sa_cond_1 := uint32(v2.(ConditionCode) ^ 1)
        return p.setins(condsel(0, 0, 0, ubfx(sa_wn_1, 5, 5), sa_cond_1, 1, mask(sa_wn_1, 5), sa_wd))
    }
    // CINC  <Xd>, <Xn>, <cond>
    if isXr(v0) && isXr(v1) && isBrCond(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_cond_1 := uint32(v2.(ConditionCode) ^ 1)
        return p.setins(condsel(1, 0, 0, ubfx(sa_xn_1, 5, 5), sa_cond_1, 1, mask(sa_xn_1, 5), sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CINC")
}

// CINV instruction have 2 forms across one single category:
//
// 1. Conditional Invert
//
//    CINV  <Wd>, <Wn>, <cond>
//    CINV  <Xd>, <Xn>, <cond>
//
// Conditional Invert returns, in the destination register, the bitwise inversion
// of the value of the source register if the condition is TRUE, and otherwise
// returns the value of the source register.
//
func (self *Program) CINV(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CINV", 3, asm.Operands { v0, v1, v2 })
    // CINV  <Wd>, <Wn>, <cond>
    if isWr(v0) && isWr(v1) && isBrCond(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn_1 := uint32(v1.(asm.Register).ID())
        sa_cond_1 := uint32(v2.(ConditionCode) ^ 1)
        return p.setins(condsel(0, 1, 0, ubfx(sa_wn_1, 5, 5), sa_cond_1, 0, mask(sa_wn_1, 5), sa_wd))
    }
    // CINV  <Xd>, <Xn>, <cond>
    if isXr(v0) && isXr(v1) && isBrCond(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_cond_1 := uint32(v2.(ConditionCode) ^ 1)
        return p.setins(condsel(1, 1, 0, ubfx(sa_xn_1, 5, 5), sa_cond_1, 0, mask(sa_xn_1, 5), sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CINV")
}

// CLRBHB instruction have one single form across one single category:
//
// 1. Clear Branch History
//
//    CLRBHB
//
// Clear Branch History clears the branch history for the current context to the
// extent that branch history information created before the CLRBHB instruction
// cannot be used by code before the CLRBHB instruction to exploitatively control
// the execution of any indirect branches in code in the current context that
// appear in program order after the instruction.
//
func (self *Program) CLRBHB() *Instruction {
    p := self.alloc("CLRBHB", 0, asm.Operands {})
    self.Arch.Require(FEAT_CLRBHB)
    p.Domain = DomainSystem
    return p.setins(hints(2, 6))
}

// CLREX instruction have one single form across one single category:
//
// 1. Clear Exclusive
//
//    CLREX  {#<imm>}
//
// Clear Exclusive clears the local monitor of the executing PE.
//
func (self *Program) CLREX(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("CLREX", 0, asm.Operands {})
        case 1  : p = self.alloc("CLREX", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction CLREX takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isInRange(vv[0], 0, 15)) {
        p.Domain = DomainSystem
        sa_imm := uint32(15)
        if len(vv) >= 1 {
            sa_imm = asUimm4(vv[0])
        }
        return p.setins(barriers(sa_imm, 2, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CLREX")
}

// CLS instruction have 3 forms across 2 categories:
//
// 1. Count Leading Sign bits (vector)
//
//    CLS  <Vd>.<T>, <Vn>.<T>
//
// Count Leading Sign bits (vector). This instruction counts the number of
// consecutive bits following the most significant bit that are the same as the
// most significant bit in each vector element in the source SIMD&FP register,
// places the result into a vector, and writes the vector to the destination
// SIMD&FP register. The count does not include the most significant bit itself.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Count Leading Sign bits
//
//    CLS  <Wd>, <Wn>
//    CLS  <Xd>, <Xn>
//
// Count Leading Sign bits counts the number of leading bits of the source register
// that have the same value as the most significant bit of the register, and writes
// the result to the destination register. This count does not include the most
// significant bit of the source register.
//
func (self *Program) CLS(v0, v1 interface{}) *Instruction {
    p := self.alloc("CLS", 2, asm.Operands { v0, v1 })
    // CLS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 4, sa_vn, sa_vd))
    }
    // CLS  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(0, 0, 0, 5, sa_wn, sa_wd))
    }
    // CLS  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 5, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CLS")
}

// CLZ instruction have 3 forms across 2 categories:
//
// 1. Count Leading Zero bits (vector)
//
//    CLZ  <Vd>.<T>, <Vn>.<T>
//
// Count Leading Zero bits (vector). This instruction counts the number of
// consecutive zeros, starting from the most significant bit, in each vector
// element in the source SIMD&FP register, places the result into a vector, and
// writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Count Leading Zeros
//
//    CLZ  <Wd>, <Wn>
//    CLZ  <Xd>, <Xn>
//
// Count Leading Zeros counts the number of consecutive binary zero bits, starting
// from the most significant bit in the source register, and places the count in
// the destination register.
//
func (self *Program) CLZ(v0, v1 interface{}) *Instruction {
    p := self.alloc("CLZ", 2, asm.Operands { v0, v1 })
    // CLZ  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 4, sa_vn, sa_vd))
    }
    // CLZ  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(0, 0, 0, 4, sa_wn, sa_wd))
    }
    // CLZ  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 4, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CLZ")
}

// CMEQ instruction have 4 forms across 2 categories:
//
// 1. Compare bitwise Equal (vector)
//
//    CMEQ  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    CMEQ  <V><d>, <V><n>, <V><m>
//
// Compare bitwise Equal (vector). This instruction compares each vector element
// from the first source SIMD&FP register with the corresponding vector element
// from the second source SIMD&FP register, and if the comparison is equal sets
// every bit of the corresponding vector element in the destination SIMD&FP
// register to one, otherwise sets every bit of the corresponding vector element in
// the destination SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Compare bitwise Equal to zero (vector)
//
//    CMEQ  <Vd>.<T>, <Vn>.<T>, #0
//    CMEQ  <V><d>, <V><n>, #0
//
// Compare bitwise Equal to zero (vector). This instruction reads each vector
// element in the source SIMD&FP register and if the value is equal to zero sets
// every bit of the corresponding vector element in the destination SIMD&FP
// register to one, otherwise sets every bit of the corresponding vector element in
// the destination SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) CMEQ(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CMEQ", 3, asm.Operands { v0, v1, v2 })
    // CMEQ  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 17, sa_vn, sa_vd))
    }
    // CMEQ  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMEQ")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 17, sa_n, sa_d))
    }
    // CMEQ  <Vd>.<T>, <Vn>.<T>, #0
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isIntLit(v2, 0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 9, sa_vn, sa_vd))
    }
    // CMEQ  <V><d>, <V><n>, #0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isIntLit(v2, 0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMEQ")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(0, sa_v, 9, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMEQ")
}

// CMGE instruction have 4 forms across 2 categories:
//
// 1. Compare signed Greater than or Equal (vector)
//
//    CMGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    CMGE  <V><d>, <V><n>, <V><m>
//
// Compare signed Greater than or Equal (vector). This instruction compares each
// vector element in the first source SIMD&FP register with the corresponding
// vector element in the second source SIMD&FP register and if the first signed
// integer value is greater than or equal to the second signed integer value sets
// every bit of the corresponding vector element in the destination SIMD&FP
// register to one, otherwise sets every bit of the corresponding vector element in
// the destination SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Compare signed Greater than or Equal to zero (vector)
//
//    CMGE  <Vd>.<T>, <Vn>.<T>, #0
//    CMGE  <V><d>, <V><n>, #0
//
// Compare signed Greater than or Equal to zero (vector). This instruction reads
// each vector element in the source SIMD&FP register and if the signed integer
// value is greater than or equal to zero sets every bit of the corresponding
// vector element in the destination SIMD&FP register to one, otherwise sets every
// bit of the corresponding vector element in the destination SIMD&FP register to
// zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) CMGE(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CMGE", 3, asm.Operands { v0, v1, v2 })
    // CMGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 7, sa_vn, sa_vd))
    }
    // CMGE  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMGE")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 7, sa_n, sa_d))
    }
    // CMGE  <Vd>.<T>, <Vn>.<T>, #0
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isIntLit(v2, 0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 8, sa_vn, sa_vd))
    }
    // CMGE  <V><d>, <V><n>, #0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isIntLit(v2, 0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMGE")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(1, sa_v, 8, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMGE")
}

// CMGT instruction have 4 forms across 2 categories:
//
// 1. Compare signed Greater than (vector)
//
//    CMGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    CMGT  <V><d>, <V><n>, <V><m>
//
// Compare signed Greater than (vector). This instruction compares each vector
// element in the first source SIMD&FP register with the corresponding vector
// element in the second source SIMD&FP register and if the first signed integer
// value is greater than the second signed integer value sets every bit of the
// corresponding vector element in the destination SIMD&FP register to one,
// otherwise sets every bit of the corresponding vector element in the destination
// SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Compare signed Greater than zero (vector)
//
//    CMGT  <Vd>.<T>, <Vn>.<T>, #0
//    CMGT  <V><d>, <V><n>, #0
//
// Compare signed Greater than zero (vector). This instruction reads each vector
// element in the source SIMD&FP register and if the signed integer value is
// greater than zero sets every bit of the corresponding vector element in the
// destination SIMD&FP register to one, otherwise sets every bit of the
// corresponding vector element in the destination SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) CMGT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CMGT", 3, asm.Operands { v0, v1, v2 })
    // CMGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 6, sa_vn, sa_vd))
    }
    // CMGT  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMGT")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 6, sa_n, sa_d))
    }
    // CMGT  <Vd>.<T>, <Vn>.<T>, #0
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isIntLit(v2, 0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 8, sa_vn, sa_vd))
    }
    // CMGT  <V><d>, <V><n>, #0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isIntLit(v2, 0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMGT")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(0, sa_v, 8, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMGT")
}

// CMHI instruction have 2 forms across one single category:
//
// 1. Compare unsigned Higher (vector)
//
//    CMHI  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    CMHI  <V><d>, <V><n>, <V><m>
//
// Compare unsigned Higher (vector). This instruction compares each vector element
// in the first source SIMD&FP register with the corresponding vector element in
// the second source SIMD&FP register and if the first unsigned integer value is
// greater than the second unsigned integer value sets every bit of the
// corresponding vector element in the destination SIMD&FP register to one,
// otherwise sets every bit of the corresponding vector element in the destination
// SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) CMHI(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CMHI", 3, asm.Operands { v0, v1, v2 })
    // CMHI  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 6, sa_vn, sa_vd))
    }
    // CMHI  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMHI")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 6, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMHI")
}

// CMHS instruction have 2 forms across one single category:
//
// 1. Compare unsigned Higher or Same (vector)
//
//    CMHS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    CMHS  <V><d>, <V><n>, <V><m>
//
// Compare unsigned Higher or Same (vector). This instruction compares each vector
// element in the first source SIMD&FP register with the corresponding vector
// element in the second source SIMD&FP register and if the first unsigned integer
// value is greater than or equal to the second unsigned integer value sets every
// bit of the corresponding vector element in the destination SIMD&FP register to
// one, otherwise sets every bit of the corresponding vector element in the
// destination SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) CMHS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CMHS", 3, asm.Operands { v0, v1, v2 })
    // CMHS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 7, sa_vn, sa_vd))
    }
    // CMHS  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMHS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 7, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMHS")
}

// CMLE instruction have 2 forms across one single category:
//
// 1. Compare signed Less than or Equal to zero (vector)
//
//    CMLE  <Vd>.<T>, <Vn>.<T>, #0
//    CMLE  <V><d>, <V><n>, #0
//
// Compare signed Less than or Equal to zero (vector). This instruction reads each
// vector element in the source SIMD&FP register and if the signed integer value is
// less than or equal to zero sets every bit of the corresponding vector element in
// the destination SIMD&FP register to one, otherwise sets every bit of the
// corresponding vector element in the destination SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) CMLE(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CMLE", 3, asm.Operands { v0, v1, v2 })
    // CMLE  <Vd>.<T>, <Vn>.<T>, #0
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isIntLit(v2, 0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 9, sa_vn, sa_vd))
    }
    // CMLE  <V><d>, <V><n>, #0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isIntLit(v2, 0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMLE")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(1, sa_v, 9, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMLE")
}

// CMLT instruction have 2 forms across one single category:
//
// 1. Compare signed Less than zero (vector)
//
//    CMLT  <Vd>.<T>, <Vn>.<T>, #0
//    CMLT  <V><d>, <V><n>, #0
//
// Compare signed Less than zero (vector). This instruction reads each vector
// element in the source SIMD&FP register and if the signed integer value is less
// than zero sets every bit of the corresponding vector element in the destination
// SIMD&FP register to one, otherwise sets every bit of the corresponding vector
// element in the destination SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) CMLT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CMLT", 3, asm.Operands { v0, v1, v2 })
    // CMLT  <Vd>.<T>, <Vn>.<T>, #0
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isIntLit(v2, 0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 10, sa_vn, sa_vd))
    }
    // CMLT  <V><d>, <V><n>, #0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isIntLit(v2, 0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMLT")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(0, sa_v, 10, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMLT")
}

// CMN instruction have 8 forms across 3 categories:
//
// 1. Compare Negative (extended register)
//
//    CMN  <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
//    CMN  <Xn|SP>, <R><m>{, <extend> {#<amount>}}
//
// Compare Negative (extended register) adds a register value and a sign or zero-
// extended register value, followed by an optional left shift amount. The argument
// that is extended from the <Rm> register can be a byte, halfword, word, or
// doubleword. It updates the condition flags based on the result, and discards the
// result.
//
// 2. Compare Negative (immediate)
//
//    CMN  <Wn|WSP>, #<imm>{, <shift>}
//    CMN  <Wn|WSP>, <label>{, <shift>}
//    CMN  <Xn|SP>, #<imm>{, <shift>}
//    CMN  <Xn|SP>, <label>{, <shift>}
//
// Compare Negative (immediate) adds a register value and an optionally-shifted
// immediate value. It updates the condition flags based on the result, and
// discards the result.
//
// 3. Compare Negative (shifted register)
//
//    CMN  <Wn>, <Wm>{, <shift> #<amount>}
//    CMN  <Xn>, <Xm>{, <shift> #<amount>}
//
// Compare Negative (shifted register) adds a register value and an optionally-
// shifted register value. It updates the condition flags based on the result, and
// discards the result.
//
func (self *Program) CMN(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("CMN", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("CMN", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction CMN takes 2 or 3 operands")
    }
    // CMN  <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isWr(v1) &&
       (len(vv) == 0 && v0 == WSP || len(vv) == 1 && modt(vv[0]) == ModUXTW) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend := uint32(0b010)
        sa_wn_wsp := uint32(v0.(asm.Register).ID())
        sa_wm := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend = 0b000
                case ModUXTH: sa_extend = 0b001
                case ModLSL: sa_extend = 0b010
                case ModUXTW: sa_extend = 0b010
                case ModUXTX: sa_extend = 0b011
                case ModSXTB: sa_extend = 0b100
                case ModSXTH: sa_extend = 0b101
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_ext(0, 0, 1, 0, sa_wm, sa_extend, sa_amount, sa_wn_wsp, 31))
    }
    // CMN  <Xn|SP>, <R><m>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isWrOrXr(v1) &&
       (len(vv) == 0 && v0 == SP || len(vv) == 1 && modt(vv[0]) == ModUXTX) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend_1 := uint32(0b011)
        var sa_r [4]uint32
        var sa_r__bit_mask [4]uint32
        sa_xn_sp := uint32(v0.(asm.Register).ID())
        sa_m := uint32(v1.(asm.Register).ID())
        switch true {
            case isWr(v1): sa_r = [4]uint32{0b000, 0b010, 0b100, 0b110}
            case isXr(v1): sa_r = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        switch true {
            case isWr(v1): sa_r__bit_mask = [4]uint32{0b110, 0b111, 0b110, 0b111}
            case isXr(v1): sa_r__bit_mask = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend_1 = 0b000
                case ModUXTH: sa_extend_1 = 0b001
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModUXTX: sa_extend_1 = 0b011
                case ModSXTB: sa_extend_1 = 0b100
                case ModSXTH: sa_extend_1 = 0b101
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        if !matchany(sa_extend_1, &sa_r[0], &sa_r__bit_mask[0], 4) {
            panic("aarch64: invalid combination of operands for CMN")
        }
        return p.setins(addsub_ext(1, 0, 1, 0, sa_m, sa_extend_1, sa_amount, sa_xn_sp, 31))
    }
    // CMN  <Wn|WSP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isInRange(v1, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wn_wsp := uint32(v0.(asm.Register).ID())
        sa_imm := asImm12(v1)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(0, 0, 1, sa_shift, sa_imm, sa_wn_wsp, 31))
    }
    // CMN  <Wn|WSP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isLabel(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wn_wsp := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(0, 0, 1, sa_shift, abs12(sa_label), sa_wn_wsp, 31)
        })
    }
    // CMN  <Xn|SP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isInRange(v1, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xn_sp := uint32(v0.(asm.Register).ID())
        sa_imm := asImm12(v1)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(1, 0, 1, sa_shift, sa_imm, sa_xn_sp, 31))
    }
    // CMN  <Xn|SP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isLabel(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xn_sp := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(1, 0, 1, sa_shift, abs12(sa_label), sa_xn_sp, 31)
        })
    }
    // CMN  <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wn := uint32(v0.(asm.Register).ID())
        sa_wm := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(0, 0, 1, sa_shift, sa_wm, sa_amount, sa_wn, 31))
    }
    // CMN  <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_xm := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(1, 0, 1, sa_shift, sa_xm, sa_amount_1, sa_xn, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMN")
}

// CMP instruction have 8 forms across 3 categories:
//
// 1. Compare (extended register)
//
//    CMP  <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
//    CMP  <Xn|SP>, <R><m>{, <extend> {#<amount>}}
//
// Compare (extended register) subtracts a sign or zero-extended register value,
// followed by an optional left shift amount, from a register value. The argument
// that is extended from the <Rm> register can be a byte, halfword, word, or
// doubleword. It updates the condition flags based on the result, and discards the
// result.
//
// 2. Compare (immediate)
//
//    CMP  <Wn|WSP>, #<imm>{, <shift>}
//    CMP  <Wn|WSP>, <label>{, <shift>}
//    CMP  <Xn|SP>, #<imm>{, <shift>}
//    CMP  <Xn|SP>, <label>{, <shift>}
//
// Compare (immediate) subtracts an optionally-shifted immediate value from a
// register value. It updates the condition flags based on the result, and discards
// the result.
//
// 3. Compare (shifted register)
//
//    CMP  <Wn>, <Wm>{, <shift> #<amount>}
//    CMP  <Xn>, <Xm>{, <shift> #<amount>}
//
// Compare (shifted register) subtracts an optionally-shifted register value from a
// register value. It updates the condition flags based on the result, and discards
// the result.
//
func (self *Program) CMP(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("CMP", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("CMP", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction CMP takes 2 or 3 operands")
    }
    // CMP  <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isWr(v1) &&
       (len(vv) == 0 && v0 == WSP || len(vv) == 1 && modt(vv[0]) == ModUXTW) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend := uint32(0b010)
        sa_wn_wsp := uint32(v0.(asm.Register).ID())
        sa_wm := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend = 0b000
                case ModUXTH: sa_extend = 0b001
                case ModLSL: sa_extend = 0b010
                case ModUXTW: sa_extend = 0b010
                case ModUXTX: sa_extend = 0b011
                case ModSXTB: sa_extend = 0b100
                case ModSXTH: sa_extend = 0b101
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_ext(0, 1, 1, 0, sa_wm, sa_extend, sa_amount, sa_wn_wsp, 31))
    }
    // CMP  <Xn|SP>, <R><m>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isWrOrXr(v1) &&
       (len(vv) == 0 && v0 == SP || len(vv) == 1 && modt(vv[0]) == ModUXTX) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend_1 := uint32(0b011)
        var sa_r [4]uint32
        var sa_r__bit_mask [4]uint32
        sa_xn_sp := uint32(v0.(asm.Register).ID())
        sa_m := uint32(v1.(asm.Register).ID())
        switch true {
            case isWr(v1): sa_r = [4]uint32{0b000, 0b010, 0b100, 0b110}
            case isXr(v1): sa_r = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        switch true {
            case isWr(v1): sa_r__bit_mask = [4]uint32{0b110, 0b111, 0b110, 0b111}
            case isXr(v1): sa_r__bit_mask = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend_1 = 0b000
                case ModUXTH: sa_extend_1 = 0b001
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModUXTX: sa_extend_1 = 0b011
                case ModSXTB: sa_extend_1 = 0b100
                case ModSXTH: sa_extend_1 = 0b101
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        if !matchany(sa_extend_1, &sa_r[0], &sa_r__bit_mask[0], 4) {
            panic("aarch64: invalid combination of operands for CMP")
        }
        return p.setins(addsub_ext(1, 1, 1, 0, sa_m, sa_extend_1, sa_amount, sa_xn_sp, 31))
    }
    // CMP  <Wn|WSP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isInRange(v1, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wn_wsp := uint32(v0.(asm.Register).ID())
        sa_imm := asImm12(v1)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(0, 1, 1, sa_shift, sa_imm, sa_wn_wsp, 31))
    }
    // CMP  <Wn|WSP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isLabel(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wn_wsp := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(0, 1, 1, sa_shift, abs12(sa_label), sa_wn_wsp, 31)
        })
    }
    // CMP  <Xn|SP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isInRange(v1, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xn_sp := uint32(v0.(asm.Register).ID())
        sa_imm := asImm12(v1)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(1, 1, 1, sa_shift, sa_imm, sa_xn_sp, 31))
    }
    // CMP  <Xn|SP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isLabel(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xn_sp := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(1, 1, 1, sa_shift, abs12(sa_label), sa_xn_sp, 31)
        })
    }
    // CMP  <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wn := uint32(v0.(asm.Register).ID())
        sa_wm := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(0, 1, 1, sa_shift, sa_wm, sa_amount, sa_wn, 31))
    }
    // CMP  <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_xm := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(1, 1, 1, sa_shift, sa_xm, sa_amount_1, sa_xn, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMP")
}

// CMPP instruction have one single form across one single category:
//
// 1. Compare with Tag
//
//    CMPP  <Xn|SP>, <Xm|SP>
//
// Compare with Tag subtracts the 56-bit address held in the second source register
// from the 56-bit address held in the first source register, updates the condition
// flags based on the result of the subtraction, and discards the result.
//
func (self *Program) CMPP(v0, v1 interface{}) *Instruction {
    p := self.alloc("CMPP", 2, asm.Operands { v0, v1 })
    if isXrOrSP(v0) && isXrOrSP(v1) && (v0 == SP || v1 == SP) {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xn_sp := uint32(v0.(asm.Register).ID())
        sa_xm_sp := uint32(v1.(asm.Register).ID())
        Rm := uint32(0b00000)
        Rm |= sa_xm_sp
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        return p.setins(dp_2src(1, 1, Rm, 0, Rn, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CMPP")
}

// CMTST instruction have 2 forms across one single category:
//
// 1. Compare bitwise Test bits nonzero (vector)
//
//    CMTST  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    CMTST  <V><d>, <V><n>, <V><m>
//
// Compare bitwise Test bits nonzero (vector). This instruction reads each vector
// element in the first source SIMD&FP register, performs an AND with the
// corresponding vector element in the second source SIMD&FP register, and if the
// result is not zero, sets every bit of the corresponding vector element in the
// destination SIMD&FP register to one, otherwise sets every bit of the
// corresponding vector element in the destination SIMD&FP register to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) CMTST(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CMTST", 3, asm.Operands { v0, v1, v2 })
    // CMTST  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 17, sa_vn, sa_vd))
    }
    // CMTST  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for CMTST")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 17, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CMTST")
}

// CNEG instruction have 2 forms across one single category:
//
// 1. Conditional Negate
//
//    CNEG  <Wd>, <Wn>, <cond>
//    CNEG  <Xd>, <Xn>, <cond>
//
// Conditional Negate returns, in the destination register, the negated value of
// the source register if the condition is TRUE, and otherwise returns the value of
// the source register.
//
func (self *Program) CNEG(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CNEG", 3, asm.Operands { v0, v1, v2 })
    // CNEG  <Wd>, <Wn>, <cond>
    if isWr(v0) && isWr(v1) && isBrCond(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn_1 := uint32(v1.(asm.Register).ID())
        sa_cond_1 := uint32(v2.(ConditionCode) ^ 1)
        return p.setins(condsel(0, 1, 0, ubfx(sa_wn_1, 5, 5), sa_cond_1, 1, mask(sa_wn_1, 5), sa_wd))
    }
    // CNEG  <Xd>, <Xn>, <cond>
    if isXr(v0) && isXr(v1) && isBrCond(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_cond_1 := uint32(v2.(ConditionCode) ^ 1)
        return p.setins(condsel(1, 1, 0, ubfx(sa_xn_1, 5, 5), sa_cond_1, 1, mask(sa_xn_1, 5), sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CNEG")
}

// CNT instruction have 3 forms across 2 categories:
//
// 1. Count bits
//
//    CNT  <Wd>, <Wn>
//    CNT  <Xd>, <Xn>
//
// Count bits counts the number of binary one bits in the value of the source
// register, and writes the result to the destination register.
//
// 2. Population Count per byte
//
//    CNT  <Vd>.<T>, <Vn>.<T>
//
// Population Count per byte. This instruction counts the number of bits that have
// a value of one in each vector element in the source SIMD&FP register, places the
// result into a vector, and writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) CNT(v0, v1 interface{}) *Instruction {
    p := self.alloc("CNT", 2, asm.Operands { v0, v1 })
    // CNT  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(0, 0, 0, 7, sa_wn, sa_wd))
    }
    // CNT  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 7, sa_xn, sa_xd))
    }
    // CNT  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec8B, Vec16B) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B) && vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 5, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CNT")
}

// COSP instruction have one single form across one single category:
//
// 1. Clear Other Speculative Predictions by Context
//
//    COSP  RCTX, <Xt>
//
// Clear Other Speculative Predictions by Context prevents predictions, other than
// Cache prefetch, Control flow, and Data Value predictions, that predict execution
// addresses based on information gathered from earlier execution within a
// particular execution context. Predictions, other than Cache prefetch, Control
// flow, and Data Value predictions, determined by the actions of code in the
// target execution context or contexts appearing in program order before the
// instruction cannot exploitatively control any speculative access occurring after
// the instruction is complete and synchronized.
//
func (self *Program) COSP(v0, v1 interface{}) *Instruction {
    p := self.alloc("COSP", 2, asm.Operands { v0, v1 })
    if v0 == RCTX && isXr(v1) {
        self.Arch.Require(FEAT_SPECRES2)
        p.Domain = DomainSystem
        sa_xt_1 := uint32(v1.(asm.Register).ID())
        return p.setins(systeminstrs(0, 3, 7, 3, 6, sa_xt_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for COSP")
}

// CPP instruction have one single form across one single category:
//
// 1. Cache Prefetch Prediction Restriction by Context
//
//    CPP  RCTX, <Xt>
//
// Cache Prefetch Prediction Restriction by Context prevents cache allocation
// predictions that predict execution addresses based on information gathered from
// earlier execution within a particular execution context. The actions of code in
// the target execution context or contexts appearing in program order before the
// instruction cannot exploitatively control cache prefetch predictions occurring
// after the instruction is complete and synchronized.
//
// For more information, see CPP RCTX, Cache Prefetch Prediction Restriction by
// Context .
//
func (self *Program) CPP(v0, v1 interface{}) *Instruction {
    p := self.alloc("CPP", 2, asm.Operands { v0, v1 })
    if v0 == RCTX && isXr(v1) {
        self.Arch.Require(FEAT_SPECRES)
        p.Domain = DomainSystem
        sa_xt_1 := uint32(v1.(asm.Register).ID())
        return p.setins(systeminstrs(0, 3, 7, 3, 7, sa_xt_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPP")
}

// CPYE instruction have one single form across one single category:
//
// 1. Memory Copy
//
//    CPYE  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy. These instructions perform a memory copy. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: CPYP, then CPYM, and then CPYE.
//
// CPYP performs some preconditioning of the arguments suitable for using the CPYM
// instruction, and performs an implementation defined amount of the memory copy.
// CPYM performs an implementation defined amount of the memory copy. CPYE performs
// the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYP, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYP, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYP, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is copied to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is made to.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from.
//         * Xd holds the highest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYE(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYE", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 0, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYE")
}

// CPYEN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes non-temporal
//
//    CPYEN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes non-temporal. These instructions perform a memory
// copy. The prologue, main, and epilogue instructions are expected to be run in
// succession and to appear consecutively in memory: CPYPN, then CPYMN, and then
// CPYEN.
//
// CPYPN performs some preconditioning of the arguments suitable for using the
// CPYMN instruction, and performs an implementation defined amount of the memory
// copy. CPYMN performs an implementation defined amount of the memory copy. CPYEN
// performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYEN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYEN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 12, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYEN")
}

// CPYERN instruction have one single form across one single category:
//
// 1. Memory Copy, reads non-temporal
//
//    CPYERN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads non-temporal. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPRN, then CPYMRN, and then CPYERN.
//
// CPYPRN performs some preconditioning of the arguments suitable for using the
// CPYMRN instruction, and performs an implementation defined amount of the memory
// copy. CPYMRN performs an implementation defined amount of the memory copy.
// CPYERN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYERN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYERN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 8, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYERN")
}

// CPYERT instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged
//
//    CPYERT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPRT, then CPYMRT, and then CPYERT.
//
// CPYPRT performs some preconditioning of the arguments suitable for using the
// CPYMRT instruction, and performs an implementation defined amount of the memory
// copy. CPYMRT performs an implementation defined amount of the memory copy.
// CPYERT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRT, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRT, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRT, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYERT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYERT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 2, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYERT")
}

// CPYERTN instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged, reads and writes non-temporal
//
//    CPYERTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged, reads and writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPRTN, then CPYMRTN, and then CPYERTN.
//
// CPYPRTN performs some preconditioning of the arguments suitable for using the
// CPYMRTN instruction, and performs an implementation defined amount of the memory
// copy. CPYMRTN performs an implementation defined amount of the memory copy.
// CPYERTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRTN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRTN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYERTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYERTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 14, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYERTN")
}

// CPYERTRN instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged and non-temporal
//
//    CPYERTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged and non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPRTRN, then
// CPYMRTRN, and then CPYERTRN.
//
// CPYPRTRN performs some preconditioning of the arguments suitable for using the
// CPYMRTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYMRTRN performs an implementation defined amount of the memory
// copy. CPYERTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRTRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYERTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYERTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 10, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYERTRN")
}

// CPYERTWN instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged, writes non-temporal
//
//    CPYERTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged, writes non-temporal. These instructions perform
// a memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPRTWN, then
// CPYMRTWN, and then CPYERTWN.
//
// CPYPRTWN performs some preconditioning of the arguments suitable for using the
// CPYMRTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYMRTWN performs an implementation defined amount of the memory
// copy. CPYERTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRTWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYERTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYERTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 6, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYERTWN")
}

// CPYET instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged
//
//    CPYET  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged. These instructions perform a memory
// copy. The prologue, main, and epilogue instructions are expected to be run in
// succession and to appear consecutively in memory: CPYPT, then CPYMT, and then
// CPYET.
//
// CPYPT performs some preconditioning of the arguments suitable for using the
// CPYMT instruction, and performs an implementation defined amount of the memory
// copy. CPYMT performs an implementation defined amount of the memory copy. CPYET
// performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPT, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPT, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYET(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYET", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 3, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYET")
}

// CPYETN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged and non-temporal
//
//    CPYETN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged and non-temporal. These instructions
// perform a memory copy. The prologue, main, and epilogue instructions are
// expected to be run in succession and to appear consecutively in memory: CPYPTN,
// then CPYMTN, and then CPYETN.
//
// CPYPTN performs some preconditioning of the arguments suitable for using the
// CPYMTN instruction, and performs an implementation defined amount of the memory
// copy. CPYMTN performs an implementation defined amount of the memory copy.
// CPYETN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPTN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYETN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYETN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 15, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYETN")
}

// CPYETRN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged, reads non-temporal
//
//    CPYETRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged, reads non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPTRN, then CPYMTRN, and then CPYETRN.
//
// CPYPTRN performs some preconditioning of the arguments suitable for using the
// CPYMTRN instruction, and performs an implementation defined amount of the memory
// copy. CPYMTRN performs an implementation defined amount of the memory copy.
// CPYETRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPTRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMTRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMTRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYETRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYETRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYETRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYETRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 11, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYETRN")
}

// CPYETWN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged, writes non-temporal
//
//    CPYETWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged, writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPTWN, then CPYMTWN, and then CPYETWN.
//
// CPYPTWN performs some preconditioning of the arguments suitable for using the
// CPYMTWN instruction, and performs an implementation defined amount of the memory
// copy. CPYMTWN performs an implementation defined amount of the memory copy.
// CPYETWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPTWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMTWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMTWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYETWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYETWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYETWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYETWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 7, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYETWN")
}

// CPYEWN instruction have one single form across one single category:
//
// 1. Memory Copy, writes non-temporal
//
//    CPYEWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes non-temporal. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPWN, then CPYMWN, and then CPYEWN.
//
// CPYPWN performs some preconditioning of the arguments suitable for using the
// CPYMWN instruction, and performs an implementation defined amount of the memory
// copy. CPYMWN performs an implementation defined amount of the memory copy.
// CPYEWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYEWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYEWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 4, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYEWN")
}

// CPYEWT instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged
//
//    CPYEWT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPWT, then CPYMWT, and then CPYEWT.
//
// CPYPWT performs some preconditioning of the arguments suitable for using the
// CPYMWT instruction, and performs an implementation defined amount of the memory
// copy. CPYMWT performs an implementation defined amount of the memory copy.
// CPYEWT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWT, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWT, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWT, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYEWT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYEWT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 1, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYEWT")
}

// CPYEWTN instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged, reads and writes non-temporal
//
//    CPYEWTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged, reads and writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPWTN, then CPYMWTN, and then CPYEWTN.
//
// CPYPWTN performs some preconditioning of the arguments suitable for using the
// CPYMWTN instruction, and performs an implementation defined amount of the memory
// copy. CPYMWTN performs an implementation defined amount of the memory copy.
// CPYEWTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWTN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWTN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYEWTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYEWTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 13, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYEWTN")
}

// CPYEWTRN instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged, reads non-temporal
//
//    CPYEWTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged, reads non-temporal. These instructions perform
// a memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPWTRN, then
// CPYMWTRN, and then CPYEWTRN.
//
// CPYPWTRN performs some preconditioning of the arguments suitable for using the
// CPYMWTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYMWTRN performs an implementation defined amount of the memory
// copy. CPYEWTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWTRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYEWTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYEWTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 9, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYEWTRN")
}

// CPYEWTWN instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged and non-temporal
//
//    CPYEWTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged and non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPWTWN, then
// CPYMWTWN, and then CPYEWTWN.
//
// CPYPWTWN performs some preconditioning of the arguments suitable for using the
// CPYMWTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYMWTWN performs an implementation defined amount of the memory
// copy. CPYEWTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWTWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYEWTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYEWTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 2, sa_xs_1, 5, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYEWTWN")
}

// CPYFE instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only
//
//    CPYFE  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYFP, then CPYFM, and then CPYFE.
//
// CPYFP performs some preconditioning of the arguments suitable for using the
// CPYFM instruction, and performs an implementation defined amount of the memory
// copy. CPYFM performs an implementation defined amount of the memory copy. CPYFE
// performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFP, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFP, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFE(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFE", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 0, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFE")
}

// CPYFEN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes non-temporal
//
//    CPYFEN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes non-temporal. These instructions
// perform a memory copy. The prologue, main, and epilogue instructions are
// expected to be run in succession and to appear consecutively in memory: CPYFPN,
// then CPYFMN, and then CPYFEN.
//
// CPYFPN performs some preconditioning of the arguments suitable for using the
// CPYFMN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMN performs an implementation defined amount of the memory copy.
// CPYFEN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFEN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFEN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 12, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFEN")
}

// CPYFERN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads non-temporal
//
//    CPYFERN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPRN, then CPYFMRN,
// and then CPYFERN.
//
// CPYFPRN performs some preconditioning of the arguments suitable for using the
// CPYFMRN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMRN performs an implementation defined amount of the memory copy.
// CPYFERN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFERN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFERN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 8, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFERN")
}

// CPYFERT instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged
//
//    CPYFERT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPRT, then CPYFMRT,
// and then CPYFERT.
//
// CPYFPRT performs some preconditioning of the arguments suitable for using the
// CPYFMRT instruction, and performs an implementation defined amount of the memory
// copy. CPYFMRT performs an implementation defined amount of the memory copy.
// CPYFERT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFERT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFERT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 2, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFERT")
}

// CPYFERTN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged, reads and writes non-temporal
//
//    CPYFERTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged, reads and writes non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPRTN, then CPYFMRTN, and then CPYFERTN.
//
// CPYFPRTN performs some preconditioning of the arguments suitable for using the
// CPYFMRTN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMRTN performs an implementation defined amount of the memory
// copy. CPYFERTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFERTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFERTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 14, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFERTN")
}

// CPYFERTRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged and non-temporal
//
//    CPYFERTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged and non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPRTRN, then CPYFMRTRN, and then CPYFERTRN.
//
// CPYFPRTRN performs some preconditioning of the arguments suitable for using the
// CPYFMRTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMRTRN performs an implementation defined amount of the memory
// copy. CPYFERTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERTRN option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFERTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFERTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 10, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFERTRN")
}

// CPYFERTWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged, writes non-temporal
//
//    CPYFERTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged, writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPRTWN, then CPYFMRTWN, and then CPYFERTWN.
//
// CPYFPRTWN performs some preconditioning of the arguments suitable for using the
// CPYFMRTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMRTWN performs an implementation defined amount of the memory
// copy. CPYFERTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFERTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFERTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 6, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFERTWN")
}

// CPYFET instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged
//
//    CPYFET  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged. These instructions
// perform a memory copy. The prologue, main, and epilogue instructions are
// expected to be run in succession and to appear consecutively in memory: CPYFPT,
// then CPYFMT, and then CPYFET.
//
// CPYFPT performs some preconditioning of the arguments suitable for using the
// CPYFMT instruction, and performs an implementation defined amount of the memory
// copy. CPYFMT performs an implementation defined amount of the memory copy.
// CPYFET performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFET(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFET", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 3, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFET")
}

// CPYFETN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged and non-temporal
//
//    CPYFETN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged and non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPTN, then CPYFMTN, and then CPYFETN.
//
// CPYFPTN performs some preconditioning of the arguments suitable for using the
// CPYFMTN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMTN performs an implementation defined amount of the memory copy.
// CPYFETN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFETN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFETN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 15, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFETN")
}

// CPYFETRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged, reads non-temporal
//
//    CPYFETRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged, reads non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPTRN, then CPYFMTRN, and then CPYFETRN.
//
// CPYFPTRN performs some preconditioning of the arguments suitable for using the
// CPYFMTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMTRN performs an implementation defined amount of the memory
// copy. CPYFETRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFETRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFETRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFETRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFETRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 11, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFETRN")
}

// CPYFETWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged, writes non-temporal
//
//    CPYFETWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged, writes non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPTWN, then CPYFMTWN, and then CPYFETWN.
//
// CPYFPTWN performs some preconditioning of the arguments suitable for using the
// CPYFMTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMTWN performs an implementation defined amount of the memory
// copy. CPYFETWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFETWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFETWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFETWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFETWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 7, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFETWN")
}

// CPYFEWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes non-temporal
//
//    CPYFEWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPWN, then CPYFMWN,
// and then CPYFEWN.
//
// CPYFPWN performs some preconditioning of the arguments suitable for using the
// CPYFMWN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMWN performs an implementation defined amount of the memory copy.
// CPYFEWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFEWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFEWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 4, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFEWN")
}

// CPYFEWT instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged
//
//    CPYFEWT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPWT, then CPYFMWT,
// and then CPYFEWT.
//
// CPYFPWT performs some preconditioning of the arguments suitable for using the
// CPYFMWT instruction, and performs an implementation defined amount of the memory
// copy. CPYFMWT performs an implementation defined amount of the memory copy.
// CPYFEWT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFEWT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFEWT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 1, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFEWT")
}

// CPYFEWTN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged, reads and writes non-temporal
//
//    CPYFEWTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged, reads and writes non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPWTN, then CPYFMWTN, and then CPYFEWTN.
//
// CPYFPWTN performs some preconditioning of the arguments suitable for using the
// CPYFMWTN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMWTN performs an implementation defined amount of the memory
// copy. CPYFEWTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFEWTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFEWTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 13, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFEWTN")
}

// CPYFEWTRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged, reads non-temporal
//
//    CPYFEWTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged, reads non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPWTRN, then CPYFMWTRN, and then CPYFEWTRN.
//
// CPYFPWTRN performs some preconditioning of the arguments suitable for using the
// CPYFMWTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMWTRN performs an implementation defined amount of the memory
// copy. CPYFEWTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFEWTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFEWTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 9, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFEWTRN")
}

// CPYFEWTWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged and non-temporal
//
//    CPYFEWTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged and non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPWTWN, then CPYFMWTWN, and then CPYFEWTWN.
//
// CPYFPWTWN performs some preconditioning of the arguments suitable for using the
// CPYFMWTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMWTWN performs an implementation defined amount of the memory
// copy. CPYFEWTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFEWTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFEWTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_2 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 2, sa_xs_1, 5, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFEWTWN")
}

// CPYFM instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only
//
//    CPYFM  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYFP, then CPYFM, and then CPYFE.
//
// CPYFP performs some preconditioning of the arguments suitable for using the
// CPYFM instruction, and performs an implementation defined amount of the memory
// copy. CPYFM performs an implementation defined amount of the memory copy. CPYFE
// performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFP, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFP, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFM(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFM", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 0, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFM")
}

// CPYFMN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes non-temporal
//
//    CPYFMN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes non-temporal. These instructions
// perform a memory copy. The prologue, main, and epilogue instructions are
// expected to be run in succession and to appear consecutively in memory: CPYFPN,
// then CPYFMN, and then CPYFEN.
//
// CPYFPN performs some preconditioning of the arguments suitable for using the
// CPYFMN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMN performs an implementation defined amount of the memory copy.
// CPYFEN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 12, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMN")
}

// CPYFMRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads non-temporal
//
//    CPYFMRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPRN, then CPYFMRN,
// and then CPYFERN.
//
// CPYFPRN performs some preconditioning of the arguments suitable for using the
// CPYFMRN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMRN performs an implementation defined amount of the memory copy.
// CPYFERN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 8, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMRN")
}

// CPYFMRT instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged
//
//    CPYFMRT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPRT, then CPYFMRT,
// and then CPYFERT.
//
// CPYFPRT performs some preconditioning of the arguments suitable for using the
// CPYFMRT instruction, and performs an implementation defined amount of the memory
// copy. CPYFMRT performs an implementation defined amount of the memory copy.
// CPYFERT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMRT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMRT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 2, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMRT")
}

// CPYFMRTN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged, reads and writes non-temporal
//
//    CPYFMRTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged, reads and writes non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPRTN, then CPYFMRTN, and then CPYFERTN.
//
// CPYFPRTN performs some preconditioning of the arguments suitable for using the
// CPYFMRTN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMRTN performs an implementation defined amount of the memory
// copy. CPYFERTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMRTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMRTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 14, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMRTN")
}

// CPYFMRTRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged and non-temporal
//
//    CPYFMRTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged and non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPRTRN, then CPYFMRTRN, and then CPYFERTRN.
//
// CPYFPRTRN performs some preconditioning of the arguments suitable for using the
// CPYFMRTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMRTRN performs an implementation defined amount of the memory
// copy. CPYFERTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERTRN option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMRTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMRTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 10, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMRTRN")
}

// CPYFMRTWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged, writes non-temporal
//
//    CPYFMRTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged, writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPRTWN, then CPYFMRTWN, and then CPYFERTWN.
//
// CPYFPRTWN performs some preconditioning of the arguments suitable for using the
// CPYFMRTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMRTWN performs an implementation defined amount of the memory
// copy. CPYFERTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMRTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMRTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 6, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMRTWN")
}

// CPYFMT instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged
//
//    CPYFMT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged. These instructions
// perform a memory copy. The prologue, main, and epilogue instructions are
// expected to be run in succession and to appear consecutively in memory: CPYFPT,
// then CPYFMT, and then CPYFET.
//
// CPYFPT performs some preconditioning of the arguments suitable for using the
// CPYFMT instruction, and performs an implementation defined amount of the memory
// copy. CPYFMT performs an implementation defined amount of the memory copy.
// CPYFET performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 3, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMT")
}

// CPYFMTN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged and non-temporal
//
//    CPYFMTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged and non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPTN, then CPYFMTN, and then CPYFETN.
//
// CPYFPTN performs some preconditioning of the arguments suitable for using the
// CPYFMTN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMTN performs an implementation defined amount of the memory copy.
// CPYFETN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 15, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMTN")
}

// CPYFMTRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged, reads non-temporal
//
//    CPYFMTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged, reads non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPTRN, then CPYFMTRN, and then CPYFETRN.
//
// CPYFPTRN performs some preconditioning of the arguments suitable for using the
// CPYFMTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMTRN performs an implementation defined amount of the memory
// copy. CPYFETRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFETRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFETRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 11, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMTRN")
}

// CPYFMTWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged, writes non-temporal
//
//    CPYFMTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged, writes non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPTWN, then CPYFMTWN, and then CPYFETWN.
//
// CPYFPTWN performs some preconditioning of the arguments suitable for using the
// CPYFMTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMTWN performs an implementation defined amount of the memory
// copy. CPYFETWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFETWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFETWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 7, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMTWN")
}

// CPYFMWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes non-temporal
//
//    CPYFMWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPWN, then CPYFMWN,
// and then CPYFEWN.
//
// CPYFPWN performs some preconditioning of the arguments suitable for using the
// CPYFMWN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMWN performs an implementation defined amount of the memory copy.
// CPYFEWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 4, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMWN")
}

// CPYFMWT instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged
//
//    CPYFMWT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPWT, then CPYFMWT,
// and then CPYFEWT.
//
// CPYFPWT performs some preconditioning of the arguments suitable for using the
// CPYFMWT instruction, and performs an implementation defined amount of the memory
// copy. CPYFMWT performs an implementation defined amount of the memory copy.
// CPYFEWT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMWT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMWT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 1, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMWT")
}

// CPYFMWTN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged, reads and writes non-temporal
//
//    CPYFMWTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged, reads and writes non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPWTN, then CPYFMWTN, and then CPYFEWTN.
//
// CPYFPWTN performs some preconditioning of the arguments suitable for using the
// CPYFMWTN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMWTN performs an implementation defined amount of the memory
// copy. CPYFEWTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMWTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMWTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 13, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMWTN")
}

// CPYFMWTRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged, reads non-temporal
//
//    CPYFMWTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged, reads non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPWTRN, then CPYFMWTRN, and then CPYFEWTRN.
//
// CPYFPWTRN performs some preconditioning of the arguments suitable for using the
// CPYFMWTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMWTRN performs an implementation defined amount of the memory
// copy. CPYFEWTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMWTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMWTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 9, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMWTRN")
}

// CPYFMWTWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged and non-temporal
//
//    CPYFMWTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged and non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPWTWN, then CPYFMWTWN, and then CPYFEWTWN.
//
// CPYFPWTWN performs some preconditioning of the arguments suitable for using the
// CPYFMWTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMWTWN performs an implementation defined amount of the memory
// copy. CPYFEWTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFMWTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFMWTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 1, sa_xs_1, 5, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFMWTWN")
}

// CPYFP instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only
//
//    CPYFP  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYFP, then CPYFM, and then CPYFE.
//
// CPYFP performs some preconditioning of the arguments suitable for using the
// CPYFM instruction, and performs an implementation defined amount of the memory
// copy. CPYFM performs an implementation defined amount of the memory copy. CPYFE
// performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFP, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFP, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFP", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 0, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFP")
}

// CPYFPN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes non-temporal
//
//    CPYFPN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes non-temporal. These instructions
// perform a memory copy. The prologue, main, and epilogue instructions are
// expected to be run in succession and to appear consecutively in memory: CPYFPN,
// then CPYFMN, and then CPYFEN.
//
// CPYFPN performs some preconditioning of the arguments suitable for using the
// CPYFMN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMN performs an implementation defined amount of the memory copy.
// CPYFEN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 12, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPN")
}

// CPYFPRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads non-temporal
//
//    CPYFPRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPRN, then CPYFMRN,
// and then CPYFERN.
//
// CPYFPRN performs some preconditioning of the arguments suitable for using the
// CPYFMRN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMRN performs an implementation defined amount of the memory copy.
// CPYFERN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 8, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPRN")
}

// CPYFPRT instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged
//
//    CPYFPRT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPRT, then CPYFMRT,
// and then CPYFERT.
//
// CPYFPRT performs some preconditioning of the arguments suitable for using the
// CPYFMRT instruction, and performs an implementation defined amount of the memory
// copy. CPYFMRT performs an implementation defined amount of the memory copy.
// CPYFERT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPRT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPRT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 2, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPRT")
}

// CPYFPRTN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged, reads and writes non-temporal
//
//    CPYFPRTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged, reads and writes non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPRTN, then CPYFMRTN, and then CPYFERTN.
//
// CPYFPRTN performs some preconditioning of the arguments suitable for using the
// CPYFMRTN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMRTN performs an implementation defined amount of the memory
// copy. CPYFERTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPRTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPRTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 14, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPRTN")
}

// CPYFPRTRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged and non-temporal
//
//    CPYFPRTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged and non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPRTRN, then CPYFMRTRN, and then CPYFERTRN.
//
// CPYFPRTRN performs some preconditioning of the arguments suitable for using the
// CPYFMRTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMRTRN performs an implementation defined amount of the memory
// copy. CPYFERTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERTRN option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPRTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPRTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 10, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPRTRN")
}

// CPYFPRTWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads unprivileged, writes non-temporal
//
//    CPYFPRTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads unprivileged, writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPRTWN, then CPYFMRTWN, and then CPYFERTWN.
//
// CPYFPRTWN performs some preconditioning of the arguments suitable for using the
// CPYFMRTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMRTWN performs an implementation defined amount of the memory
// copy. CPYFERTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPRTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPRTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMRTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMRTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFERTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFERTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPRTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPRTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 6, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPRTWN")
}

// CPYFPT instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged
//
//    CPYFPT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged. These instructions
// perform a memory copy. The prologue, main, and epilogue instructions are
// expected to be run in succession and to appear consecutively in memory: CPYFPT,
// then CPYFMT, and then CPYFET.
//
// CPYFPT performs some preconditioning of the arguments suitable for using the
// CPYFMT instruction, and performs an implementation defined amount of the memory
// copy. CPYFMT performs an implementation defined amount of the memory copy.
// CPYFET performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 3, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPT")
}

// CPYFPTN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged and non-temporal
//
//    CPYFPTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged and non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPTN, then CPYFMTN, and then CPYFETN.
//
// CPYFPTN performs some preconditioning of the arguments suitable for using the
// CPYFMTN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMTN performs an implementation defined amount of the memory copy.
// CPYFETN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 15, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPTN")
}

// CPYFPTRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged, reads non-temporal
//
//    CPYFPTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged, reads non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPTRN, then CPYFMTRN, and then CPYFETRN.
//
// CPYFPTRN performs some preconditioning of the arguments suitable for using the
// CPYFMTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMTRN performs an implementation defined amount of the memory
// copy. CPYFETRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFETRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFETRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 11, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPTRN")
}

// CPYFPTWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, reads and writes unprivileged, writes non-temporal
//
//    CPYFPTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, reads and writes unprivileged, writes non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPTWN, then CPYFMTWN, and then CPYFETWN.
//
// CPYFPTWN performs some preconditioning of the arguments suitable for using the
// CPYFMTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMTWN performs an implementation defined amount of the memory
// copy. CPYFETWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFETWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFETWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 7, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPTWN")
}

// CPYFPWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes non-temporal
//
//    CPYFPWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPWN, then CPYFMWN,
// and then CPYFEWN.
//
// CPYFPWN performs some preconditioning of the arguments suitable for using the
// CPYFMWN instruction, and performs an implementation defined amount of the memory
// copy. CPYFMWN performs an implementation defined amount of the memory copy.
// CPYFEWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 4, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPWN")
}

// CPYFPWT instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged
//
//    CPYFPWT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYFPWT, then CPYFMWT,
// and then CPYFEWT.
//
// CPYFPWT performs some preconditioning of the arguments suitable for using the
// CPYFMWT instruction, and performs an implementation defined amount of the memory
// copy. CPYFMWT performs an implementation defined amount of the memory copy.
// CPYFEWT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPWT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPWT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 1, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPWT")
}

// CPYFPWTN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged, reads and writes non-temporal
//
//    CPYFPWTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged, reads and writes non-temporal.
// These instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPWTN, then CPYFMWTN, and then CPYFEWTN.
//
// CPYFPWTN performs some preconditioning of the arguments suitable for using the
// CPYFMWTN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMWTN performs an implementation defined amount of the memory
// copy. CPYFEWTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWTN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWTN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPWTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPWTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 13, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPWTN")
}

// CPYFPWTRN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged, reads non-temporal
//
//    CPYFPWTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged, reads non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPWTRN, then CPYFMWTRN, and then CPYFEWTRN.
//
// CPYFPWTRN performs some preconditioning of the arguments suitable for using the
// CPYFMWTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMWTRN performs an implementation defined amount of the memory
// copy. CPYFEWTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPWTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPWTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 9, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPWTRN")
}

// CPYFPWTWN instruction have one single form across one single category:
//
// 1. Memory Copy Forward-only, writes unprivileged and non-temporal
//
//    CPYFPWTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy Forward-only, writes unprivileged and non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYFPWTWN, then CPYFMWTWN, and then CPYFEWTWN.
//
// CPYFPWTWN performs some preconditioning of the arguments suitable for using the
// CPYFMWTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYFMWTWN performs an implementation defined amount of the memory
// copy. CPYFEWTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// The memory copy performed by these instructions is in the forward direction
// only, so the instructions are suitable for a memory copy only where there is no
// overlap between the source and destination locations, or where the source
// address is greater than the destination address.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYFPWTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + saturated Xn.
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of CPYFPWTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xs holds the original Xs + an implementation defined number of bytes
//       copied.
//     * Xd holds the original Xd + an implementation defined number of bytes
//       copied.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       copied.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For CPYFMWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be copied in the memory copy in
//       total.
//
// For CPYFMWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be copied in the memory copy in total.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For CPYFEWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number and holds -1* the number of
//       bytes remaining to be copied in the memory copy in total.
//     * Xs holds the lowest address that the copy is copied from -Xn.
//     * Xd holds the lowest address that the copy is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For CPYFEWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes remaining to be copied in the memory copy
//       in total.
//     * Xs holds the lowest address that the copy is copied from.
//     * Xd holds the lowest address that the copy is copied to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xs is written back with the lowest address that
//           has not been copied from.
//         * the value of Xd is written back with the lowest address that
//           has not been copied to.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYFPWTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYFPWTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 0, sa_xs, 5, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYFPWTWN")
}

// CPYM instruction have one single form across one single category:
//
// 1. Memory Copy
//
//    CPYM  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy. These instructions perform a memory copy. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: CPYP, then CPYM, and then CPYE.
//
// CPYP performs some preconditioning of the arguments suitable for using the CPYM
// instruction, and performs an implementation defined amount of the memory copy.
// CPYM performs an implementation defined amount of the memory copy. CPYE performs
// the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYP, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYP, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYP, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is copied to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is made to.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from.
//         * Xd holds the highest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYM(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYM", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 0, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYM")
}

// CPYMN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes non-temporal
//
//    CPYMN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes non-temporal. These instructions perform a memory
// copy. The prologue, main, and epilogue instructions are expected to be run in
// succession and to appear consecutively in memory: CPYPN, then CPYMN, and then
// CPYEN.
//
// CPYPN performs some preconditioning of the arguments suitable for using the
// CPYMN instruction, and performs an implementation defined amount of the memory
// copy. CPYMN performs an implementation defined amount of the memory copy. CPYEN
// performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 12, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMN")
}

// CPYMRN instruction have one single form across one single category:
//
// 1. Memory Copy, reads non-temporal
//
//    CPYMRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads non-temporal. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPRN, then CPYMRN, and then CPYERN.
//
// CPYPRN performs some preconditioning of the arguments suitable for using the
// CPYMRN instruction, and performs an implementation defined amount of the memory
// copy. CPYMRN performs an implementation defined amount of the memory copy.
// CPYERN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 8, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMRN")
}

// CPYMRT instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged
//
//    CPYMRT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPRT, then CPYMRT, and then CPYERT.
//
// CPYPRT performs some preconditioning of the arguments suitable for using the
// CPYMRT instruction, and performs an implementation defined amount of the memory
// copy. CPYMRT performs an implementation defined amount of the memory copy.
// CPYERT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRT, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRT, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRT, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMRT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMRT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 2, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMRT")
}

// CPYMRTN instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged, reads and writes non-temporal
//
//    CPYMRTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged, reads and writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPRTN, then CPYMRTN, and then CPYERTN.
//
// CPYPRTN performs some preconditioning of the arguments suitable for using the
// CPYMRTN instruction, and performs an implementation defined amount of the memory
// copy. CPYMRTN performs an implementation defined amount of the memory copy.
// CPYERTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRTN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRTN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMRTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMRTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 14, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMRTN")
}

// CPYMRTRN instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged and non-temporal
//
//    CPYMRTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged and non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPRTRN, then
// CPYMRTRN, and then CPYERTRN.
//
// CPYPRTRN performs some preconditioning of the arguments suitable for using the
// CPYMRTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYMRTRN performs an implementation defined amount of the memory
// copy. CPYERTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRTRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMRTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMRTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 10, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMRTRN")
}

// CPYMRTWN instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged, writes non-temporal
//
//    CPYMRTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged, writes non-temporal. These instructions perform
// a memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPRTWN, then
// CPYMRTWN, and then CPYERTWN.
//
// CPYPRTWN performs some preconditioning of the arguments suitable for using the
// CPYMRTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYMRTWN performs an implementation defined amount of the memory
// copy. CPYERTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRTWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMRTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMRTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 6, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMRTWN")
}

// CPYMT instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged
//
//    CPYMT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged. These instructions perform a memory
// copy. The prologue, main, and epilogue instructions are expected to be run in
// succession and to appear consecutively in memory: CPYPT, then CPYMT, and then
// CPYET.
//
// CPYPT performs some preconditioning of the arguments suitable for using the
// CPYMT instruction, and performs an implementation defined amount of the memory
// copy. CPYMT performs an implementation defined amount of the memory copy. CPYET
// performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPT, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPT, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 3, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMT")
}

// CPYMTN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged and non-temporal
//
//    CPYMTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged and non-temporal. These instructions
// perform a memory copy. The prologue, main, and epilogue instructions are
// expected to be run in succession and to appear consecutively in memory: CPYPTN,
// then CPYMTN, and then CPYETN.
//
// CPYPTN performs some preconditioning of the arguments suitable for using the
// CPYMTN instruction, and performs an implementation defined amount of the memory
// copy. CPYMTN performs an implementation defined amount of the memory copy.
// CPYETN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPTN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 15, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMTN")
}

// CPYMTRN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged, reads non-temporal
//
//    CPYMTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged, reads non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPTRN, then CPYMTRN, and then CPYETRN.
//
// CPYPTRN performs some preconditioning of the arguments suitable for using the
// CPYMTRN instruction, and performs an implementation defined amount of the memory
// copy. CPYMTRN performs an implementation defined amount of the memory copy.
// CPYETRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPTRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMTRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMTRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYETRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYETRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 11, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMTRN")
}

// CPYMTWN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged, writes non-temporal
//
//    CPYMTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged, writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPTWN, then CPYMTWN, and then CPYETWN.
//
// CPYPTWN performs some preconditioning of the arguments suitable for using the
// CPYMTWN instruction, and performs an implementation defined amount of the memory
// copy. CPYMTWN performs an implementation defined amount of the memory copy.
// CPYETWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPTWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMTWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMTWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYETWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYETWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 7, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMTWN")
}

// CPYMWN instruction have one single form across one single category:
//
// 1. Memory Copy, writes non-temporal
//
//    CPYMWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes non-temporal. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPWN, then CPYMWN, and then CPYEWN.
//
// CPYPWN performs some preconditioning of the arguments suitable for using the
// CPYMWN instruction, and performs an implementation defined amount of the memory
// copy. CPYMWN performs an implementation defined amount of the memory copy.
// CPYEWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 4, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMWN")
}

// CPYMWT instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged
//
//    CPYMWT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPWT, then CPYMWT, and then CPYEWT.
//
// CPYPWT performs some preconditioning of the arguments suitable for using the
// CPYMWT instruction, and performs an implementation defined amount of the memory
// copy. CPYMWT performs an implementation defined amount of the memory copy.
// CPYEWT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWT, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWT, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWT, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMWT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMWT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 1, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMWT")
}

// CPYMWTN instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged, reads and writes non-temporal
//
//    CPYMWTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged, reads and writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPWTN, then CPYMWTN, and then CPYEWTN.
//
// CPYPWTN performs some preconditioning of the arguments suitable for using the
// CPYMWTN instruction, and performs an implementation defined amount of the memory
// copy. CPYMWTN performs an implementation defined amount of the memory copy.
// CPYEWTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWTN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWTN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMWTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMWTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 13, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMWTN")
}

// CPYMWTRN instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged, reads non-temporal
//
//    CPYMWTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged, reads non-temporal. These instructions perform
// a memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPWTRN, then
// CPYMWTRN, and then CPYEWTRN.
//
// CPYPWTRN performs some preconditioning of the arguments suitable for using the
// CPYMWTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYMWTRN performs an implementation defined amount of the memory
// copy. CPYEWTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWTRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMWTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMWTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 9, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMWTRN")
}

// CPYMWTWN instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged and non-temporal
//
//    CPYMWTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged and non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPWTWN, then
// CPYMWTWN, and then CPYEWTWN.
//
// CPYPWTWN performs some preconditioning of the arguments suitable for using the
// CPYMWTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYMWTWN performs an implementation defined amount of the memory
// copy. CPYEWTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWTWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYMWTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYMWTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xs_1 := uint32(mbase(v1).ID())
        sa_xn_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 1, sa_xs_1, 5, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYMWTWN")
}

// CPYP instruction have one single form across one single category:
//
// 1. Memory Copy
//
//    CPYP  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy. These instructions perform a memory copy. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: CPYP, then CPYM, and then CPYE.
//
// CPYP performs some preconditioning of the arguments suitable for using the CPYM
// instruction, and performs an implementation defined amount of the memory copy.
// CPYM performs an implementation defined amount of the memory copy. CPYE performs
// the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYP, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYP, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYP, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is copied to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is made to.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from.
//         * Xd holds the highest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYP", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 0, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYP")
}

// CPYPN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes non-temporal
//
//    CPYPN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes non-temporal. These instructions perform a memory
// copy. The prologue, main, and epilogue instructions are expected to be run in
// succession and to appear consecutively in memory: CPYPN, then CPYMN, and then
// CPYEN.
//
// CPYPN performs some preconditioning of the arguments suitable for using the
// CPYMN instruction, and performs an implementation defined amount of the memory
// copy. CPYMN performs an implementation defined amount of the memory copy. CPYEN
// performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 12, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPN")
}

// CPYPRN instruction have one single form across one single category:
//
// 1. Memory Copy, reads non-temporal
//
//    CPYPRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads non-temporal. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPRN, then CPYMRN, and then CPYERN.
//
// CPYPRN performs some preconditioning of the arguments suitable for using the
// CPYMRN instruction, and performs an implementation defined amount of the memory
// copy. CPYMRN performs an implementation defined amount of the memory copy.
// CPYERN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 8, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPRN")
}

// CPYPRT instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged
//
//    CPYPRT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPRT, then CPYMRT, and then CPYERT.
//
// CPYPRT performs some preconditioning of the arguments suitable for using the
// CPYMRT instruction, and performs an implementation defined amount of the memory
// copy. CPYMRT performs an implementation defined amount of the memory copy.
// CPYERT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRT, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRT, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRT, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPRT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPRT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 2, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPRT")
}

// CPYPRTN instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged, reads and writes non-temporal
//
//    CPYPRTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged, reads and writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPRTN, then CPYMRTN, and then CPYERTN.
//
// CPYPRTN performs some preconditioning of the arguments suitable for using the
// CPYMRTN instruction, and performs an implementation defined amount of the memory
// copy. CPYMRTN performs an implementation defined amount of the memory copy.
// CPYERTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRTN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRTN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPRTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPRTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 14, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPRTN")
}

// CPYPRTRN instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged and non-temporal
//
//    CPYPRTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged and non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPRTRN, then
// CPYMRTRN, and then CPYERTRN.
//
// CPYPRTRN performs some preconditioning of the arguments suitable for using the
// CPYMRTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYMRTRN performs an implementation defined amount of the memory
// copy. CPYERTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRTRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPRTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPRTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 10, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPRTRN")
}

// CPYPRTWN instruction have one single form across one single category:
//
// 1. Memory Copy, reads unprivileged, writes non-temporal
//
//    CPYPRTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads unprivileged, writes non-temporal. These instructions perform
// a memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPRTWN, then
// CPYMRTWN, and then CPYERTWN.
//
// CPYPRTWN performs some preconditioning of the arguments suitable for using the
// CPYMRTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYMRTWN performs an implementation defined amount of the memory
// copy. CPYERTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPRTWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPRTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPRTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMRTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMRTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYERTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYERTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPRTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPRTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 6, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPRTWN")
}

// CPYPT instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged
//
//    CPYPT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged. These instructions perform a memory
// copy. The prologue, main, and epilogue instructions are expected to be run in
// succession and to appear consecutively in memory: CPYPT, then CPYMT, and then
// CPYET.
//
// CPYPT performs some preconditioning of the arguments suitable for using the
// CPYMT instruction, and performs an implementation defined amount of the memory
// copy. CPYMT performs an implementation defined amount of the memory copy. CPYET
// performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPT, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPT, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 3, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPT")
}

// CPYPTN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged and non-temporal
//
//    CPYPTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged and non-temporal. These instructions
// perform a memory copy. The prologue, main, and epilogue instructions are
// expected to be run in succession and to appear consecutively in memory: CPYPTN,
// then CPYMTN, and then CPYETN.
//
// CPYPTN performs some preconditioning of the arguments suitable for using the
// CPYMTN instruction, and performs an implementation defined amount of the memory
// copy. CPYMTN performs an implementation defined amount of the memory copy.
// CPYETN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPTN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 15, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPTN")
}

// CPYPTRN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged, reads non-temporal
//
//    CPYPTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged, reads non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPTRN, then CPYMTRN, and then CPYETRN.
//
// CPYPTRN performs some preconditioning of the arguments suitable for using the
// CPYMTRN instruction, and performs an implementation defined amount of the memory
// copy. CPYMTRN performs an implementation defined amount of the memory copy.
// CPYETRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPTRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMTRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMTRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYETRN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYETRN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 11, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPTRN")
}

// CPYPTWN instruction have one single form across one single category:
//
// 1. Memory Copy, reads and writes unprivileged, writes non-temporal
//
//    CPYPTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, reads and writes unprivileged, writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPTWN, then CPYMTWN, and then CPYETWN.
//
// CPYPTWN performs some preconditioning of the arguments suitable for using the
// CPYMTWN instruction, and performs an implementation defined amount of the memory
// copy. CPYMTWN performs an implementation defined amount of the memory copy.
// CPYETWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPTWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMTWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMTWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYETWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYETWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 7, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPTWN")
}

// CPYPWN instruction have one single form across one single category:
//
// 1. Memory Copy, writes non-temporal
//
//    CPYPWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes non-temporal. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPWN, then CPYMWN, and then CPYEWN.
//
// CPYPWN performs some preconditioning of the arguments suitable for using the
// CPYMWN instruction, and performs an implementation defined amount of the memory
// copy. CPYMWN performs an implementation defined amount of the memory copy.
// CPYEWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 4, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPWN")
}

// CPYPWT instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged
//
//    CPYPWT  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged. These instructions perform a memory copy. The
// prologue, main, and epilogue instructions are expected to be run in succession
// and to appear consecutively in memory: CPYPWT, then CPYMWT, and then CPYEWT.
//
// CPYPWT performs some preconditioning of the arguments suitable for using the
// CPYMWT instruction, and performs an implementation defined amount of the memory
// copy. CPYMWT performs an implementation defined amount of the memory copy.
// CPYEWT performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWT, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWT, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWT, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPWT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPWT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 1, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPWT")
}

// CPYPWTN instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged, reads and writes non-temporal
//
//    CPYPWTN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged, reads and writes non-temporal. These
// instructions perform a memory copy. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: CPYPWTN, then CPYMWTN, and then CPYEWTN.
//
// CPYPWTN performs some preconditioning of the arguments suitable for using the
// CPYMWTN instruction, and performs an implementation defined amount of the memory
// copy. CPYMWTN performs an implementation defined amount of the memory copy.
// CPYEWTN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWTN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWTN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPWTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPWTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 13, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPWTN")
}

// CPYPWTRN instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged, reads non-temporal
//
//    CPYPWTRN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged, reads non-temporal. These instructions perform
// a memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPWTRN, then
// CPYMWTRN, and then CPYEWTRN.
//
// CPYPWTRN performs some preconditioning of the arguments suitable for using the
// CPYMWTRN instruction, and performs an implementation defined amount of the
// memory copy. CPYMWTRN performs an implementation defined amount of the memory
// copy. CPYEWTRN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWTRN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWTRN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWTRN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWTRN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWTRN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPWTRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPWTRN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 9, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPWTRN")
}

// CPYPWTWN instruction have one single form across one single category:
//
// 1. Memory Copy, writes unprivileged and non-temporal
//
//    CPYPWTWN  [<Xd>]!, [<Xs>]!, <Xn>!
//
// Memory Copy, writes unprivileged and non-temporal. These instructions perform a
// memory copy. The prologue, main, and epilogue instructions are expected to be
// run in succession and to appear consecutively in memory: CPYPWTWN, then
// CPYMWTWN, and then CPYEWTWN.
//
// CPYPWTWN performs some preconditioning of the arguments suitable for using the
// CPYMWTWN instruction, and performs an implementation defined amount of the
// memory copy. CPYMWTWN performs an implementation defined amount of the memory
// copy. CPYEWTWN performs the last part of the memory copy.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory copy allows
//     some optimization of the size that can be performed.
//
// For CPYPWTWN, the following saturation logic is applied:
//
// If Xn<63:55> != 000000000, the copy size Xn is saturated to 0x007FFFFFFFFFFFFF .
//
// After that saturation logic is applied, the direction of the memory copy is
// based on the following algorithm:
//
// If (Xs > Xd) && (Xd + saturated Xn) > Xs, then direction = forward
//
// Elsif (Xs < Xd) && (Xs + saturated Xn) > Xd, then direction = backward
//
// Else direction = implementation defined choice between forward and backward.
//
// The architecture supports two algorithms for the memory copy: option A and
// option B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of CPYPWTWN, option A (which results in encoding PSTATE.C = 0):
//
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + saturated Xn.
//         * Xd holds the original Xd + saturated Xn.
//         * Xn holds -1* saturated Xn + an implementation defined number
//           of bytes copied.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs and Xd are unchanged.
//         * Xn holds the saturated value of Xn - an implementation defined
//           number of bytes copied.
//
// After execution of CPYPWTWN, option B (which results in encoding PSTATE.C = 1):
//
//     * If the copy is in the forward direction, then:
//
//         * Xs holds the original Xs + an implementation defined number of
//           bytes copied.
//         * Xd holds the original Xd + an implementation defined number of
//           bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {0,0,0}.
//
//     * If the copy is in the backward direction, then:
//
//         * Xs holds the original Xs + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xd holds the original Xd + saturated Xn - an implementation
//           defined number of bytes copied.
//         * Xn holds the saturated Xn - an implementation defined number
//           of bytes copied.
//         * PSTATE.{N,Z,V} are set to {1,0,0}.
//
// For CPYMWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with the number of bytes remaining to be copied in the memory
//           copy in total.
//
// For CPYMWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with the number of
//               bytes remaining to be copied in the memory copy in
//               total.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For CPYEWTWN, option A (encoded by PSTATE.C = 0), the format of the arguments
// is:
//
//     * Xn is treated as a signed 64-bit number.
//     * If the copy is in the forward direction (Xn is a negative number),
//       then:
//
//         * Xn holds -1* the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the lowest address that the copy is copied from -Xn.
//         * Xd holds the lowest address that the copy is made to -Xn.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
//     * If the copy is in the backward direction (Xn is a positive number),
//       then:
//
//         * Xn holds the number of bytes remaining to be copied in the
//           memory copy in total.
//         * Xs holds the highest address that the copy is copied from
//           -Xn+1.
//         * Xd holds the highest address that the copy is copied to -Xn+1.
//         * At the end of the instruction, the value of Xn is written back
//           with 0.
//
// For CPYEWTWN, option B (encoded by PSTATE.C = 1), the format of the arguments
// is:
//
//     * Xn holds the number of bytes to be copied in the memory copy in total.
//     * If the copy is in the forward direction (PSTATE.N == 0), then:
//
//         * Xs holds the lowest address that the copy is copied from.
//         * Xd holds the lowest address that the copy is copied to.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the lowest
//               address that has not been copied from.
//             * the value of Xd is written back with the lowest
//               address that has not been copied to.
//
//     * If the copy is in the backward direction (PSTATE.N == 1), then:
//
//         * Xs holds the highest address that the copy is copied from +1.
//         * Xd holds the highest address that the copy is copied to +1.
//         * At the end of the instruction:
//
//             * the value of Xn is written back with 0.
//             * the value of Xs is written back with the highest
//               address that has not been copied from +1.
//             * the value of Xd is written back with the highest
//               address that has not been copied to +1.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set CPY* .
//
func (self *Program) CPYPWTWN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CPYPWTWN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isMem(v1) &&
       isXr(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == PreIndex &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xs := uint32(mbase(v1).ID())
        sa_xn := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 0, sa_xs, 5, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CPYPWTWN")
}

// CRC32B instruction have one single form across one single category:
//
// 1. CRC32 checksum
//
//    CRC32B  <Wd>, <Wn>, <Wm>
//
// CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value
// held in a general-purpose register. It takes an input CRC value in the first
// source operand, performs a CRC on the input value in the second source operand,
// and returns the output CRC value. The second source operand can be 8, 16, 32, or
// 64 bits. To align with common usage, the bit order of the values is reversed as
// part of the operation, and the polynomial 0x04C11DB7 is used for the CRC
// calculation.
//
// In an Armv8.0 implementation, this is an optional instruction. From Armv8.1, it
// is mandatory for all implementations to implement this instruction.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .CRC32 indicates whether this instruction is supported.
//
func (self *Program) CRC32B(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CRC32B", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CRC32)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 16, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CRC32B")
}

// CRC32CB instruction have one single form across one single category:
//
// 1. CRC32C checksum
//
//    CRC32CB  <Wd>, <Wn>, <Wm>
//
// CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value
// held in a general-purpose register. It takes an input CRC value in the first
// source operand, performs a CRC on the input value in the second source operand,
// and returns the output CRC value. The second source operand can be 8, 16, 32, or
// 64 bits. To align with common usage, the bit order of the values is reversed as
// part of the operation, and the polynomial 0x1EDC6F41 is used for the CRC
// calculation.
//
// In an Armv8.0 implementation, this is an optional instruction. From Armv8.1, it
// is mandatory for all implementations to implement this instruction.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .CRC32 indicates whether this instruction is supported.
//
func (self *Program) CRC32CB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CRC32CB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CRC32)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 20, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CRC32CB")
}

// CRC32CH instruction have one single form across one single category:
//
// 1. CRC32C checksum
//
//    CRC32CH  <Wd>, <Wn>, <Wm>
//
// CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value
// held in a general-purpose register. It takes an input CRC value in the first
// source operand, performs a CRC on the input value in the second source operand,
// and returns the output CRC value. The second source operand can be 8, 16, 32, or
// 64 bits. To align with common usage, the bit order of the values is reversed as
// part of the operation, and the polynomial 0x1EDC6F41 is used for the CRC
// calculation.
//
// In an Armv8.0 implementation, this is an optional instruction. From Armv8.1, it
// is mandatory for all implementations to implement this instruction.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .CRC32 indicates whether this instruction is supported.
//
func (self *Program) CRC32CH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CRC32CH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CRC32)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 21, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CRC32CH")
}

// CRC32CW instruction have one single form across one single category:
//
// 1. CRC32C checksum
//
//    CRC32CW  <Wd>, <Wn>, <Wm>
//
// CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value
// held in a general-purpose register. It takes an input CRC value in the first
// source operand, performs a CRC on the input value in the second source operand,
// and returns the output CRC value. The second source operand can be 8, 16, 32, or
// 64 bits. To align with common usage, the bit order of the values is reversed as
// part of the operation, and the polynomial 0x1EDC6F41 is used for the CRC
// calculation.
//
// In an Armv8.0 implementation, this is an optional instruction. From Armv8.1, it
// is mandatory for all implementations to implement this instruction.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .CRC32 indicates whether this instruction is supported.
//
func (self *Program) CRC32CW(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CRC32CW", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CRC32)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 22, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CRC32CW")
}

// CRC32CX instruction have one single form across one single category:
//
// 1. CRC32C checksum
//
//    CRC32CX  <Wd>, <Wn>, <Xm>
//
// CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value
// held in a general-purpose register. It takes an input CRC value in the first
// source operand, performs a CRC on the input value in the second source operand,
// and returns the output CRC value. The second source operand can be 8, 16, 32, or
// 64 bits. To align with common usage, the bit order of the values is reversed as
// part of the operation, and the polynomial 0x1EDC6F41 is used for the CRC
// calculation.
//
// In an Armv8.0 implementation, this is an optional instruction. From Armv8.1, it
// is mandatory for all implementations to implement this instruction.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .CRC32 indicates whether this instruction is supported.
//
func (self *Program) CRC32CX(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CRC32CX", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) && isWr(v1) && isXr(v2) {
        self.Arch.Require(FEAT_CRC32)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 23, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CRC32CX")
}

// CRC32H instruction have one single form across one single category:
//
// 1. CRC32 checksum
//
//    CRC32H  <Wd>, <Wn>, <Wm>
//
// CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value
// held in a general-purpose register. It takes an input CRC value in the first
// source operand, performs a CRC on the input value in the second source operand,
// and returns the output CRC value. The second source operand can be 8, 16, 32, or
// 64 bits. To align with common usage, the bit order of the values is reversed as
// part of the operation, and the polynomial 0x04C11DB7 is used for the CRC
// calculation.
//
// In an Armv8.0 implementation, this is an optional instruction. From Armv8.1, it
// is mandatory for all implementations to implement this instruction.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .CRC32 indicates whether this instruction is supported.
//
func (self *Program) CRC32H(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CRC32H", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CRC32)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 17, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CRC32H")
}

// CRC32W instruction have one single form across one single category:
//
// 1. CRC32 checksum
//
//    CRC32W  <Wd>, <Wn>, <Wm>
//
// CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value
// held in a general-purpose register. It takes an input CRC value in the first
// source operand, performs a CRC on the input value in the second source operand,
// and returns the output CRC value. The second source operand can be 8, 16, 32, or
// 64 bits. To align with common usage, the bit order of the values is reversed as
// part of the operation, and the polynomial 0x04C11DB7 is used for the CRC
// calculation.
//
// In an Armv8.0 implementation, this is an optional instruction. From Armv8.1, it
// is mandatory for all implementations to implement this instruction.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .CRC32 indicates whether this instruction is supported.
//
func (self *Program) CRC32W(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CRC32W", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CRC32)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 18, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CRC32W")
}

// CRC32X instruction have one single form across one single category:
//
// 1. CRC32 checksum
//
//    CRC32X  <Wd>, <Wn>, <Xm>
//
// CRC32 checksum performs a cyclic redundancy check (CRC) calculation on a value
// held in a general-purpose register. It takes an input CRC value in the first
// source operand, performs a CRC on the input value in the second source operand,
// and returns the output CRC value. The second source operand can be 8, 16, 32, or
// 64 bits. To align with common usage, the bit order of the values is reversed as
// part of the operation, and the polynomial 0x04C11DB7 is used for the CRC
// calculation.
//
// In an Armv8.0 implementation, this is an optional instruction. From Armv8.1, it
// is mandatory for all implementations to implement this instruction.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .CRC32 indicates whether this instruction is supported.
//
func (self *Program) CRC32X(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("CRC32X", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) && isWr(v1) && isXr(v2) {
        self.Arch.Require(FEAT_CRC32)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 19, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for CRC32X")
}

// CSDB instruction have one single form across one single category:
//
// 1. Consumption of Speculative Data Barrier
//
//    CSDB
//
// Consumption of Speculative Data Barrier is a memory barrier that controls
// speculative execution and data value prediction.
//
// No instruction other than branch instructions appearing in program order after
// the CSDB can be speculatively executed using the results of any:
//
//     * Data value predictions of any instructions.
//     * PSTATE.{N,Z,C,V} predictions of any instructions other than
//       conditional branch instructions appearing in program order before the
//       CSDB that have not been architecturally resolved.
//     * Predictions of SVE predication state for any SVE instructions.
//
// NOTE: 
//     For purposes of the definition of CSDB, PSTATE.{N,Z,C,V} is not
//     considered a data value. This definition permits:
//
//         * Control flow speculation before and after the CSDB.
//         * Speculative execution of conditional data processing
//           instructions after the CSDB, unless they use the results of
//           data value or PSTATE.{N,Z,C,V} predictions of instructions
//           appearing in program order before the CSDB that have not been
//           architecturally resolved.
//
func (self *Program) CSDB() *Instruction {
    p := self.alloc("CSDB", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(hints(2, 4))
}

// CSEL instruction have 2 forms across one single category:
//
// 1. Conditional Select
//
//    CSEL  <Wd>, <Wn>, <Wm>, <cond>
//    CSEL  <Xd>, <Xn>, <Xm>, <cond>
//
// If the condition is true, Conditional Select writes the value of the first
// source register to the destination register. If the condition is false, it
// writes the value of the second source register to the destination register.
//
func (self *Program) CSEL(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("CSEL", 4, asm.Operands { v0, v1, v2, v3 })
    // CSEL  <Wd>, <Wn>, <Wm>, <cond>
    if isWr(v0) && isWr(v1) && isWr(v2) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condsel(0, 0, 0, sa_wm, sa_cond, 0, sa_wn, sa_wd))
    }
    // CSEL  <Xd>, <Xn>, <Xm>, <cond>
    if isXr(v0) && isXr(v1) && isXr(v2) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condsel(1, 0, 0, sa_xm, sa_cond, 0, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CSEL")
}

// CSET instruction have 2 forms across one single category:
//
// 1. Conditional Set
//
//    CSET  <Wd>, <cond>
//    CSET  <Xd>, <cond>
//
// Conditional Set sets the destination register to 1 if the condition is TRUE, and
// otherwise sets it to 0.
//
func (self *Program) CSET(v0, v1 interface{}) *Instruction {
    p := self.alloc("CSET", 2, asm.Operands { v0, v1 })
    // CSET  <Wd>, <cond>
    if isWr(v0) && isBrCond(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_cond_1 := uint32(v1.(ConditionCode) ^ 1)
        return p.setins(condsel(0, 0, 0, 31, sa_cond_1, 1, 31, sa_wd))
    }
    // CSET  <Xd>, <cond>
    if isXr(v0) && isBrCond(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_cond_1 := uint32(v1.(ConditionCode) ^ 1)
        return p.setins(condsel(1, 0, 0, 31, sa_cond_1, 1, 31, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CSET")
}

// CSETM instruction have 2 forms across one single category:
//
// 1. Conditional Set Mask
//
//    CSETM  <Wd>, <cond>
//    CSETM  <Xd>, <cond>
//
// Conditional Set Mask sets all bits of the destination register to 1 if the
// condition is TRUE, and otherwise sets all bits to 0.
//
func (self *Program) CSETM(v0, v1 interface{}) *Instruction {
    p := self.alloc("CSETM", 2, asm.Operands { v0, v1 })
    // CSETM  <Wd>, <cond>
    if isWr(v0) && isBrCond(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_cond_1 := uint32(v1.(ConditionCode) ^ 1)
        return p.setins(condsel(0, 1, 0, 31, sa_cond_1, 0, 31, sa_wd))
    }
    // CSETM  <Xd>, <cond>
    if isXr(v0) && isBrCond(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_cond_1 := uint32(v1.(ConditionCode) ^ 1)
        return p.setins(condsel(1, 1, 0, 31, sa_cond_1, 0, 31, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CSETM")
}

// CSINC instruction have 2 forms across one single category:
//
// 1. Conditional Select Increment
//
//    CSINC  <Wd>, <Wn>, <Wm>, <cond>
//    CSINC  <Xd>, <Xn>, <Xm>, <cond>
//
// Conditional Select Increment returns, in the destination register, the value of
// the first source register if the condition is TRUE, and otherwise returns the
// value of the second source register incremented by 1.
//
func (self *Program) CSINC(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("CSINC", 4, asm.Operands { v0, v1, v2, v3 })
    // CSINC  <Wd>, <Wn>, <Wm>, <cond>
    if isWr(v0) && isWr(v1) && isWr(v2) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condsel(0, 0, 0, sa_wm, sa_cond, 1, sa_wn, sa_wd))
    }
    // CSINC  <Xd>, <Xn>, <Xm>, <cond>
    if isXr(v0) && isXr(v1) && isXr(v2) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condsel(1, 0, 0, sa_xm, sa_cond, 1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CSINC")
}

// CSINV instruction have 2 forms across one single category:
//
// 1. Conditional Select Invert
//
//    CSINV  <Wd>, <Wn>, <Wm>, <cond>
//    CSINV  <Xd>, <Xn>, <Xm>, <cond>
//
// Conditional Select Invert returns, in the destination register, the value of the
// first source register if the condition is TRUE, and otherwise returns the
// bitwise inversion value of the second source register.
//
func (self *Program) CSINV(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("CSINV", 4, asm.Operands { v0, v1, v2, v3 })
    // CSINV  <Wd>, <Wn>, <Wm>, <cond>
    if isWr(v0) && isWr(v1) && isWr(v2) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condsel(0, 1, 0, sa_wm, sa_cond, 0, sa_wn, sa_wd))
    }
    // CSINV  <Xd>, <Xn>, <Xm>, <cond>
    if isXr(v0) && isXr(v1) && isXr(v2) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condsel(1, 1, 0, sa_xm, sa_cond, 0, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CSINV")
}

// CSNEG instruction have 2 forms across one single category:
//
// 1. Conditional Select Negation
//
//    CSNEG  <Wd>, <Wn>, <Wm>, <cond>
//    CSNEG  <Xd>, <Xn>, <Xm>, <cond>
//
// Conditional Select Negation returns, in the destination register, the value of
// the first source register if the condition is TRUE, and otherwise returns the
// negated value of the second source register.
//
func (self *Program) CSNEG(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("CSNEG", 4, asm.Operands { v0, v1, v2, v3 })
    // CSNEG  <Wd>, <Wn>, <Wm>, <cond>
    if isWr(v0) && isWr(v1) && isWr(v2) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condsel(0, 1, 0, sa_wm, sa_cond, 1, sa_wn, sa_wd))
    }
    // CSNEG  <Xd>, <Xn>, <Xm>, <cond>
    if isXr(v0) && isXr(v1) && isXr(v2) && isBrCond(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(condsel(1, 1, 0, sa_xm, sa_cond, 1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CSNEG")
}

// CTZ instruction have 2 forms across one single category:
//
// 1. Count Trailing Zeros
//
//    CTZ  <Wd>, <Wn>
//    CTZ  <Xd>, <Xn>
//
// Count Trailing Zeros counts the number of consecutive binary zero bits, starting
// from the least significant bit in the source register, and places the count in
// the destination register.
//
func (self *Program) CTZ(v0, v1 interface{}) *Instruction {
    p := self.alloc("CTZ", 2, asm.Operands { v0, v1 })
    // CTZ  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(0, 0, 0, 6, sa_wn, sa_wd))
    }
    // CTZ  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 6, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for CTZ")
}

// DC instruction have one single form across one single category:
//
// 1. Data Cache operation
//
//    DC  <dc_op>, <Xt>
//
// Data Cache operation. For more information, see op0==0b01, cache maintenance,
// TLB maintenance, and address translation instructions .
//
func (self *Program) DC(v0, v1 interface{}) *Instruction {
    p := self.alloc("DC", 2, asm.Operands { v0, v1 })
    if isDCOption(v0) && isXr(v1) {
        p.Domain = DomainSystem
        sa_dc_op := uint32(v0.(DCOption))
        sa_xt_1 := uint32(v1.(asm.Register).ID())
        return p.setins(systeminstrs(0, ubfx(sa_dc_op, 7, 3), 7, ubfx(sa_dc_op, 3, 4), mask(sa_dc_op, 3), sa_xt_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for DC")
}

// DCPS1 instruction have one single form across one single category:
//
// 1. Debug Change PE State to EL1
//
//    DCPS1  {#<imm>}
//
// Debug Change PE State to EL1, when executed in Debug state:
//
//     * If executed at EL0 changes the current Exception level and SP to EL1
//       using SP_EL1.
//     * Otherwise, if executed at ELx, selects SP_ELx.
//
// The target exception level of a DCPS1 instruction is:
//
//     * EL1 if the instruction is executed at EL0.
//     * Otherwise, the Exception level at which the instruction is executed.
//
// When the target Exception level of a DCPS1 instruction is ELx, on executing this
// instruction:
//
//     * ELR_ELx becomes unknown .
//     * SPSR_ELx becomes unknown .
//     * ESR_ELx becomes unknown .
//     * DLR_EL0 and DSPSR_EL0 become unknown .
//     * The endianness is set according to SCTLR_ELx .EE.
//
// This instruction is undefined at EL0 in Non-secure state if EL2 is implemented
// and HCR_EL2 .TGE == 1.
//
// This instruction is always undefined in Non-debug state.
//
// For more information on the operation of the DCPS<n> instructions, see DCPS .
//
func (self *Program) DCPS1(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("DCPS1", 0, asm.Operands {})
        case 1  : p = self.alloc("DCPS1", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction DCPS1 takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isInRange(vv[0], 0, 65535)) {
        p.Domain = DomainSystem
        sa_imm := uint32(0)
        if len(vv) >= 1 {
            sa_imm = asUimm16(vv[0])
        }
        return p.setins(exception(5, sa_imm, 0, 1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for DCPS1")
}

// DCPS2 instruction have one single form across one single category:
//
// 1. Debug Change PE State to EL2
//
//    DCPS2  {#<imm>}
//
// Debug Change PE State to EL2, when executed in Debug state:
//
//     * If executed at EL0 or EL1 changes the current Exception level and SP
//       to EL2 using SP_EL2.
//     * Otherwise, if executed at ELx, selects SP_ELx.
//
// The target exception level of a DCPS2 instruction is:
//
//     * EL2 if the instruction is executed at an exception level that is not
//       EL3.
//     * EL3 if the instruction is executed at EL3.
//
// When the target Exception level of a DCPS2 instruction is ELx, on executing this
// instruction:
//
//     * ELR_ELx becomes unknown .
//     * SPSR_ELx becomes unknown .
//     * ESR_ELx becomes unknown .
//     * DLR_EL0 and DSPSR_EL0 become unknown .
//     * The endianness is set according to SCTLR_ELx .EE.
//
// This instruction is undefined at the following exception levels:
//
//     * All exception levels if EL2 is not implemented.
//     * At EL0 and EL1 if EL2 is disabled in the current Security state.
//
// This instruction is always undefined in Non-debug state.
//
// For more information on the operation of the DCPS<n> instructions, see DCPS .
//
func (self *Program) DCPS2(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("DCPS2", 0, asm.Operands {})
        case 1  : p = self.alloc("DCPS2", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction DCPS2 takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isInRange(vv[0], 0, 65535)) {
        p.Domain = DomainSystem
        sa_imm := uint32(0)
        if len(vv) >= 1 {
            sa_imm = asUimm16(vv[0])
        }
        return p.setins(exception(5, sa_imm, 0, 2))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for DCPS2")
}

// DCPS3 instruction have one single form across one single category:
//
// 1. Debug Change PE State to EL3
//
//    DCPS3  {#<imm>}
//
// Debug Change PE State to EL3, when executed in Debug state:
//
//     * If executed at EL3 selects SP_EL3.
//     * Otherwise, changes the current Exception level and SP to EL3 using
//       SP_EL3.
//
// The target exception level of a DCPS3 instruction is EL3.
//
// On executing a DCPS3 instruction:
//
//     * ELR_EL3 becomes unknown .
//     * SPSR_EL3 becomes unknown .
//     * ESR_EL3 becomes unknown .
//     * DLR_EL0 and DSPSR_EL0 become unknown .
//     * The endianness is set according to SCTLR_EL3 .EE.
//
// This instruction is undefined at all exception levels if either:
//
//     * EDSCR .SDD == 1.
//     * EL3 is not implemented.
//
// This instruction is always undefined in Non-debug state.
//
// For more information on the operation of the DCPS<n> instructions, see DCPS .
//
func (self *Program) DCPS3(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("DCPS3", 0, asm.Operands {})
        case 1  : p = self.alloc("DCPS3", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction DCPS3 takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isInRange(vv[0], 0, 65535)) {
        p.Domain = DomainSystem
        sa_imm := uint32(0)
        if len(vv) >= 1 {
            sa_imm = asUimm16(vv[0])
        }
        return p.setins(exception(5, sa_imm, 0, 3))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for DCPS3")
}

// DGH instruction have one single form across one single category:
//
// 1. Data Gathering Hint
//
//    DGH
//
// Data Gathering Hint is a hint instruction that indicates that it is not expected
// to be performance optimal to merge memory accesses with Normal Non-cacheable or
// Device-GRE attributes appearing in program order before the hint instruction
// with any memory accesses appearing after the hint instruction into a single
// memory transaction on an interconnect.
//
func (self *Program) DGH() *Instruction {
    p := self.alloc("DGH", 0, asm.Operands {})
    self.Arch.Require(FEAT_DGH)
    p.Domain = DomainSystem
    return p.setins(hints(0, 6))
}

// DMB instruction have one single form across one single category:
//
// 1. Data Memory Barrier
//
//    DMB  <option>|#<imm>
//
// Data Memory Barrier is a memory barrier that ensures the ordering of
// observations of memory accesses, see Data Memory Barrier .
//
func (self *Program) DMB(v0 interface{}) *Instruction {
    p := self.alloc("DMB", 1, asm.Operands { v0 })
    if isOption(v0) {
        p.Domain = DomainSystem
        sa_option := asBarrierOption(v0)
        sa_imm := sa_option
        return p.setins(barriers(sa_imm, 5, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for DMB")
}

// DRPS instruction have one single form across one single category:
//
// 1. Debug restore process state
//
//    DRPS
//
func (self *Program) DRPS() *Instruction {
    p := self.alloc("DRPS", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(branch_reg(5, 31, 0, 31, 0))
}

// DSB instruction have 2 forms across one single category:
//
// 1. Data Synchronization Barrier
//
//    DSB  <option>|#<imm>
//    DSB  <option>nXS
//
// Data Synchronization Barrier is a memory barrier that ensures the completion of
// memory accesses, see Data Synchronization Barrier .
//
// A DSB instruction with the nXS qualifier is complete when the subset of these
// memory accesses with the XS attribute set to 0 are complete. It does not require
// that memory accesses with the XS attribute set to 1 are complete.
//
func (self *Program) DSB(v0 interface{}) *Instruction {
    p := self.alloc("DSB", 1, asm.Operands { v0 })
    // DSB  <option>|#<imm>
    if isOption(v0) {
        p.Domain = DomainSystem
        sa_option := asBarrierOption(v0)
        sa_imm := sa_option
        if sa_imm != sa_option {
            panic("aarch64: invalid combination of operands for DSB")
        }
        return p.setins(barriers(sa_imm, 4, 31))
    }
    // DSB  <option>nXS
    if isOptionNXS(v0) {
        self.Arch.Require(FEAT_XS)
        p.Domain = DomainSystem
        sa_option_1 := v0.(BarrierOption).nxs()
        CRm := uint32(0b0010)
        CRm |= sa_option_1 << 2
        return p.setins(barriers(CRm, 1, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for DSB")
}

// DUP instruction have 3 forms across 2 categories:
//
// 1. Duplicate vector element to vector or scalar
//
//    DUP  <Vd>.<T>, <Vn>.<Ts>[<index>]
//    DUP  <V><d>, <Vn>.<T>[<index>]
//
// Duplicate vector element to vector or scalar. This instruction duplicates the
// vector element at the specified element index in the source SIMD&FP register
// into a scalar or each element in a vector, and writes the result to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Duplicate general-purpose register to vector
//
//    DUP  <Vd>.<T>, <R><n>
//
// Duplicate general-purpose register to vector. This instruction duplicates the
// contents of the source general-purpose register into a scalar or each element in
// a vector, and writes the result to the SIMD&FP destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) DUP(v0, v1 interface{}) *Instruction {
    p := self.alloc("DUP", 2, asm.Operands { v0, v1 })
    // DUP  <Vd>.<T>, <Vn>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) && isVri(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_t__bit_mask uint32
        var sa_ts uint32
        var sa_ts__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000010
            case Vec16B: sa_t = 0b000011
            case Vec4H: sa_t = 0b000100
            case Vec8H: sa_t = 0b000101
            case Vec2S: sa_t = 0b001000
            case Vec4S: sa_t = 0b001001
            case Vec2D: sa_t = 0b010001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b000011
            case Vec16B: sa_t__bit_mask = 0b000011
            case Vec4H: sa_t__bit_mask = 0b000111
            case Vec8H: sa_t__bit_mask = 0b000111
            case Vec2S: sa_t__bit_mask = 0b001111
            case Vec4S: sa_t__bit_mask = 0b001111
            case Vec2D: sa_t__bit_mask = 0b011111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(VidxRegister).ID())
        switch vmoder(v1) {
            case ModeB: sa_ts = 0b00001
            case ModeH: sa_ts = 0b00010
            case ModeS: sa_ts = 0b00100
            case ModeD: sa_ts = 0b01000
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v1) {
            case ModeB: sa_ts__bit_mask = 0b00001
            case ModeH: sa_ts__bit_mask = 0b00011
            case ModeS: sa_ts__bit_mask = 0b00111
            case ModeD: sa_ts__bit_mask = 0b01111
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v1))
        if sa_index != ubfx(sa_t, 1, 5) & ubfx(sa_t__bit_mask, 1, 5) ||
           ubfx(sa_t, 1, 5) & ubfx(sa_t__bit_mask, 1, 5) != sa_ts & sa_ts__bit_mask {
            panic("aarch64: invalid combination of operands for DUP")
        }
        return p.setins(asimdins(mask(sa_t, 1), 0, sa_index, 0, sa_vn, sa_vd))
    }
    // DUP  <V><d>, <Vn>.<T>[<index>]
    if isAdvSIMD(v0) && isVri(v1) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_t_1__bit_mask uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00001
            case HRegister: sa_v = 0b00010
            case SRegister: sa_v = 0b00100
            case DRegister: sa_v = 0b01000
            default: panic("aarch64: invalid scalar operand size for DUP")
        }
        switch v0.(type) {
            case BRegister: sa_v__bit_mask = 0b00001
            case HRegister: sa_v__bit_mask = 0b00011
            case SRegister: sa_v__bit_mask = 0b00111
            case DRegister: sa_v__bit_mask = 0b01111
            default: panic("aarch64: invalid scalar operand size for DUP")
        }
        sa_vn := uint32(v1.(VidxRegister).ID())
        switch vmoder(v1) {
            case ModeB: sa_t_1 = 0b00001
            case ModeH: sa_t_1 = 0b00010
            case ModeS: sa_t_1 = 0b00100
            case ModeD: sa_t_1 = 0b01000
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v1) {
            case ModeB: sa_t_1__bit_mask = 0b00001
            case ModeH: sa_t_1__bit_mask = 0b00011
            case ModeS: sa_t_1__bit_mask = 0b00111
            case ModeD: sa_t_1__bit_mask = 0b01111
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v1))
        if sa_index != sa_t_1 & sa_t_1__bit_mask || sa_t_1 & sa_t_1__bit_mask != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for DUP")
        }
        return p.setins(asisdone(0, sa_index, 0, sa_vn, sa_d))
    }
    // DUP  <Vd>.<T>, <R><n>
    if isVr(v0) && isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) && isWrOrXr(v1) {
        p.Domain = DomainAdvSimd
        var sa_r [3]uint32
        var sa_r__bit_mask [3]uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000010
            case Vec16B: sa_t = 0b000011
            case Vec4H: sa_t = 0b000100
            case Vec8H: sa_t = 0b000101
            case Vec2S: sa_t = 0b001000
            case Vec4S: sa_t = 0b001001
            case Vec2D: sa_t = 0b010001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b000011
            case Vec16B: sa_t__bit_mask = 0b000011
            case Vec4H: sa_t__bit_mask = 0b000111
            case Vec8H: sa_t__bit_mask = 0b000111
            case Vec2S: sa_t__bit_mask = 0b001111
            case Vec4S: sa_t__bit_mask = 0b001111
            case Vec2D: sa_t__bit_mask = 0b011111
            default: panic("aarch64: unreachable")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch true {
            case isWr(v1): sa_r = [3]uint32{0b00100, 0b00010, 0b00001}
            case isXr(v1): sa_r = [3]uint32{0b01000}
            default: panic("aarch64: unreachable")
        }
        switch true {
            case isWr(v1): sa_r__bit_mask = [3]uint32{0b00111, 0b00011, 0b00001}
            case isXr(v1): sa_r__bit_mask = [3]uint32{0b01111}
            default: panic("aarch64: unreachable")
        }
        if !matchany(ubfx(sa_t, 1, 5) & ubfx(sa_t__bit_mask, 1, 5), &sa_r[0], &sa_r__bit_mask[0], 3) {
            panic("aarch64: invalid combination of operands for DUP")
        }
        return p.setins(asimdins(mask(sa_t, 1), 0, ubfx(sa_t, 1, 5), 1, sa_n, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for DUP")
}

// DVP instruction have one single form across one single category:
//
// 1. Data Value Prediction Restriction by Context
//
//    DVP  RCTX, <Xt>
//
// Data Value Prediction Restriction by Context prevents data value predictions
// that predict execution addresses based on information gathered from earlier
// execution within a particular execution context. Data value predictions
// determined by the actions of code in the target execution context or contexts
// appearing in program order before the instruction cannot be used to
// exploitatively control speculative execution occurring after the instruction is
// complete and synchronized.
//
// For more information, see DVP RCTX, Data Value Prediction Restriction by Context
// .
//
func (self *Program) DVP(v0, v1 interface{}) *Instruction {
    p := self.alloc("DVP", 2, asm.Operands { v0, v1 })
    if v0 == RCTX && isXr(v1) {
        self.Arch.Require(FEAT_SPECRES)
        p.Domain = DomainSystem
        sa_xt_1 := uint32(v1.(asm.Register).ID())
        return p.setins(systeminstrs(0, 3, 7, 3, 5, sa_xt_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for DVP")
}

// EON instruction have 2 forms across one single category:
//
// 1. Bitwise Exclusive-OR NOT (shifted register)
//
//    EON  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    EON  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Bitwise Exclusive-OR NOT (shifted register) performs a bitwise exclusive-OR NOT
// of a register value and an optionally-shifted register value, and writes the
// result to the destination register.
//
func (self *Program) EON(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("EON", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("EON", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction EON takes 3 or 4 operands")
    }
    // EON  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 2, sa_shift, 1, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // EON  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 2, sa_shift, 1, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for EON")
}

// EOR instruction have 5 forms across 3 categories:
//
// 1. Bitwise Exclusive-OR (vector)
//
//    EOR  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Bitwise Exclusive-OR (vector). This instruction performs a bitwise exclusive-OR
// operation between the two source SIMD&FP registers, and places the result in the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Bitwise Exclusive-OR (immediate)
//
//    EOR  <Wd|WSP>, <Wn>, #<imm>
//    EOR  <Xd|SP>, <Xn>, #<imm>
//
// Bitwise Exclusive-OR (immediate) performs a bitwise exclusive-OR of a register
// value and an immediate value, and writes the result to the destination register.
//
// 3. Bitwise Exclusive-OR (shifted register)
//
//    EOR  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    EOR  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Bitwise Exclusive-OR (shifted register) performs a bitwise exclusive-OR of a
// register value and an optionally-shifted register value, and writes the result
// to the destination register.
//
func (self *Program) EOR(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("EOR", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("EOR", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction EOR takes 3 or 4 operands")
    }
    // EOR  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(sa_t, 1, 0, sa_vm, 3, sa_vn, sa_vd))
    }
    // EOR  <Wd|WSP>, <Wn>, #<imm>
    if isWrOrWSP(v0) && isWr(v1) && isMask32(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_imm := asMaskOp(v2)
        return p.setins(log_imm(0, 2, 0, ubfx(sa_imm, 6, 6), mask(sa_imm, 6), sa_wn, sa_wd_wsp))
    }
    // EOR  <Xd|SP>, <Xn>, #<imm>
    if isXrOrSP(v0) && isXr(v1) && isMask64(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_imm_1 := asMaskOp(v2)
        return p.setins(log_imm(1, 2, ubfx(sa_imm_1, 12, 1), ubfx(sa_imm_1, 6, 6), mask(sa_imm_1, 6), sa_xn, sa_xd_sp))
    }
    // EOR  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 2, sa_shift, 0, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // EOR  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 2, sa_shift, 0, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for EOR")
}

// EOR3 instruction have one single form across one single category:
//
// 1. Three-way Exclusive-OR
//
//    EOR3  <Vd>.16B, <Vn>.16B, <Vm>.16B, <Va>.16B
//
// Three-way Exclusive-OR performs a three-way exclusive-OR of the values in the
// three source SIMD&FP registers, and writes the result to the destination SIMD&FP
// register.
//
// This instruction is implemented only when FEAT_SHA3 is implemented.
//
func (self *Program) EOR3(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("EOR3", 4, asm.Operands { v0, v1, v2, v3 })
    if isVr(v0) &&
       vfmt(v0) == Vec16B &&
       isVr(v1) &&
       vfmt(v1) == Vec16B &&
       isVr(v2) &&
       vfmt(v2) == Vec16B &&
       isVr(v3) &&
       vfmt(v3) == Vec16B {
        self.Arch.Require(FEAT_SHA3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        sa_va := uint32(v3.(asm.Register).ID())
        return p.setins(crypto4(0, sa_vm, sa_va, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for EOR3")
}

// ERET instruction have one single form across one single category:
//
// 1. Exception Return
//
//    ERET
//
// Exception Return using the ELR and SPSR for the current Exception level. When
// executed, the PE restores PSTATE from the SPSR, and branches to the address held
// in the ELR.
//
// The PE checks the SPSR for the current Exception level for an illegal return
// event. See Illegal return events from AArch64 state .
//
// ERET is undefined at EL0.
//
func (self *Program) ERET() *Instruction {
    p := self.alloc("ERET", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(branch_reg(4, 31, 0, 31, 0))
}

// ERETAA instruction have one single form across one single category:
//
// 1. Exception Return, with pointer authentication
//
//    ERETAA
//
// Exception Return, with pointer authentication. This instruction authenticates
// the address in ELR, using SP as the modifier and the specified key, the PE
// restores PSTATE from the SPSR for the current Exception level, and branches to
// the authenticated address.
//
// Key A is used for ERETAA . Key B is used for ERETAB .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to ELR.
//
// The PE checks the SPSR for the current Exception level for an illegal return
// event. See Illegal return events from AArch64 state .
//
// ERETAA and ERETAB are undefined at EL0.
//
func (self *Program) ERETAA() *Instruction {
    p := self.alloc("ERETAA", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = asm.DomainGeneric
    return p.setins(branch_reg(4, 31, 2, 31, 31))
}

// ERETAB instruction have one single form across one single category:
//
// 1. Exception Return, with pointer authentication
//
//    ERETAB
//
// Exception Return, with pointer authentication. This instruction authenticates
// the address in ELR, using SP as the modifier and the specified key, the PE
// restores PSTATE from the SPSR for the current Exception level, and branches to
// the authenticated address.
//
// Key A is used for ERETAA . Key B is used for ERETAB .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to ELR.
//
// The PE checks the SPSR for the current Exception level for an illegal return
// event. See Illegal return events from AArch64 state .
//
// ERETAA and ERETAB are undefined at EL0.
//
func (self *Program) ERETAB() *Instruction {
    p := self.alloc("ERETAB", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = asm.DomainGeneric
    return p.setins(branch_reg(4, 31, 3, 31, 31))
}

// ESB instruction have one single form across one single category:
//
// 1. Error Synchronization Barrier
//
//    ESB
//
// Error Synchronization Barrier is an error synchronization event that might also
// update DISR_EL1 and VDISR_EL2.
//
// This instruction can be used at all Exception levels and in Debug state.
//
// In Debug state, this instruction behaves as if SError interrupts are masked at
// all Exception levels. See Error Synchronization Barrier in the Arm(R)
// Reliability, Availability, and Serviceability (RAS) Specification, Armv8, for
// Armv8-A architecture profile.
//
// If the RAS Extension is not implemented, this instruction executes as a NOP .
//
func (self *Program) ESB() *Instruction {
    p := self.alloc("ESB", 0, asm.Operands {})
    self.Arch.Require(FEAT_RAS)
    p.Domain = DomainSystem
    return p.setins(hints(2, 0))
}

// EXT instruction have one single form across one single category:
//
// 1. Extract vector from pair of vectors
//
//    EXT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<index>
//
// Extract vector from pair of vectors. This instruction extracts the lowest vector
// elements from the second source SIMD&FP register and the highest vector elements
// from the first source SIMD&FP register, concatenates the results into a vector,
// and writes the vector to the destination SIMD&FP register vector. The index
// value specifies the lowest vector element to extract from the first source
// register, and consecutive elements are extracted from the first, then second,
// source registers until the destination vector is filled.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.ext_doubleword_operation_for_imm3.svg]
// EXT doubleword operation for Q = 0 and imm4<2:0> = 3
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) EXT(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("EXT", 4, asm.Operands { v0, v1, v2, v3 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       isExtIndex(v0, v3) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        sa_index := asExtIndex(v0, v3)
        if ubfx(sa_index, 4, 1) != sa_t {
            panic("aarch64: invalid combination of operands for EXT")
        }
        return p.setins(asimdext(ubfx(sa_index, 4, 1), 0, sa_vm, mask(sa_index, 4), sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for EXT")
}

// EXTR instruction have 2 forms across one single category:
//
// 1. Extract register
//
//    EXTR  <Wd>, <Wn>, <Wm>, #<lsb>
//    EXTR  <Xd>, <Xn>, <Xm>, #<lsb>
//
// Extract register extracts a register from a pair of registers.
//
func (self *Program) EXTR(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("EXTR", 4, asm.Operands { v0, v1, v2, v3 })
    // EXTR  <Wd>, <Wn>, <Wm>, #<lsb>
    if isWr(v0) && isWr(v1) && isWr(v2) && isInRange(v3, 0, 31) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_lsb := asUimm6(v3)
        return p.setins(extract(0, 0, 0, 0, sa_wm, sa_lsb, sa_wn, sa_wd))
    }
    // EXTR  <Xd>, <Xn>, <Xm>, #<lsb>
    if isXr(v0) && isXr(v1) && isXr(v2) && isInRange(v3, 0, 63) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        sa_lsb_1 := asUimm6(v3)
        return p.setins(extract(1, 0, 1, 0, sa_xm, sa_lsb_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for EXTR")
}

// FABD instruction have 4 forms across one single category:
//
// 1. Floating-point Absolute Difference (vector)
//
//    FABD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FABD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FABD  <V><d>, <V><n>, <V><m>
//    FABD  <Hd>, <Hn>, <Hm>
//
// Floating-point Absolute Difference (vector). This instruction subtracts the
// floating-point values in the elements of the second source SIMD&FP register,
// from the corresponding floating-point values in the elements of the first source
// SIMD&FP register, places the absolute value of each result in a vector, and
// writes the vector to the destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FABD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FABD", 3, asm.Operands { v0, v1, v2 })
    // FABD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 26, sa_vn, sa_vd))
    }
    // FABD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 1, sa_vm, 2, sa_vn, sa_vd))
    }
    // FABD  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FABD")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdsame(1, size, sa_m, 26, sa_n, sa_d))
    }
    // FABD  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsamefp16(1, 1, sa_hm, 2, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FABD")
}

// FABS instruction have 5 forms across 2 categories:
//
// 1. Floating-point Absolute value (vector)
//
//    FABS  <Vd>.<T>, <Vn>.<T>
//    FABS  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Absolute value (vector). This instruction calculates the absolute
// value of each vector element in the source SIMD&FP register, writes the result
// to a vector, and writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Absolute value (scalar)
//
//    FABS  <Dd>, <Dn>
//    FABS  <Hd>, <Hn>
//    FABS  <Sd>, <Sn>
//
// Floating-point Absolute value (scalar). This instruction calculates the absolute
// value in the SIMD&FP source register and writes the result to the SIMD&FP
// destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FABS(v0, v1 interface{}) *Instruction {
    p := self.alloc("FABS", 2, asm.Operands { v0, v1 })
    // FABS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 15, sa_vn, sa_vd))
    }
    // FABS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 1, 15, sa_vn, sa_vd))
    }
    // FABS  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 1, sa_dn, sa_dd))
    }
    // FABS  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 1, sa_hn, sa_hd))
    }
    // FABS  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 1, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FABS")
}

// FACGE instruction have 4 forms across one single category:
//
// 1. Floating-point Absolute Compare Greater than or Equal (vector)
//
//    FACGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FACGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FACGE  <V><d>, <V><n>, <V><m>
//    FACGE  <Hd>, <Hn>, <Hm>
//
// Floating-point Absolute Compare Greater than or Equal (vector). This instruction
// compares the absolute value of each floating-point value in the first source
// SIMD&FP register with the absolute value of the corresponding floating-point
// value in the second source SIMD&FP register and if the first value is greater
// than or equal to the second value sets every bit of the corresponding vector
// element in the destination SIMD&FP register to one, otherwise sets every bit of
// the corresponding vector element in the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FACGE(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FACGE", 3, asm.Operands { v0, v1, v2 })
    // FACGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 29, sa_vn, sa_vd))
    }
    // FACGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 0, sa_vm, 5, sa_vn, sa_vd))
    }
    // FACGE  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FACGE")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdsame(1, size, sa_m, 29, sa_n, sa_d))
    }
    // FACGE  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsamefp16(1, 0, sa_hm, 5, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FACGE")
}

// FACGT instruction have 4 forms across one single category:
//
// 1. Floating-point Absolute Compare Greater than (vector)
//
//    FACGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FACGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FACGT  <V><d>, <V><n>, <V><m>
//    FACGT  <Hd>, <Hn>, <Hm>
//
// Floating-point Absolute Compare Greater than (vector). This instruction compares
// the absolute value of each vector element in the first source SIMD&FP register
// with the absolute value of the corresponding vector element in the second source
// SIMD&FP register and if the first value is greater than the second value sets
// every bit of the corresponding vector element in the destination SIMD&FP
// register to one, otherwise sets every bit of the corresponding vector element in
// the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FACGT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FACGT", 3, asm.Operands { v0, v1, v2 })
    // FACGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 29, sa_vn, sa_vd))
    }
    // FACGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 1, sa_vm, 5, sa_vn, sa_vd))
    }
    // FACGT  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FACGT")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdsame(1, size, sa_m, 29, sa_n, sa_d))
    }
    // FACGT  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsamefp16(1, 1, sa_hm, 5, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FACGT")
}

// FADD instruction have 5 forms across 2 categories:
//
// 1. Floating-point Add (vector)
//
//    FADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Add (vector). This instruction adds corresponding vector elements
// in the two source SIMD&FP registers, writes the result into a vector, and writes
// the vector to the destination SIMD&FP register. All the values in this
// instruction are floating-point values.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Add (scalar)
//
//    FADD  <Dd>, <Dn>, <Dm>
//    FADD  <Hd>, <Hn>, <Hm>
//    FADD  <Sd>, <Sn>, <Sm>
//
// Floating-point Add (scalar). This instruction adds the floating-point values of
// the two source SIMD&FP registers, and writes the result to the destination
// SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FADD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FADD", 3, asm.Operands { v0, v1, v2 })
    // FADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 26, sa_vn, sa_vd))
    }
    // FADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 0, sa_vm, 2, sa_vn, sa_vd))
    }
    // FADD  <Dd>, <Dn>, <Dm>
    if isDr(v0) && isDr(v1) && isDr(v2) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 1, sa_dm, 2, sa_dn, sa_dd))
    }
    // FADD  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 3, sa_hm, 2, sa_hn, sa_hd))
    }
    // FADD  <Sd>, <Sn>, <Sm>
    if isSr(v0) && isSr(v1) && isSr(v2) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 0, sa_sm, 2, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FADD")
}

// FADDP instruction have 4 forms across 2 categories:
//
// 1. Floating-point Add Pair of elements (scalar)
//
//    FADDP  <V><d>, <Vn>.<T>
//    FADDP  <V><d>, <Vn>.<T>
//
// Floating-point Add Pair of elements (scalar). This instruction adds two
// floating-point vector elements in the source SIMD&FP register and writes the
// scalar result into the destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Add Pairwise (vector)
//
//    FADDP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FADDP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Add Pairwise (vector). This instruction creates a vector by
// concatenating the vector elements of the first source SIMD&FP register after the
// vector elements of the second source SIMD&FP register, reads each pair of
// adjacent vector elements from the concatenated vector, adds each pair of values
// together, places the result into a vector, and writes the vector to the
// destination SIMD&FP register. All the values in this instruction are floating-
// point values.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FADDP(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("FADDP", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("FADDP", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction FADDP takes 2 or 3 operands")
    }
    // FADDP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec2H {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b0
            default: panic("aarch64: invalid scalar operand size for FADDP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_t = 0b0
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_v
        if sa_v != sa_t {
            panic("aarch64: invalid combination of operands for FADDP")
        }
        return p.setins(asisdpair(0, size, 13, sa_vn, sa_d))
    }
    // FADDP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec2S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_v_1 uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v_1 = 0b0
            case DRegister: sa_v_1 = 0b1
            default: panic("aarch64: invalid scalar operand size for FADDP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2S: sa_t_1 = 0b0
            case Vec2D: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_v_1
        if sa_v_1 != sa_t_1 {
            panic("aarch64: invalid combination of operands for FADDP")
        }
        return p.setins(asisdpair(1, size, 13, sa_vn, sa_d))
    }
    // FADDP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 26, sa_vn, sa_vd))
    }
    // FADDP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 0, sa_vm, 2, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FADDP")
}

// FCADD instruction have one single form across one single category:
//
// 1. Floating-point Complex Add
//
//    FCADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<rotate>
//
// Floating-point Complex Add.
//
// This instruction operates on complex numbers that are represented in SIMD&FP
// registers as pairs of elements, with the more significant element holding the
// imaginary part of the number and the less significant element holding the real
// part of the number. Each element holds a floating-point value. It performs the
// following computation on the corresponding complex number element pairs from the
// two source registers:
//
//     * Considering the complex number from the second source register on an
//       Argand diagram, the number is rotated counterclockwise by 90 or 270
//       degrees.
//     * The rotated complex number is added to the complex number from the
//       first source register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCADD(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("FCADD", 4, asm.Operands { v0, v1, v2, v3 })
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isIntLit(v3, 90, 270) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FCMA)
        p.Domain = DomainAdvSimd
        var sa_rotate uint32
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch asLit(v3) {
            case 90: sa_rotate = 0b0
            case 270: sa_rotate = 0b1
            default: panic("aarch64: invalid operand 'sa_rotate' for FCADD")
        }
        opcode := uint32(0b1100)
        opcode |= sa_rotate << 1
        return p.setins(asimdsame2(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, opcode, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for FCADD")
}

// FCCMP instruction have 3 forms across one single category:
//
// 1. Floating-point Conditional quiet Compare (scalar)
//
//    FCCMP  <Dn>, <Dm>, #<nzcv>, <cond>
//    FCCMP  <Hn>, <Hm>, #<nzcv>, <cond>
//    FCCMP  <Sn>, <Sm>, #<nzcv>, <cond>
//
// Floating-point Conditional quiet Compare (scalar). This instruction compares the
// two SIMD&FP source register values and writes the result to the PSTATE .{N, Z,
// C, V} flags. If the condition does not pass then the PSTATE .{N, Z, C, V} flags
// are set to the flag bit specifier.
//
// This instruction raises an Invalid Operation floating-point exception if either
// or both of the operands is a signaling NaN.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCCMP(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("FCCMP", 4, asm.Operands { v0, v1, v2, v3 })
    // FCCMP  <Dn>, <Dm>, #<nzcv>, <cond>
    if isDr(v0) && isDr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = DomainFloat
        sa_dn := uint32(v0.(asm.Register).ID())
        sa_dm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(floatccmp(0, 0, 1, sa_dm, sa_cond, sa_dn, 0, sa_nzcv))
    }
    // FCCMP  <Hn>, <Hm>, #<nzcv>, <cond>
    if isHr(v0) && isHr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = DomainFloat
        sa_hn := uint32(v0.(asm.Register).ID())
        sa_hm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(floatccmp(0, 0, 3, sa_hm, sa_cond, sa_hn, 0, sa_nzcv))
    }
    // FCCMP  <Sn>, <Sm>, #<nzcv>, <cond>
    if isSr(v0) && isSr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = DomainFloat
        sa_sn := uint32(v0.(asm.Register).ID())
        sa_sm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(floatccmp(0, 0, 0, sa_sm, sa_cond, sa_sn, 0, sa_nzcv))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCCMP")
}

// FCCMPE instruction have 3 forms across one single category:
//
// 1. Floating-point Conditional signaling Compare (scalar)
//
//    FCCMPE  <Dn>, <Dm>, #<nzcv>, <cond>
//    FCCMPE  <Hn>, <Hm>, #<nzcv>, <cond>
//    FCCMPE  <Sn>, <Sm>, #<nzcv>, <cond>
//
// Floating-point Conditional signaling Compare (scalar). This instruction compares
// the two SIMD&FP source register values and writes the result to the PSTATE .{N,
// Z, C, V} flags. If the condition does not pass then the PSTATE .{N, Z, C, V}
// flags are set to the flag bit specifier.
//
// This instruction raises an Invalid Operation floating-point exception if either
// or both of the operands is any type of NaN.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCCMPE(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("FCCMPE", 4, asm.Operands { v0, v1, v2, v3 })
    // FCCMPE  <Dn>, <Dm>, #<nzcv>, <cond>
    if isDr(v0) && isDr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = DomainFloat
        sa_dn := uint32(v0.(asm.Register).ID())
        sa_dm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(floatccmp(0, 0, 1, sa_dm, sa_cond, sa_dn, 1, sa_nzcv))
    }
    // FCCMPE  <Hn>, <Hm>, #<nzcv>, <cond>
    if isHr(v0) && isHr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = DomainFloat
        sa_hn := uint32(v0.(asm.Register).ID())
        sa_hm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(floatccmp(0, 0, 3, sa_hm, sa_cond, sa_hn, 1, sa_nzcv))
    }
    // FCCMPE  <Sn>, <Sm>, #<nzcv>, <cond>
    if isSr(v0) && isSr(v1) && isInRange(v2, 0, 15) && isBrCond(v3) {
        p.Domain = DomainFloat
        sa_sn := uint32(v0.(asm.Register).ID())
        sa_sm := uint32(v1.(asm.Register).ID())
        sa_nzcv := asUimm4(v2)
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(floatccmp(0, 0, 0, sa_sm, sa_cond, sa_sn, 1, sa_nzcv))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCCMPE")
}

// FCMEQ instruction have 8 forms across 2 categories:
//
// 1. Floating-point Compare Equal (vector)
//
//    FCMEQ  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FCMEQ  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FCMEQ  <V><d>, <V><n>, <V><m>
//    FCMEQ  <Hd>, <Hn>, <Hm>
//
// Floating-point Compare Equal (vector). This instruction compares each floating-
// point value from the first source SIMD&FP register, with the corresponding
// floating-point value from the second source SIMD&FP register, and if the
// comparison is equal sets every bit of the corresponding vector element in the
// destination SIMD&FP register to one, otherwise sets every bit of the
// corresponding vector element in the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Compare Equal to zero (vector)
//
//    FCMEQ  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMEQ  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMEQ  <V><d>, <V><n>, #0.0
//    FCMEQ  <Hd>, <Hn>, #0.0
//
// Floating-point Compare Equal to zero (vector). This instruction reads each
// floating-point value in the source SIMD&FP register and if the value is equal to
// zero sets every bit of the corresponding vector element in the destination
// SIMD&FP register to one, otherwise sets every bit of the corresponding vector
// element in the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCMEQ(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FCMEQ", 3, asm.Operands { v0, v1, v2 })
    // FCMEQ  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 28, sa_vn, sa_vd))
    }
    // FCMEQ  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 0, sa_vm, 4, sa_vn, sa_vd))
    }
    // FCMEQ  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCMEQ")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdsame(0, size, sa_m, 28, sa_n, sa_d))
    }
    // FCMEQ  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsamefp16(0, 0, sa_hm, 4, sa_hn, sa_hd))
    }
    // FCMEQ  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 13, sa_vn, sa_vd))
    }
    // FCMEQ  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 1, 13, sa_vn, sa_vd))
    }
    // FCMEQ  <V><d>, <V><n>, #0.0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFloatLit(v2, 0.0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCMEQ")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 13, sa_n, sa_d))
    }
    // FCMEQ  <Hd>, <Hn>, #0.0
    if isHr(v0) && isHr(v1) && isFloatLit(v2, 0.0) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 1, 13, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCMEQ")
}

// FCMGE instruction have 8 forms across 2 categories:
//
// 1. Floating-point Compare Greater than or Equal (vector)
//
//    FCMGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FCMGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FCMGE  <V><d>, <V><n>, <V><m>
//    FCMGE  <Hd>, <Hn>, <Hm>
//
// Floating-point Compare Greater than or Equal (vector). This instruction reads
// each floating-point value in the first source SIMD&FP register and if the value
// is greater than or equal to the corresponding floating-point value in the second
// source SIMD&FP register sets every bit of the corresponding vector element in
// the destination SIMD&FP register to one, otherwise sets every bit of the
// corresponding vector element in the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Compare Greater than or Equal to zero (vector)
//
//    FCMGE  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMGE  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMGE  <V><d>, <V><n>, #0.0
//    FCMGE  <Hd>, <Hn>, #0.0
//
// Floating-point Compare Greater than or Equal to zero (vector). This instruction
// reads each floating-point value in the source SIMD&FP register and if the value
// is greater than or equal to zero sets every bit of the corresponding vector
// element in the destination SIMD&FP register to one, otherwise sets every bit of
// the corresponding vector element in the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCMGE(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FCMGE", 3, asm.Operands { v0, v1, v2 })
    // FCMGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 28, sa_vn, sa_vd))
    }
    // FCMGE  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 0, sa_vm, 4, sa_vn, sa_vd))
    }
    // FCMGE  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCMGE")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdsame(1, size, sa_m, 28, sa_n, sa_d))
    }
    // FCMGE  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsamefp16(1, 0, sa_hm, 4, sa_hn, sa_hd))
    }
    // FCMGE  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 12, sa_vn, sa_vd))
    }
    // FCMGE  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 1, 12, sa_vn, sa_vd))
    }
    // FCMGE  <V><d>, <V><n>, #0.0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFloatLit(v2, 0.0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCMGE")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(1, size, 12, sa_n, sa_d))
    }
    // FCMGE  <Hd>, <Hn>, #0.0
    if isHr(v0) && isHr(v1) && isFloatLit(v2, 0.0) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(1, 1, 12, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCMGE")
}

// FCMGT instruction have 8 forms across 2 categories:
//
// 1. Floating-point Compare Greater than (vector)
//
//    FCMGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FCMGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FCMGT  <V><d>, <V><n>, <V><m>
//    FCMGT  <Hd>, <Hn>, <Hm>
//
// Floating-point Compare Greater than (vector). This instruction reads each
// floating-point value in the first source SIMD&FP register and if the value is
// greater than the corresponding floating-point value in the second source SIMD&FP
// register sets every bit of the corresponding vector element in the destination
// SIMD&FP register to one, otherwise sets every bit of the corresponding vector
// element in the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Compare Greater than zero (vector)
//
//    FCMGT  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMGT  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMGT  <V><d>, <V><n>, #0.0
//    FCMGT  <Hd>, <Hn>, #0.0
//
// Floating-point Compare Greater than zero (vector). This instruction reads each
// floating-point value in the source SIMD&FP register and if the value is greater
// than zero sets every bit of the corresponding vector element in the destination
// SIMD&FP register to one, otherwise sets every bit of the corresponding vector
// element in the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCMGT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FCMGT", 3, asm.Operands { v0, v1, v2 })
    // FCMGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 28, sa_vn, sa_vd))
    }
    // FCMGT  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 1, sa_vm, 4, sa_vn, sa_vd))
    }
    // FCMGT  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCMGT")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdsame(1, size, sa_m, 28, sa_n, sa_d))
    }
    // FCMGT  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsamefp16(1, 1, sa_hm, 4, sa_hn, sa_hd))
    }
    // FCMGT  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 12, sa_vn, sa_vd))
    }
    // FCMGT  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 1, 12, sa_vn, sa_vd))
    }
    // FCMGT  <V><d>, <V><n>, #0.0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFloatLit(v2, 0.0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCMGT")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 12, sa_n, sa_d))
    }
    // FCMGT  <Hd>, <Hn>, #0.0
    if isHr(v0) && isHr(v1) && isFloatLit(v2, 0.0) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 1, 12, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCMGT")
}

// FCMLA instruction have 3 forms across 2 categories:
//
// 1. Floating-point Complex Multiply Accumulate (by element)
//
//    FCMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>], #<rotate>
//    FCMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>], #<rotate>
//
// Floating-point Complex Multiply Accumulate (by element).
//
// This instruction operates on complex numbers that are represented in SIMD&FP
// registers as pairs of elements, with the more significant element holding the
// imaginary part of the number and the less significant element holding the real
// part of the number. Each element holds a floating-point value. It performs the
// following computation on complex numbers from the first source register and the
// destination register with the specified complex number from the second source
// register:
//
//     * Considering the complex number from the second source register on an
//       Argand diagram, the number is rotated counterclockwise by 0, 90, 180,
//       or 270 degrees.
//     * The two elements of the transformed complex number are multiplied by:
//
//         * The real element of the complex number from the first source
//           register, if the transformation was a rotation by 0 or 180
//           degrees.
//         * The imaginary element of the complex number from the first
//           source register, if the transformation was a rotation by 90 or
//           270 degrees.
//
//     * The complex number resulting from that multiplication is added to the
//       complex number from the destination register.
//
// The multiplication and addition operations are performed as a fused multiply-
// add, without any intermediate rounding.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Complex Multiply Accumulate
//
//    FCMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<rotate>
//
// Floating-point Complex Multiply Accumulate.
//
// This instruction operates on complex numbers that are represented in SIMD&FP
// registers as pairs of elements, with the more significant element holding the
// imaginary part of the number and the less significant element holding the real
// part of the number. Each element holds a floating-point value. It performs the
// following computation on the corresponding complex number element pairs from the
// two source registers and the destination register:
//
//     * Considering the complex number from the second source register on an
//       Argand diagram, the number is rotated counterclockwise by 0, 90, 180,
//       or 270 degrees.
//     * The two elements of the transformed complex number are multiplied by:
//
//         * The real element of the complex number from the first source
//           register, if the transformation was a rotation by 0 or 180
//           degrees.
//         * The imaginary element of the complex number from the first
//           source register, if the transformation was a rotation by 90 or
//           270 degrees.
//
//     * The complex number resulting from that multiplication is added to the
//       complex number from the destination register.
//
// The multiplication and addition operations are performed as a fused multiply-
// add, without any intermediate rounding.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCMLA(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("FCMLA", 4, asm.Operands { v0, v1, v2, v3 })
    // FCMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>], #<rotate>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec4S) &&
       isVri(v2) &&
       isIntLit(v3, 0, 90, 180, 270) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FCMA)
        p.Domain = DomainAdvSimd
        var sa_rotate uint32
        var sa_t uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        switch asLit(v3) {
            case 0: sa_rotate = 0b00
            case 90: sa_rotate = 0b01
            case 180: sa_rotate = 0b10
            case 270: sa_rotate = 0b11
            default: panic("aarch64: invalid operand 'sa_rotate' for FCMLA")
        }
        opcode := uint32(0b0001)
        opcode |= sa_rotate << 1
        if ubfx(sa_t, 1, 2) != sa_ts || sa_ts != ubfx(sa_index, 2, 2) {
            panic("aarch64: invalid combination of operands for FCMLA")
        }
        return p.setins(asimdelem(
            mask(sa_t, 1),
            1,
            1,
            mask(sa_index, 1),
            ubfx(sa_vm, 4, 1),
            mask(sa_vm, 4),
            opcode,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FCMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>], #<rotate>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec4S) &&
       isVri(v2) &&
       isIntLit(v3, 0, 90, 180, 270) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FCMA)
        p.Domain = DomainAdvSimd
        var sa_rotate uint32
        var sa_t uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        switch asLit(v3) {
            case 0: sa_rotate = 0b00
            case 90: sa_rotate = 0b01
            case 180: sa_rotate = 0b10
            case 270: sa_rotate = 0b11
            default: panic("aarch64: invalid operand 'sa_rotate' for FCMLA")
        }
        opcode := uint32(0b0001)
        opcode |= sa_rotate << 1
        if ubfx(sa_t, 1, 2) != sa_ts || sa_ts != ubfx(sa_index, 2, 2) {
            panic("aarch64: invalid combination of operands for FCMLA")
        }
        return p.setins(asimdelem(
            mask(sa_t, 1),
            1,
            2,
            mask(sa_index, 1),
            ubfx(sa_vm, 4, 1),
            mask(sa_vm, 4),
            opcode,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FCMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<rotate>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isIntLit(v3, 0, 90, 180, 270) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FCMA)
        p.Domain = DomainAdvSimd
        var sa_rotate uint32
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch asLit(v3) {
            case 0: sa_rotate = 0b00
            case 90: sa_rotate = 0b01
            case 180: sa_rotate = 0b10
            case 270: sa_rotate = 0b11
            default: panic("aarch64: invalid operand 'sa_rotate' for FCMLA")
        }
        opcode := uint32(0b1000)
        opcode |= sa_rotate
        return p.setins(asimdsame2(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, opcode, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCMLA")
}

// FCMLE instruction have 4 forms across one single category:
//
// 1. Floating-point Compare Less than or Equal to zero (vector)
//
//    FCMLE  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMLE  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMLE  <V><d>, <V><n>, #0.0
//    FCMLE  <Hd>, <Hn>, #0.0
//
// Floating-point Compare Less than or Equal to zero (vector). This instruction
// reads each floating-point value in the source SIMD&FP register and if the value
// is less than or equal to zero sets every bit of the corresponding vector element
// in the destination SIMD&FP register to one, otherwise sets every bit of the
// corresponding vector element in the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCMLE(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FCMLE", 3, asm.Operands { v0, v1, v2 })
    // FCMLE  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 13, sa_vn, sa_vd))
    }
    // FCMLE  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 1, 13, sa_vn, sa_vd))
    }
    // FCMLE  <V><d>, <V><n>, #0.0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFloatLit(v2, 0.0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCMLE")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(1, size, 13, sa_n, sa_d))
    }
    // FCMLE  <Hd>, <Hn>, #0.0
    if isHr(v0) && isHr(v1) && isFloatLit(v2, 0.0) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(1, 1, 13, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCMLE")
}

// FCMLT instruction have 4 forms across one single category:
//
// 1. Floating-point Compare Less than zero (vector)
//
//    FCMLT  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMLT  <Vd>.<T>, <Vn>.<T>, #0.0
//    FCMLT  <V><d>, <V><n>, #0.0
//    FCMLT  <Hd>, <Hn>, #0.0
//
// Floating-point Compare Less than zero (vector). This instruction reads each
// floating-point value in the source SIMD&FP register and if the value is less
// than zero sets every bit of the corresponding vector element in the destination
// SIMD&FP register to one, otherwise sets every bit of the corresponding vector
// element in the destination SIMD&FP register to zero.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCMLT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FCMLT", 3, asm.Operands { v0, v1, v2 })
    // FCMLT  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 14, sa_vn, sa_vd))
    }
    // FCMLT  <Vd>.<T>, <Vn>.<T>, #0.0
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isFloatLit(v2, 0.0) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 1, 14, sa_vn, sa_vd))
    }
    // FCMLT  <V><d>, <V><n>, #0.0
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFloatLit(v2, 0.0) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCMLT")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 14, sa_n, sa_d))
    }
    // FCMLT  <Hd>, <Hn>, #0.0
    if isHr(v0) && isHr(v1) && isFloatLit(v2, 0.0) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 1, 14, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCMLT")
}

// FCMP instruction have 6 forms across one single category:
//
// 1. Floating-point quiet Compare (scalar)
//
//    FCMP  <Dn>, #0.0
//    FCMP  <Dn>, <Dm>
//    FCMP  <Hn>, #0.0
//    FCMP  <Hn>, <Hm>
//    FCMP  <Sn>, #0.0
//    FCMP  <Sn>, <Sm>
//
// Floating-point quiet Compare (scalar). This instruction compares the two SIMD&FP
// source register values, or the first SIMD&FP source register value and zero. It
// writes the result to the PSTATE .{N, Z, C, V} flags.
//
// This instruction raises an Invalid Operation floating-point exception if either
// or both of the operands is a signaling NaN.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCMP(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCMP", 2, asm.Operands { v0, v1 })
    // FCMP  <Dn>, #0.0
    if isDr(v0) && isFloatLit(v1, 0.0) {
        p.Domain = DomainFloat
        sa_dn := uint32(v0.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 1, 0, 0, sa_dn, 8))
    }
    // FCMP  <Dn>, <Dm>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dn_1 := uint32(v0.(asm.Register).ID())
        sa_dm := uint32(v1.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 1, sa_dm, 0, sa_dn_1, 0))
    }
    // FCMP  <Hn>, #0.0
    if isHr(v0) && isFloatLit(v1, 0.0) {
        p.Domain = DomainFloat
        sa_hn := uint32(v0.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 3, 0, 0, sa_hn, 8))
    }
    // FCMP  <Hn>, <Hm>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hn_1 := uint32(v0.(asm.Register).ID())
        sa_hm := uint32(v1.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 3, sa_hm, 0, sa_hn_1, 0))
    }
    // FCMP  <Sn>, #0.0
    if isSr(v0) && isFloatLit(v1, 0.0) {
        p.Domain = DomainFloat
        sa_sn := uint32(v0.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 0, 0, 0, sa_sn, 8))
    }
    // FCMP  <Sn>, <Sm>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sn_1 := uint32(v0.(asm.Register).ID())
        sa_sm := uint32(v1.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 0, sa_sm, 0, sa_sn_1, 0))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCMP")
}

// FCMPE instruction have 6 forms across one single category:
//
// 1. Floating-point signaling Compare (scalar)
//
//    FCMPE  <Dn>, #0.0
//    FCMPE  <Dn>, <Dm>
//    FCMPE  <Hn>, #0.0
//    FCMPE  <Hn>, <Hm>
//    FCMPE  <Sn>, #0.0
//    FCMPE  <Sn>, <Sm>
//
// Floating-point signaling Compare (scalar). This instruction compares the two
// SIMD&FP source register values, or the first SIMD&FP source register value and
// zero. It writes the result to the PSTATE .{N, Z, C, V} flags.
//
// This instruction raises an Invalid Operation floating-point exception if either
// or both of the operands is any type of NaN.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCMPE(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCMPE", 2, asm.Operands { v0, v1 })
    // FCMPE  <Dn>, #0.0
    if isDr(v0) && isFloatLit(v1, 0.0) {
        p.Domain = DomainFloat
        sa_dn := uint32(v0.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 1, 0, 0, sa_dn, 24))
    }
    // FCMPE  <Dn>, <Dm>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dn_1 := uint32(v0.(asm.Register).ID())
        sa_dm := uint32(v1.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 1, sa_dm, 0, sa_dn_1, 16))
    }
    // FCMPE  <Hn>, #0.0
    if isHr(v0) && isFloatLit(v1, 0.0) {
        p.Domain = DomainFloat
        sa_hn := uint32(v0.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 3, 0, 0, sa_hn, 24))
    }
    // FCMPE  <Hn>, <Hm>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hn_1 := uint32(v0.(asm.Register).ID())
        sa_hm := uint32(v1.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 3, sa_hm, 0, sa_hn_1, 16))
    }
    // FCMPE  <Sn>, #0.0
    if isSr(v0) && isFloatLit(v1, 0.0) {
        p.Domain = DomainFloat
        sa_sn := uint32(v0.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 0, 0, 0, sa_sn, 24))
    }
    // FCMPE  <Sn>, <Sm>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sn_1 := uint32(v0.(asm.Register).ID())
        sa_sm := uint32(v1.(asm.Register).ID())
        return p.setins(floatcmp(0, 0, 0, sa_sm, 0, sa_sn_1, 16))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCMPE")
}

// FCSEL instruction have 3 forms across one single category:
//
// 1. Floating-point Conditional Select (scalar)
//
//    FCSEL  <Dd>, <Dn>, <Dm>, <cond>
//    FCSEL  <Hd>, <Hn>, <Hm>, <cond>
//    FCSEL  <Sd>, <Sn>, <Sm>, <cond>
//
// Floating-point Conditional Select (scalar). This instruction allows the SIMD&FP
// destination register to take the value from either one or the other of two
// SIMD&FP source registers. If the condition passes, the first SIMD&FP source
// register value is taken, otherwise the second SIMD&FP source register value is
// taken.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCSEL(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("FCSEL", 4, asm.Operands { v0, v1, v2, v3 })
    // FCSEL  <Dd>, <Dn>, <Dm>, <cond>
    if isDr(v0) && isDr(v1) && isDr(v2) && isBrCond(v3) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(floatsel(0, 0, 1, sa_dm, sa_cond, sa_dn, sa_dd))
    }
    // FCSEL  <Hd>, <Hn>, <Hm>, <cond>
    if isHr(v0) && isHr(v1) && isHr(v2) && isBrCond(v3) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(floatsel(0, 0, 3, sa_hm, sa_cond, sa_hn, sa_hd))
    }
    // FCSEL  <Sd>, <Sn>, <Sm>, <cond>
    if isSr(v0) && isSr(v1) && isSr(v2) && isBrCond(v3) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        sa_cond := uint32(v3.(ConditionCode))
        return p.setins(floatsel(0, 0, 0, sa_sm, sa_cond, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCSEL")
}

// FCVT instruction have 6 forms across one single category:
//
// 1. Floating-point Convert precision (scalar)
//
//    FCVT  <Dd>, <Hn>
//    FCVT  <Dd>, <Sn>
//    FCVT  <Hd>, <Dn>
//    FCVT  <Hd>, <Sn>
//    FCVT  <Sd>, <Dn>
//    FCVT  <Sd>, <Hn>
//
// Floating-point Convert precision (scalar). This instruction converts the
// floating-point value in the SIMD&FP source register to the precision for the
// destination register data type using the rounding mode that is determined by the
// FPCR and writes the result to the SIMD&FP destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVT(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVT", 2, asm.Operands { v0, v1 })
    // FCVT  <Dd>, <Hn>
    if isDr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 5, sa_hn, sa_dd))
    }
    // FCVT  <Dd>, <Sn>
    if isDr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 5, sa_sn, sa_dd))
    }
    // FCVT  <Hd>, <Dn>
    if isHr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 7, sa_dn, sa_hd))
    }
    // FCVT  <Hd>, <Sn>
    if isHr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 7, sa_sn, sa_hd))
    }
    // FCVT  <Sd>, <Dn>
    if isSr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 4, sa_dn, sa_sd))
    }
    // FCVT  <Sd>, <Hn>
    if isSr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 4, sa_hn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVT")
}

// FCVTAS instruction have 10 forms across 2 categories:
//
// 1. Floating-point Convert to Signed integer, rounding to nearest with ties to
//    Away (vector)
//
//    FCVTAS  <Vd>.<T>, <Vn>.<T>
//    FCVTAS  <Vd>.<T>, <Vn>.<T>
//    FCVTAS  <V><d>, <V><n>
//    FCVTAS  <Hd>, <Hn>
//
// Floating-point Convert to Signed integer, rounding to nearest with ties to Away
// (vector). This instruction converts each element in a vector from a floating-
// point value to a signed integer value using the Round to Nearest with Ties to
// Away rounding mode and writes the result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Convert to Signed integer, rounding to nearest with ties to
//    Away (scalar)
//
//    FCVTAS  <Wd>, <Dn>
//    FCVTAS  <Wd>, <Hn>
//    FCVTAS  <Wd>, <Sn>
//    FCVTAS  <Xd>, <Dn>
//    FCVTAS  <Xd>, <Hn>
//    FCVTAS  <Xd>, <Sn>
//
// Floating-point Convert to Signed integer, rounding to nearest with ties to Away
// (scalar). This instruction converts the floating-point value in the SIMD&FP
// source register to a 32-bit or 64-bit signed integer using the Round to Nearest
// with Ties to Away rounding mode, and writes the result to the general-purpose
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTAS(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTAS", 2, asm.Operands { v0, v1 })
    // FCVTAS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 28, sa_vn, sa_vd))
    }
    // FCVTAS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 0, 28, sa_vn, sa_vd))
    }
    // FCVTAS  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTAS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 28, sa_n, sa_d))
    }
    // FCVTAS  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 0, 28, sa_hn, sa_hd))
    }
    // FCVTAS  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 0, 4, sa_dn, sa_wd))
    }
    // FCVTAS  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 0, 4, sa_hn, sa_wd))
    }
    // FCVTAS  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 0, 4, sa_sn, sa_wd))
    }
    // FCVTAS  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 0, 4, sa_dn, sa_xd))
    }
    // FCVTAS  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 0, 4, sa_hn, sa_xd))
    }
    // FCVTAS  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 0, 4, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTAS")
}

// FCVTAU instruction have 10 forms across 2 categories:
//
// 1. Floating-point Convert to Unsigned integer, rounding to nearest with ties to
//    Away (vector)
//
//    FCVTAU  <Vd>.<T>, <Vn>.<T>
//    FCVTAU  <Vd>.<T>, <Vn>.<T>
//    FCVTAU  <V><d>, <V><n>
//    FCVTAU  <Hd>, <Hn>
//
// Floating-point Convert to Unsigned integer, rounding to nearest with ties to
// Away (vector). This instruction converts each element in a vector from a
// floating-point value to an unsigned integer value using the Round to Nearest
// with Ties to Away rounding mode and writes the result to the SIMD&FP destination
// register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Convert to Unsigned integer, rounding to nearest with ties to
//    Away (scalar)
//
//    FCVTAU  <Wd>, <Dn>
//    FCVTAU  <Wd>, <Hn>
//    FCVTAU  <Wd>, <Sn>
//    FCVTAU  <Xd>, <Dn>
//    FCVTAU  <Xd>, <Hn>
//    FCVTAU  <Xd>, <Sn>
//
// Floating-point Convert to Unsigned integer, rounding to nearest with ties to
// Away (scalar). This instruction converts the floating-point value in the SIMD&FP
// source register to a 32-bit or 64-bit unsigned integer using the Round to
// Nearest with Ties to Away rounding mode, and writes the result to the general-
// purpose destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTAU(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTAU", 2, asm.Operands { v0, v1 })
    // FCVTAU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 28, sa_vn, sa_vd))
    }
    // FCVTAU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 0, 28, sa_vn, sa_vd))
    }
    // FCVTAU  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTAU")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdmisc(1, size, 28, sa_n, sa_d))
    }
    // FCVTAU  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(1, 0, 28, sa_hn, sa_hd))
    }
    // FCVTAU  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 0, 5, sa_dn, sa_wd))
    }
    // FCVTAU  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 0, 5, sa_hn, sa_wd))
    }
    // FCVTAU  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 0, 5, sa_sn, sa_wd))
    }
    // FCVTAU  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 0, 5, sa_dn, sa_xd))
    }
    // FCVTAU  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 0, 5, sa_hn, sa_xd))
    }
    // FCVTAU  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 0, 5, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTAU")
}

// FCVTL instruction have one single form across one single category:
//
// 1. Floating-point Convert to higher precision Long (vector)
//
//    FCVTL  <Vd>.<Ta>, <Vn>.<Tb>
//
// Floating-point Convert to higher precision Long (vector). This instruction reads
// each element in a vector in the SIMD&FP source register, converts each value to
// double the precision of the source element using the rounding mode that is
// determined by the FPCR , and writes each result to the equivalent element of the
// vector in the SIMD&FP destination register.
//
// Where the operation lengthens a 64-bit vector to a 128-bit vector, the FCVTL2
// variant operates on the elements in the top 64 bits of the source register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTL(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTL", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b0
            case Vec2D: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b00
            case Vec8H: sa_tb = 0b01
            case Vec2S: sa_tb = 0b10
            case Vec4S: sa_tb = 0b11
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_ta
        if sa_ta != ubfx(sa_tb, 1, 1) {
            panic("aarch64: invalid combination of operands for FCVTL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for FCVTL")
        }
        return p.setins(asimdmisc(0, 0, size, 23, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTL")
}

// FCVTL2 instruction have one single form across one single category:
//
// 1. Floating-point Convert to higher precision Long (vector)
//
//    FCVTL2  <Vd>.<Ta>, <Vn>.<Tb>
//
// Floating-point Convert to higher precision Long (vector). This instruction reads
// each element in a vector in the SIMD&FP source register, converts each value to
// double the precision of the source element using the rounding mode that is
// determined by the FPCR , and writes each result to the equivalent element of the
// vector in the SIMD&FP destination register.
//
// Where the operation lengthens a 64-bit vector to a 128-bit vector, the FCVTL2
// variant operates on the elements in the top 64 bits of the source register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTL2(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTL2", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b0
            case Vec2D: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b00
            case Vec8H: sa_tb = 0b01
            case Vec2S: sa_tb = 0b10
            case Vec4S: sa_tb = 0b11
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_ta
        if sa_ta != ubfx(sa_tb, 1, 1) {
            panic("aarch64: invalid combination of operands for FCVTL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for FCVTL2")
        }
        return p.setins(asimdmisc(1, 0, size, 23, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTL2")
}

// FCVTMS instruction have 10 forms across 2 categories:
//
// 1. Floating-point Convert to Signed integer, rounding toward Minus infinity
//    (vector)
//
//    FCVTMS  <Vd>.<T>, <Vn>.<T>
//    FCVTMS  <Vd>.<T>, <Vn>.<T>
//    FCVTMS  <V><d>, <V><n>
//    FCVTMS  <Hd>, <Hn>
//
// Floating-point Convert to Signed integer, rounding toward Minus infinity
// (vector). This instruction converts a scalar or each element in a vector from a
// floating-point value to a signed integer value using the Round towards Minus
// Infinity rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Floating-point Convert to Signed integer, rounding toward Minus infinity
//    (scalar)
//
//    FCVTMS  <Wd>, <Dn>
//    FCVTMS  <Wd>, <Hn>
//    FCVTMS  <Wd>, <Sn>
//    FCVTMS  <Xd>, <Dn>
//    FCVTMS  <Xd>, <Hn>
//    FCVTMS  <Xd>, <Sn>
//
// Floating-point Convert to Signed integer, rounding toward Minus infinity
// (scalar). This instruction converts the floating-point value in the SIMD&FP
// source register to a 32-bit or 64-bit signed integer using the Round towards
// Minus Infinity rounding mode, and writes the result to the general-purpose
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTMS(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTMS", 2, asm.Operands { v0, v1 })
    // FCVTMS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 27, sa_vn, sa_vd))
    }
    // FCVTMS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 0, 27, sa_vn, sa_vd))
    }
    // FCVTMS  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTMS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 27, sa_n, sa_d))
    }
    // FCVTMS  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 0, 27, sa_hn, sa_hd))
    }
    // FCVTMS  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 2, 0, sa_dn, sa_wd))
    }
    // FCVTMS  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 2, 0, sa_hn, sa_wd))
    }
    // FCVTMS  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 2, 0, sa_sn, sa_wd))
    }
    // FCVTMS  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 2, 0, sa_dn, sa_xd))
    }
    // FCVTMS  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 2, 0, sa_hn, sa_xd))
    }
    // FCVTMS  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 2, 0, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTMS")
}

// FCVTMU instruction have 10 forms across 2 categories:
//
// 1. Floating-point Convert to Unsigned integer, rounding toward Minus infinity
//    (vector)
//
//    FCVTMU  <Vd>.<T>, <Vn>.<T>
//    FCVTMU  <Vd>.<T>, <Vn>.<T>
//    FCVTMU  <V><d>, <V><n>
//    FCVTMU  <Hd>, <Hn>
//
// Floating-point Convert to Unsigned integer, rounding toward Minus infinity
// (vector). This instruction converts a scalar or each element in a vector from a
// floating-point value to an unsigned integer value using the Round towards Minus
// Infinity rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Floating-point Convert to Unsigned integer, rounding toward Minus infinity
//    (scalar)
//
//    FCVTMU  <Wd>, <Dn>
//    FCVTMU  <Wd>, <Hn>
//    FCVTMU  <Wd>, <Sn>
//    FCVTMU  <Xd>, <Dn>
//    FCVTMU  <Xd>, <Hn>
//    FCVTMU  <Xd>, <Sn>
//
// Floating-point Convert to Unsigned integer, rounding toward Minus infinity
// (scalar). This instruction converts the floating-point value in the SIMD&FP
// source register to a 32-bit or 64-bit unsigned integer using the Round towards
// Minus Infinity rounding mode, and writes the result to the general-purpose
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTMU(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTMU", 2, asm.Operands { v0, v1 })
    // FCVTMU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 27, sa_vn, sa_vd))
    }
    // FCVTMU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 0, 27, sa_vn, sa_vd))
    }
    // FCVTMU  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTMU")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdmisc(1, size, 27, sa_n, sa_d))
    }
    // FCVTMU  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(1, 0, 27, sa_hn, sa_hd))
    }
    // FCVTMU  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 2, 1, sa_dn, sa_wd))
    }
    // FCVTMU  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 2, 1, sa_hn, sa_wd))
    }
    // FCVTMU  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 2, 1, sa_sn, sa_wd))
    }
    // FCVTMU  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 2, 1, sa_dn, sa_xd))
    }
    // FCVTMU  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 2, 1, sa_hn, sa_xd))
    }
    // FCVTMU  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 2, 1, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTMU")
}

// FCVTN instruction have one single form across one single category:
//
// 1. Floating-point Convert to lower precision Narrow (vector)
//
//    FCVTN  <Vd>.<Tb>, <Vn>.<Ta>
//
// Floating-point Convert to lower precision Narrow (vector). This instruction
// reads each vector element in the SIMD&FP source register, converts each result
// to half the precision of the source element, writes the final result to a
// vector, and writes the vector to the lower or upper half of the destination
// SIMD&FP register. The destination vector elements are half as long as the source
// vector elements. The rounding mode is determined by the FPCR .
//
// The FCVTN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the FCVTN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// or a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
func (self *Program) FCVTN(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTN", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) && isVr(v1) && isVfmt(v1, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_tb = 0b00
            case Vec8H: sa_tb = 0b01
            case Vec2S: sa_tb = 0b10
            case Vec4S: sa_tb = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4S: sa_ta = 0b0
            case Vec2D: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= ubfx(sa_tb, 1, 1)
        if ubfx(sa_tb, 1, 1) != sa_ta {
            panic("aarch64: invalid combination of operands for FCVTN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for FCVTN")
        }
        return p.setins(asimdmisc(0, 0, size, 22, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTN")
}

// FCVTN2 instruction have one single form across one single category:
//
// 1. Floating-point Convert to lower precision Narrow (vector)
//
//    FCVTN2  <Vd>.<Tb>, <Vn>.<Ta>
//
// Floating-point Convert to lower precision Narrow (vector). This instruction
// reads each vector element in the SIMD&FP source register, converts each result
// to half the precision of the source element, writes the final result to a
// vector, and writes the vector to the lower or upper half of the destination
// SIMD&FP register. The destination vector elements are half as long as the source
// vector elements. The rounding mode is determined by the FPCR .
//
// The FCVTN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the FCVTN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// or a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
func (self *Program) FCVTN2(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTN2", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) && isVr(v1) && isVfmt(v1, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_tb = 0b00
            case Vec8H: sa_tb = 0b01
            case Vec2S: sa_tb = 0b10
            case Vec4S: sa_tb = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4S: sa_ta = 0b0
            case Vec2D: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= ubfx(sa_tb, 1, 1)
        if ubfx(sa_tb, 1, 1) != sa_ta {
            panic("aarch64: invalid combination of operands for FCVTN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for FCVTN2")
        }
        return p.setins(asimdmisc(1, 0, size, 22, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTN2")
}

// FCVTNS instruction have 10 forms across 2 categories:
//
// 1. Floating-point Convert to Signed integer, rounding to nearest with ties to
//    even (vector)
//
//    FCVTNS  <Vd>.<T>, <Vn>.<T>
//    FCVTNS  <Vd>.<T>, <Vn>.<T>
//    FCVTNS  <V><d>, <V><n>
//    FCVTNS  <Hd>, <Hn>
//
// Floating-point Convert to Signed integer, rounding to nearest with ties to even
// (vector). This instruction converts a scalar or each element in a vector from a
// floating-point value to a signed integer value using the Round to Nearest
// rounding mode, and writes the result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Floating-point Convert to Signed integer, rounding to nearest with ties to
//    even (scalar)
//
//    FCVTNS  <Wd>, <Dn>
//    FCVTNS  <Wd>, <Hn>
//    FCVTNS  <Wd>, <Sn>
//    FCVTNS  <Xd>, <Dn>
//    FCVTNS  <Xd>, <Hn>
//    FCVTNS  <Xd>, <Sn>
//
// Floating-point Convert to Signed integer, rounding to nearest with ties to even
// (scalar). This instruction converts the floating-point value in the SIMD&FP
// source register to a 32-bit or 64-bit signed integer using the Round to Nearest
// rounding mode, and writes the result to the general-purpose destination
// register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTNS(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTNS", 2, asm.Operands { v0, v1 })
    // FCVTNS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 26, sa_vn, sa_vd))
    }
    // FCVTNS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 0, 26, sa_vn, sa_vd))
    }
    // FCVTNS  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTNS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 26, sa_n, sa_d))
    }
    // FCVTNS  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 0, 26, sa_hn, sa_hd))
    }
    // FCVTNS  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 0, 0, sa_dn, sa_wd))
    }
    // FCVTNS  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 0, 0, sa_hn, sa_wd))
    }
    // FCVTNS  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 0, 0, sa_sn, sa_wd))
    }
    // FCVTNS  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 0, 0, sa_dn, sa_xd))
    }
    // FCVTNS  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 0, 0, sa_hn, sa_xd))
    }
    // FCVTNS  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 0, 0, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTNS")
}

// FCVTNU instruction have 10 forms across 2 categories:
//
// 1. Floating-point Convert to Unsigned integer, rounding to nearest with ties to
//    even (vector)
//
//    FCVTNU  <Vd>.<T>, <Vn>.<T>
//    FCVTNU  <Vd>.<T>, <Vn>.<T>
//    FCVTNU  <V><d>, <V><n>
//    FCVTNU  <Hd>, <Hn>
//
// Floating-point Convert to Unsigned integer, rounding to nearest with ties to
// even (vector). This instruction converts a scalar or each element in a vector
// from a floating-point value to an unsigned integer value using the Round to
// Nearest rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Floating-point Convert to Unsigned integer, rounding to nearest with ties to
//    even (scalar)
//
//    FCVTNU  <Wd>, <Dn>
//    FCVTNU  <Wd>, <Hn>
//    FCVTNU  <Wd>, <Sn>
//    FCVTNU  <Xd>, <Dn>
//    FCVTNU  <Xd>, <Hn>
//    FCVTNU  <Xd>, <Sn>
//
// Floating-point Convert to Unsigned integer, rounding to nearest with ties to
// even (scalar). This instruction converts the floating-point value in the SIMD&FP
// source register to a 32-bit or 64-bit unsigned integer using the Round to
// Nearest rounding mode, and writes the result to the general-purpose destination
// register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTNU(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTNU", 2, asm.Operands { v0, v1 })
    // FCVTNU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 26, sa_vn, sa_vd))
    }
    // FCVTNU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 0, 26, sa_vn, sa_vd))
    }
    // FCVTNU  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTNU")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdmisc(1, size, 26, sa_n, sa_d))
    }
    // FCVTNU  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(1, 0, 26, sa_hn, sa_hd))
    }
    // FCVTNU  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 0, 1, sa_dn, sa_wd))
    }
    // FCVTNU  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 0, 1, sa_hn, sa_wd))
    }
    // FCVTNU  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 0, 1, sa_sn, sa_wd))
    }
    // FCVTNU  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 0, 1, sa_dn, sa_xd))
    }
    // FCVTNU  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 0, 1, sa_hn, sa_xd))
    }
    // FCVTNU  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 0, 1, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTNU")
}

// FCVTPS instruction have 10 forms across 2 categories:
//
// 1. Floating-point Convert to Signed integer, rounding toward Plus infinity
//    (vector)
//
//    FCVTPS  <Vd>.<T>, <Vn>.<T>
//    FCVTPS  <Vd>.<T>, <Vn>.<T>
//    FCVTPS  <V><d>, <V><n>
//    FCVTPS  <Hd>, <Hn>
//
// Floating-point Convert to Signed integer, rounding toward Plus infinity
// (vector). This instruction converts a scalar or each element in a vector from a
// floating-point value to a signed integer value using the Round towards Plus
// Infinity rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Floating-point Convert to Signed integer, rounding toward Plus infinity
//    (scalar)
//
//    FCVTPS  <Wd>, <Dn>
//    FCVTPS  <Wd>, <Hn>
//    FCVTPS  <Wd>, <Sn>
//    FCVTPS  <Xd>, <Dn>
//    FCVTPS  <Xd>, <Hn>
//    FCVTPS  <Xd>, <Sn>
//
// Floating-point Convert to Signed integer, rounding toward Plus infinity
// (scalar). This instruction converts the floating-point value in the SIMD&FP
// source register to a 32-bit or 64-bit signed integer using the Round towards
// Plus Infinity rounding mode, and writes the result to the general-purpose
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTPS(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTPS", 2, asm.Operands { v0, v1 })
    // FCVTPS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 26, sa_vn, sa_vd))
    }
    // FCVTPS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 1, 26, sa_vn, sa_vd))
    }
    // FCVTPS  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTPS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 26, sa_n, sa_d))
    }
    // FCVTPS  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 1, 26, sa_hn, sa_hd))
    }
    // FCVTPS  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 1, 0, sa_dn, sa_wd))
    }
    // FCVTPS  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 1, 0, sa_hn, sa_wd))
    }
    // FCVTPS  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 1, 0, sa_sn, sa_wd))
    }
    // FCVTPS  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 1, 0, sa_dn, sa_xd))
    }
    // FCVTPS  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 1, 0, sa_hn, sa_xd))
    }
    // FCVTPS  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 1, 0, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTPS")
}

// FCVTPU instruction have 10 forms across 2 categories:
//
// 1. Floating-point Convert to Unsigned integer, rounding toward Plus infinity
//    (vector)
//
//    FCVTPU  <Vd>.<T>, <Vn>.<T>
//    FCVTPU  <Vd>.<T>, <Vn>.<T>
//    FCVTPU  <V><d>, <V><n>
//    FCVTPU  <Hd>, <Hn>
//
// Floating-point Convert to Unsigned integer, rounding toward Plus infinity
// (vector). This instruction converts a scalar or each element in a vector from a
// floating-point value to an unsigned integer value using the Round towards Plus
// Infinity rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Floating-point Convert to Unsigned integer, rounding toward Plus infinity
//    (scalar)
//
//    FCVTPU  <Wd>, <Dn>
//    FCVTPU  <Wd>, <Hn>
//    FCVTPU  <Wd>, <Sn>
//    FCVTPU  <Xd>, <Dn>
//    FCVTPU  <Xd>, <Hn>
//    FCVTPU  <Xd>, <Sn>
//
// Floating-point Convert to Unsigned integer, rounding toward Plus infinity
// (scalar). This instruction converts the floating-point value in the SIMD&FP
// source register to a 32-bit or 64-bit unsigned integer using the Round towards
// Plus Infinity rounding mode, and writes the result to the general-purpose
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTPU(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTPU", 2, asm.Operands { v0, v1 })
    // FCVTPU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 26, sa_vn, sa_vd))
    }
    // FCVTPU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 1, 26, sa_vn, sa_vd))
    }
    // FCVTPU  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTPU")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(1, size, 26, sa_n, sa_d))
    }
    // FCVTPU  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(1, 1, 26, sa_hn, sa_hd))
    }
    // FCVTPU  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 1, 1, sa_dn, sa_wd))
    }
    // FCVTPU  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 1, 1, sa_hn, sa_wd))
    }
    // FCVTPU  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 1, 1, sa_sn, sa_wd))
    }
    // FCVTPU  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 1, 1, sa_dn, sa_xd))
    }
    // FCVTPU  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 1, 1, sa_hn, sa_xd))
    }
    // FCVTPU  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 1, 1, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTPU")
}

// FCVTXN instruction have 2 forms across one single category:
//
// 1. Floating-point Convert to lower precision Narrow, rounding to odd (vector)
//
//    FCVTXN  <Vb><d>, <Va><n>
//    FCVTXN  <Vd>.<Tb>, <Vn>.<Ta>
//
// Floating-point Convert to lower precision Narrow, rounding to odd (vector). This
// instruction reads each vector element in the source SIMD&FP register, narrows
// each value to half the precision of the source element using the Round to Odd
// rounding mode, writes the result to a vector, and writes the vector to the
// destination SIMD&FP register.
//
// NOTE: 
//     This instruction uses the Round to Odd rounding mode which is not
//     defined by the IEEE 754-2008 standard. This rounding mode ensures that
//     if the result of the conversion is inexact the least significant bit of
//     the mantissa is forced to 1. This rounding mode enables a floating-point
//     value to be converted to a lower precision format via an intermediate
//     precision format while avoiding double rounding errors. For example, a
//     64-bit floating-point value can be converted to a correctly rounded
//     16-bit floating-point value by first using this instruction to produce a
//     32-bit value and then using another instruction with the wanted rounding
//     mode to convert the 32-bit value to the final 16-bit floating-point
//     value.
//
// The FCVTXN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the FCVTXN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTXN(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTXN", 2, asm.Operands { v0, v1 })
    // FCVTXN  <Vb><d>, <Va><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) {
        p.Domain = DomainAdvSimd
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_vb = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTXN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case DRegister: sa_va = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTXN")
        }
        size := uint32(0b00)
        size |= sa_vb
        if sa_vb != sa_va {
            panic("aarch64: invalid combination of operands for FCVTXN")
        }
        return p.setins(asisdmisc(1, size, 22, sa_n, sa_d))
    }
    // FCVTXN  <Vd>.<Tb>, <Vn>.<Ta>
    if isVr(v0) && isVfmt(v0, Vec2S, Vec4S) && isVr(v1) && vfmt(v1) == Vec2D {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_tb = 0b10
            case Vec4S: sa_tb = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2D: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= ubfx(sa_tb, 1, 1)
        if ubfx(sa_tb, 1, 1) != sa_ta {
            panic("aarch64: invalid combination of operands for FCVTXN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for FCVTXN")
        }
        return p.setins(asimdmisc(0, 1, size, 22, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTXN")
}

// FCVTXN2 instruction have one single form across one single category:
//
// 1. Floating-point Convert to lower precision Narrow, rounding to odd (vector)
//
//    FCVTXN2  <Vd>.<Tb>, <Vn>.<Ta>
//
// Floating-point Convert to lower precision Narrow, rounding to odd (vector). This
// instruction reads each vector element in the source SIMD&FP register, narrows
// each value to half the precision of the source element using the Round to Odd
// rounding mode, writes the result to a vector, and writes the vector to the
// destination SIMD&FP register.
//
// NOTE: 
//     This instruction uses the Round to Odd rounding mode which is not
//     defined by the IEEE 754-2008 standard. This rounding mode ensures that
//     if the result of the conversion is inexact the least significant bit of
//     the mantissa is forced to 1. This rounding mode enables a floating-point
//     value to be converted to a lower precision format via an intermediate
//     precision format while avoiding double rounding errors. For example, a
//     64-bit floating-point value can be converted to a correctly rounded
//     16-bit floating-point value by first using this instruction to produce a
//     32-bit value and then using another instruction with the wanted rounding
//     mode to convert the 32-bit value to the final 16-bit floating-point
//     value.
//
// The FCVTXN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the FCVTXN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTXN2(v0, v1 interface{}) *Instruction {
    p := self.alloc("FCVTXN2", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec2S, Vec4S) && isVr(v1) && vfmt(v1) == Vec2D {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_tb = 0b10
            case Vec4S: sa_tb = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2D: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= ubfx(sa_tb, 1, 1)
        if ubfx(sa_tb, 1, 1) != sa_ta {
            panic("aarch64: invalid combination of operands for FCVTXN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for FCVTXN2")
        }
        return p.setins(asimdmisc(1, 1, size, 22, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTXN2")
}

// FCVTZS instruction have 18 forms across 4 categories:
//
// 1. Floating-point Convert to Signed fixed-point, rounding toward Zero (vector)
//
//    FCVTZS  <Vd>.<T>, <Vn>.<T>, #<fbits>
//    FCVTZS  <V><d>, <V><n>, #<fbits>
//
// Floating-point Convert to Signed fixed-point, rounding toward Zero (vector).
// This instruction converts a scalar or each element in a vector from floating-
// point to fixed-point signed integer using the Round towards Zero rounding mode,
// and writes the result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Floating-point Convert to Signed integer, rounding toward Zero (vector)
//
//    FCVTZS  <Vd>.<T>, <Vn>.<T>
//    FCVTZS  <Vd>.<T>, <Vn>.<T>
//    FCVTZS  <V><d>, <V><n>
//    FCVTZS  <Hd>, <Hn>
//
// Floating-point Convert to Signed integer, rounding toward Zero (vector). This
// instruction converts a scalar or each element in a vector from a floating-point
// value to a signed integer value using the Round towards Zero rounding mode, and
// writes the result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 3. Floating-point Convert to Signed fixed-point, rounding toward Zero (scalar)
//
//    FCVTZS  <Wd>, <Dn>, #<fbits>
//    FCVTZS  <Wd>, <Hn>, #<fbits>
//    FCVTZS  <Wd>, <Sn>, #<fbits>
//    FCVTZS  <Xd>, <Dn>, #<fbits>
//    FCVTZS  <Xd>, <Hn>, #<fbits>
//    FCVTZS  <Xd>, <Sn>, #<fbits>
//
// Floating-point Convert to Signed fixed-point, rounding toward Zero (scalar).
// This instruction converts the floating-point value in the SIMD&FP source
// register to a 32-bit or 64-bit fixed-point signed integer using the Round
// towards Zero rounding mode, and writes the result to the general-purpose
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 4. Floating-point Convert to Signed integer, rounding toward Zero (scalar)
//
//    FCVTZS  <Wd>, <Dn>
//    FCVTZS  <Wd>, <Hn>
//    FCVTZS  <Wd>, <Sn>
//    FCVTZS  <Xd>, <Dn>
//    FCVTZS  <Xd>, <Hn>
//    FCVTZS  <Xd>, <Sn>
//
// Floating-point Convert to Signed integer, rounding toward Zero (scalar). This
// instruction converts the floating-point value in the SIMD&FP source register to
// a 32-bit or 64-bit signed integer using the Round towards Zero rounding mode,
// and writes the result to the general-purpose destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTZS(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("FCVTZS", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("FCVTZS", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction FCVTZS takes 2 or 3 operands")
    }
    // FCVTZS  <Vd>.<T>, <Vn>.<T>, #<fbits>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(vv[0]) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_fbits uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0010: sa_fbits = 32 - uint32(asLit(vv[0]))
            case 0b0100: sa_fbits = 64 - uint32(asLit(vv[0]))
            case 0b1000: sa_fbits = 128 - uint32(asLit(vv[0]))
            default: panic("aarch64: invalid operand 'sa_fbits' for FCVTZS")
        }
        if ubfx(sa_fbits, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for FCVTZS")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 0, ubfx(sa_fbits, 3, 4), mask(sa_fbits, 3), 31, sa_vn, sa_vd))
    }
    // FCVTZS  <V><d>, <V><n>, #<fbits>
    if len(vv) == 1 && isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(vv[0]) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_fbits_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b0010
            case SRegister: sa_v = 0b0100
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for FCVTZS")
        }
        switch v0.(type) {
            case HRegister: sa_v__bit_mask = 0b1110
            case SRegister: sa_v__bit_mask = 0b1100
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for FCVTZS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b0010: sa_fbits_1 = 32 - uint32(asLit(vv[0]))
            case 0b0100: sa_fbits_1 = 64 - uint32(asLit(vv[0]))
            case 0b1000: sa_fbits_1 = 128 - uint32(asLit(vv[0]))
            default: panic("aarch64: invalid operand 'sa_fbits_1' for FCVTZS")
        }
        if ubfx(sa_fbits_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for FCVTZS")
        }
        return p.setins(asisdshf(0, ubfx(sa_fbits_1, 3, 4), mask(sa_fbits_1, 3), 31, sa_n, sa_d))
    }
    // FCVTZS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 27, sa_vn, sa_vd))
    }
    // FCVTZS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 1, 27, sa_vn, sa_vd))
    }
    // FCVTZS  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTZS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 27, sa_n, sa_d))
    }
    // FCVTZS  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 1, 27, sa_hn, sa_hd))
    }
    // FCVTZS  <Wd>, <Dn>, #<fbits>
    if len(vv) == 1 && isWr(v0) && isDr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 1, 3, 0, sa_fbits, sa_dn, sa_wd))
    }
    // FCVTZS  <Wd>, <Hn>, #<fbits>
    if len(vv) == 1 && isWr(v0) && isHr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 3, 3, 0, sa_fbits, sa_hn, sa_wd))
    }
    // FCVTZS  <Wd>, <Sn>, #<fbits>
    if len(vv) == 1 && isWr(v0) && isSr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 0, 3, 0, sa_fbits, sa_sn, sa_wd))
    }
    // FCVTZS  <Xd>, <Dn>, #<fbits>
    if len(vv) == 1 && isXr(v0) && isDr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 1, 3, 0, sa_fbits_1, sa_dn, sa_xd))
    }
    // FCVTZS  <Xd>, <Hn>, #<fbits>
    if len(vv) == 1 && isXr(v0) && isHr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 3, 3, 0, sa_fbits_1, sa_hn, sa_xd))
    }
    // FCVTZS  <Xd>, <Sn>, #<fbits>
    if len(vv) == 1 && isXr(v0) && isSr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 0, 3, 0, sa_fbits_1, sa_sn, sa_xd))
    }
    // FCVTZS  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 3, 0, sa_dn, sa_wd))
    }
    // FCVTZS  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 3, 0, sa_hn, sa_wd))
    }
    // FCVTZS  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 3, 0, sa_sn, sa_wd))
    }
    // FCVTZS  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 3, 0, sa_dn, sa_xd))
    }
    // FCVTZS  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 3, 0, sa_hn, sa_xd))
    }
    // FCVTZS  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 3, 0, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTZS")
}

// FCVTZU instruction have 18 forms across 4 categories:
//
// 1. Floating-point Convert to Unsigned fixed-point, rounding toward Zero (vector)
//
//    FCVTZU  <Vd>.<T>, <Vn>.<T>, #<fbits>
//    FCVTZU  <V><d>, <V><n>, #<fbits>
//
// Floating-point Convert to Unsigned fixed-point, rounding toward Zero (vector).
// This instruction converts a scalar or each element in a vector from floating-
// point to fixed-point unsigned integer using the Round towards Zero rounding
// mode, and writes the result to the general-purpose destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Floating-point Convert to Unsigned integer, rounding toward Zero (vector)
//
//    FCVTZU  <Vd>.<T>, <Vn>.<T>
//    FCVTZU  <Vd>.<T>, <Vn>.<T>
//    FCVTZU  <V><d>, <V><n>
//    FCVTZU  <Hd>, <Hn>
//
// Floating-point Convert to Unsigned integer, rounding toward Zero (vector). This
// instruction converts a scalar or each element in a vector from a floating-point
// value to an unsigned integer value using the Round towards Zero rounding mode,
// and writes the result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 3. Floating-point Convert to Unsigned fixed-point, rounding toward Zero (scalar)
//
//    FCVTZU  <Wd>, <Dn>, #<fbits>
//    FCVTZU  <Wd>, <Hn>, #<fbits>
//    FCVTZU  <Wd>, <Sn>, #<fbits>
//    FCVTZU  <Xd>, <Dn>, #<fbits>
//    FCVTZU  <Xd>, <Hn>, #<fbits>
//    FCVTZU  <Xd>, <Sn>, #<fbits>
//
// Floating-point Convert to Unsigned fixed-point, rounding toward Zero (scalar).
// This instruction converts the floating-point value in the SIMD&FP source
// register to a 32-bit or 64-bit fixed-point unsigned integer using the Round
// towards Zero rounding mode, and writes the result to the general-purpose
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 4. Floating-point Convert to Unsigned integer, rounding toward Zero (scalar)
//
//    FCVTZU  <Wd>, <Dn>
//    FCVTZU  <Wd>, <Hn>
//    FCVTZU  <Wd>, <Sn>
//    FCVTZU  <Xd>, <Dn>
//    FCVTZU  <Xd>, <Hn>
//    FCVTZU  <Xd>, <Sn>
//
// Floating-point Convert to Unsigned integer, rounding toward Zero (scalar). This
// instruction converts the floating-point value in the SIMD&FP source register to
// a 32-bit or 64-bit unsigned integer using the Round towards Zero rounding mode,
// and writes the result to the general-purpose destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FCVTZU(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("FCVTZU", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("FCVTZU", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction FCVTZU takes 2 or 3 operands")
    }
    // FCVTZU  <Vd>.<T>, <Vn>.<T>, #<fbits>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(vv[0]) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_fbits uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0010: sa_fbits = 32 - uint32(asLit(vv[0]))
            case 0b0100: sa_fbits = 64 - uint32(asLit(vv[0]))
            case 0b1000: sa_fbits = 128 - uint32(asLit(vv[0]))
            default: panic("aarch64: invalid operand 'sa_fbits' for FCVTZU")
        }
        if ubfx(sa_fbits, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for FCVTZU")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_fbits, 3, 4), mask(sa_fbits, 3), 31, sa_vn, sa_vd))
    }
    // FCVTZU  <V><d>, <V><n>, #<fbits>
    if len(vv) == 1 && isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(vv[0]) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_fbits_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b0010
            case SRegister: sa_v = 0b0100
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for FCVTZU")
        }
        switch v0.(type) {
            case HRegister: sa_v__bit_mask = 0b1110
            case SRegister: sa_v__bit_mask = 0b1100
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for FCVTZU")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b0010: sa_fbits_1 = 32 - uint32(asLit(vv[0]))
            case 0b0100: sa_fbits_1 = 64 - uint32(asLit(vv[0]))
            case 0b1000: sa_fbits_1 = 128 - uint32(asLit(vv[0]))
            default: panic("aarch64: invalid operand 'sa_fbits_1' for FCVTZU")
        }
        if ubfx(sa_fbits_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for FCVTZU")
        }
        return p.setins(asisdshf(1, ubfx(sa_fbits_1, 3, 4), mask(sa_fbits_1, 3), 31, sa_n, sa_d))
    }
    // FCVTZU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 27, sa_vn, sa_vd))
    }
    // FCVTZU  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 1, 27, sa_vn, sa_vd))
    }
    // FCVTZU  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FCVTZU")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(1, size, 27, sa_n, sa_d))
    }
    // FCVTZU  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(1, 1, 27, sa_hn, sa_hd))
    }
    // FCVTZU  <Wd>, <Dn>, #<fbits>
    if len(vv) == 1 && isWr(v0) && isDr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 1, 3, 1, sa_fbits, sa_dn, sa_wd))
    }
    // FCVTZU  <Wd>, <Hn>, #<fbits>
    if len(vv) == 1 && isWr(v0) && isHr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 3, 3, 1, sa_fbits, sa_hn, sa_wd))
    }
    // FCVTZU  <Wd>, <Sn>, #<fbits>
    if len(vv) == 1 && isWr(v0) && isSr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 0, 3, 1, sa_fbits, sa_sn, sa_wd))
    }
    // FCVTZU  <Xd>, <Dn>, #<fbits>
    if len(vv) == 1 && isXr(v0) && isDr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 1, 3, 1, sa_fbits_1, sa_dn, sa_xd))
    }
    // FCVTZU  <Xd>, <Hn>, #<fbits>
    if len(vv) == 1 && isXr(v0) && isHr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 3, 3, 1, sa_fbits_1, sa_hn, sa_xd))
    }
    // FCVTZU  <Xd>, <Sn>, #<fbits>
    if len(vv) == 1 && isXr(v0) && isSr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 0, 3, 1, sa_fbits_1, sa_sn, sa_xd))
    }
    // FCVTZU  <Wd>, <Dn>
    if isWr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 3, 1, sa_dn, sa_wd))
    }
    // FCVTZU  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 3, 1, sa_hn, sa_wd))
    }
    // FCVTZU  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 3, 1, sa_sn, sa_wd))
    }
    // FCVTZU  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 3, 1, sa_dn, sa_xd))
    }
    // FCVTZU  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 3, 1, sa_hn, sa_xd))
    }
    // FCVTZU  <Xd>, <Sn>
    if isXr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 3, 1, sa_sn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FCVTZU")
}

// FDIV instruction have 5 forms across 2 categories:
//
// 1. Floating-point Divide (vector)
//
//    FDIV  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FDIV  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Divide (vector). This instruction divides the floating-point
// values in the elements in the first source SIMD&FP register, by the floating-
// point values in the corresponding elements in the second source SIMD&FP
// register, places the results in a vector, and writes the vector to the
// destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Divide (scalar)
//
//    FDIV  <Dd>, <Dn>, <Dm>
//    FDIV  <Hd>, <Hn>, <Hm>
//    FDIV  <Sd>, <Sn>, <Sm>
//
// Floating-point Divide (scalar). This instruction divides the floating-point
// value of the first source SIMD&FP register by the floating-point value of the
// second source SIMD&FP register, and writes the result to the destination SIMD&FP
// register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FDIV(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FDIV", 3, asm.Operands { v0, v1, v2 })
    // FDIV  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 31, sa_vn, sa_vd))
    }
    // FDIV  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 0, sa_vm, 7, sa_vn, sa_vd))
    }
    // FDIV  <Dd>, <Dn>, <Dm>
    if isDr(v0) && isDr(v1) && isDr(v2) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 1, sa_dm, 1, sa_dn, sa_dd))
    }
    // FDIV  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 3, sa_hm, 1, sa_hn, sa_hd))
    }
    // FDIV  <Sd>, <Sn>, <Sm>
    if isSr(v0) && isSr(v1) && isSr(v2) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 0, sa_sm, 1, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FDIV")
}

// FJCVTZS instruction have one single form across one single category:
//
// 1. Floating-point Javascript Convert to Signed fixed-point, rounding toward Zero
//
//    FJCVTZS  <Wd>, <Dn>
//
// Floating-point Javascript Convert to Signed fixed-point, rounding toward Zero.
// This instruction converts the double-precision floating-point value in the
// SIMD&FP source register to a 32-bit signed integer using the Round towards Zero
// rounding mode, and writes the result to the general-purpose destination
// register. If the result is too large to be represented as a signed 32-bit
// integer, then the result is the integer modulo 2 ^ 32 , as held in a 32-bit
// signed integer.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FJCVTZS(v0, v1 interface{}) *Instruction {
    p := self.alloc("FJCVTZS", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isDr(v1) {
        self.Arch.Require(FEAT_JSCVT)
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 3, 6, sa_dn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for FJCVTZS")
}

// FMADD instruction have 3 forms across one single category:
//
// 1. Floating-point fused Multiply-Add (scalar)
//
//    FMADD  <Dd>, <Dn>, <Dm>, <Da>
//    FMADD  <Hd>, <Hn>, <Hm>, <Ha>
//    FMADD  <Sd>, <Sn>, <Sm>, <Sa>
//
// Floating-point fused Multiply-Add (scalar). This instruction multiplies the
// values of the first two SIMD&FP source registers, adds the product to the value
// of the third SIMD&FP source register, and writes the result to the SIMD&FP
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMADD(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("FMADD", 4, asm.Operands { v0, v1, v2, v3 })
    // FMADD  <Dd>, <Dn>, <Dm>, <Da>
    if isDr(v0) && isDr(v1) && isDr(v2) && isDr(v3) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        sa_da := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 1, 0, sa_dm, 0, sa_da, sa_dn, sa_dd))
    }
    // FMADD  <Hd>, <Hn>, <Hm>, <Ha>
    if isHr(v0) && isHr(v1) && isHr(v2) && isHr(v3) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        sa_ha := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 3, 0, sa_hm, 0, sa_ha, sa_hn, sa_hd))
    }
    // FMADD  <Sd>, <Sn>, <Sm>, <Sa>
    if isSr(v0) && isSr(v1) && isSr(v2) && isSr(v3) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        sa_sa := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 0, 0, sa_sm, 0, sa_sa, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMADD")
}

// FMAX instruction have 5 forms across 2 categories:
//
// 1. Floating-point Maximum (vector)
//
//    FMAX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMAX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Maximum (vector). This instruction compares corresponding vector
// elements in the two source SIMD&FP registers, places the larger of each of the
// two floating-point values into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// When FPCR .AH is 0, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either element is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either element is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows:
//
//     * If both elements are zeros, regardless of the sign of either zero, the
//       result is the second element.
//     * If either element is a NaN, regardless of the value of FPCR .DN, the
//       result is the second element.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Maximum (scalar)
//
//    FMAX  <Dd>, <Dn>, <Dm>
//    FMAX  <Hd>, <Hn>, <Hm>
//    FMAX  <Sd>, <Sn>, <Sm>
//
// Floating-point Maximum (scalar). This instruction compares the two source
// SIMD&FP registers, and writes the larger of the two floating-point values to the
// destination SIMD&FP register.
//
// When FPCR .AH is 0, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either value is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either value is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows:
//
//     * If both values are zeros, regardless of the sign of either zero, the
//       result is the second value.
//     * If either value is a NaN, regardless of the value of FPCR .DN, the
//       result is the second value.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMAX(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMAX", 3, asm.Operands { v0, v1, v2 })
    // FMAX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 30, sa_vn, sa_vd))
    }
    // FMAX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 0, sa_vm, 6, sa_vn, sa_vd))
    }
    // FMAX  <Dd>, <Dn>, <Dm>
    if isDr(v0) && isDr(v1) && isDr(v2) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 1, sa_dm, 4, sa_dn, sa_dd))
    }
    // FMAX  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 3, sa_hm, 4, sa_hn, sa_hd))
    }
    // FMAX  <Sd>, <Sn>, <Sm>
    if isSr(v0) && isSr(v1) && isSr(v2) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 0, sa_sm, 4, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMAX")
}

// FMAXNM instruction have 5 forms across 2 categories:
//
// 1. Floating-point Maximum Number (vector)
//
//    FMAXNM  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMAXNM  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Maximum Number (vector). This instruction compares corresponding
// vector elements in the two source SIMD&FP registers, writes the larger of the
// two floating-point values into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Regardless of the value of FPCR .AH, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * If one element is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either element is a signaling NaN or if both
//       elements are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either element is a signaling NaN or if both
//       elements are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Maximum Number (scalar)
//
//    FMAXNM  <Dd>, <Dn>, <Dm>
//    FMAXNM  <Hd>, <Hn>, <Hm>
//    FMAXNM  <Sd>, <Sn>, <Sm>
//
// Floating-point Maximum Number (scalar). This instruction compares the first and
// second source SIMD&FP register values, and writes the larger of the two
// floating-point values to the destination SIMD&FP register.
//
// Regardless of the value of FPCR .AH, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * If one value is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either value is a signaling NaN or if both
//       values are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either value is a signaling NaN or if both
//       values are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMAXNM(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMAXNM", 3, asm.Operands { v0, v1, v2 })
    // FMAXNM  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 24, sa_vn, sa_vd))
    }
    // FMAXNM  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 0, sa_vm, 0, sa_vn, sa_vd))
    }
    // FMAXNM  <Dd>, <Dn>, <Dm>
    if isDr(v0) && isDr(v1) && isDr(v2) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 1, sa_dm, 6, sa_dn, sa_dd))
    }
    // FMAXNM  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 3, sa_hm, 6, sa_hn, sa_hd))
    }
    // FMAXNM  <Sd>, <Sn>, <Sm>
    if isSr(v0) && isSr(v1) && isSr(v2) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 0, sa_sm, 6, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMAXNM")
}

// FMAXNMP instruction have 4 forms across 2 categories:
//
// 1. Floating-point Maximum Number of Pair of elements (scalar)
//
//    FMAXNMP  <V><d>, <Vn>.<T>
//    FMAXNMP  <V><d>, <Vn>.<T>
//
// Floating-point Maximum Number of Pair of elements (scalar). This instruction
// compares two vector elements in the source SIMD&FP register and writes the
// largest of the floating-point values as a scalar to the destination SIMD&FP
// register.
//
// Regardless of the value of FPCR .AH, the behavior is as follows for each
// pairwise operation:
//
//     * Negative zero compares less than positive zero.
//     * If one element is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either element is a signaling NaN or if both
//       elements are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either element is a signaling NaN or if both
//       elements are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Maximum Number Pairwise (vector)
//
//    FMAXNMP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMAXNMP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Maximum Number Pairwise (vector). This instruction creates a
// vector by concatenating the vector elements of the first source SIMD&FP register
// after the vector elements of the second source SIMD&FP register, reads each pair
// of adjacent vector elements in the two source SIMD&FP registers, writes the
// largest of each pair of values into a vector, and writes the vector to the
// destination SIMD&FP register. All the values in this instruction are floating-
// point values.
//
// Regardless of the value of FPCR .AH, the behavior is as follows for each
// pairwise operation:
//
//     * Negative zero compares less than positive zero.
//     * If one element is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either element is a signaling NaN or if both
//       elements are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either element is a signaling NaN or if both
//       elements are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMAXNMP(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("FMAXNMP", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("FMAXNMP", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction FMAXNMP takes 2 or 3 operands")
    }
    // FMAXNMP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec2H {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b0
            default: panic("aarch64: invalid scalar operand size for FMAXNMP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_t = 0b0
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_v
        if sa_v != sa_t {
            panic("aarch64: invalid combination of operands for FMAXNMP")
        }
        return p.setins(asisdpair(0, size, 12, sa_vn, sa_d))
    }
    // FMAXNMP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec2S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_v_1 uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v_1 = 0b0
            case DRegister: sa_v_1 = 0b1
            default: panic("aarch64: invalid scalar operand size for FMAXNMP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2S: sa_t_1 = 0b0
            case Vec2D: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_v_1
        if sa_v_1 != sa_t_1 {
            panic("aarch64: invalid combination of operands for FMAXNMP")
        }
        return p.setins(asisdpair(1, size, 12, sa_vn, sa_d))
    }
    // FMAXNMP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 24, sa_vn, sa_vd))
    }
    // FMAXNMP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 0, sa_vm, 0, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMAXNMP")
}

// FMAXNMV instruction have 2 forms across one single category:
//
// 1. Floating-point Maximum Number across Vector
//
//    FMAXNMV  <V><d>, <Vn>.<T>
//    FMAXNMV  <V><d>, <Vn>.<T>
//
// Floating-point Maximum Number across Vector. This instruction compares all the
// vector elements in the source SIMD&FP register, and writes the largest of the
// values as a scalar to the destination SIMD&FP register. All the values in this
// instruction are floating-point values.
//
// Regardless of the value of FPCR .AH, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * If one value is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either value is a signaling NaN or if both
//       values are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either value is a signaling NaN or if both
//       values are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMAXNMV(v0, v1 interface{}) *Instruction {
    p := self.alloc("FMAXNMV", 2, asm.Operands { v0, v1 })
    // FMAXNMV  <V><d>, <Vn>.<T>
    if isHr(v0) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_d := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        return p.setins(asimdall(sa_t, 0, 0, 12, sa_vn, sa_d))
    }
    // FMAXNMV  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec4S {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_v_1 uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v_1 = 0b0
            default: panic("aarch64: invalid scalar operand size for FMAXNMV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4S: sa_t_1 = 0b10
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_v_1
        if sa_v_1 != mask(sa_t_1, 1) {
            panic("aarch64: invalid combination of operands for FMAXNMV")
        }
        return p.setins(asimdall(ubfx(sa_t_1, 1, 1), 1, size, 12, sa_vn, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMAXNMV")
}

// FMAXP instruction have 4 forms across 2 categories:
//
// 1. Floating-point Maximum of Pair of elements (scalar)
//
//    FMAXP  <V><d>, <Vn>.<T>
//    FMAXP  <V><d>, <Vn>.<T>
//
// Floating-point Maximum of Pair of elements (scalar). This instruction compares
// two vector elements in the source SIMD&FP register and writes the largest of the
// floating-point values as a scalar to the destination SIMD&FP register.
//
// When FPCR .AH is 0, the behavior is as follows for each pairwise operation:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either element is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either element is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows for each pairwise operation:
//
//     * If both elements are zeros, regardless of the sign of either zero, the
//       result is the second element.
//     * If either element is a NaN, regardless of the value of FPCR .DN, the
//       result is the second element.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Maximum Pairwise (vector)
//
//    FMAXP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMAXP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Maximum Pairwise (vector). This instruction creates a vector by
// concatenating the vector elements of the first source SIMD&FP register after the
// vector elements of the second source SIMD&FP register, reads each pair of
// adjacent vector elements from the concatenated vector, writes the larger of each
// pair of values into a vector, and writes the vector to the destination SIMD&FP
// register. All the values in this instruction are floating-point values.
//
// When FPCR .AH is 0, the behavior is as follows for each pairwise operation:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either element is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either element is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows for each pairwise operation:
//
//     * If both elements are zeros, regardless of the sign of either zero, the
//       result is the second element.
//     * If either element is a NaN, regardless of the value of FPCR .DN, the
//       result is the second element.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMAXP(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("FMAXP", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("FMAXP", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction FMAXP takes 2 or 3 operands")
    }
    // FMAXP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec2H {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b0
            default: panic("aarch64: invalid scalar operand size for FMAXP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_t = 0b0
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_v
        if sa_v != sa_t {
            panic("aarch64: invalid combination of operands for FMAXP")
        }
        return p.setins(asisdpair(0, size, 15, sa_vn, sa_d))
    }
    // FMAXP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec2S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_v_1 uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v_1 = 0b0
            case DRegister: sa_v_1 = 0b1
            default: panic("aarch64: invalid scalar operand size for FMAXP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2S: sa_t_1 = 0b0
            case Vec2D: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_v_1
        if sa_v_1 != sa_t_1 {
            panic("aarch64: invalid combination of operands for FMAXP")
        }
        return p.setins(asisdpair(1, size, 15, sa_vn, sa_d))
    }
    // FMAXP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 30, sa_vn, sa_vd))
    }
    // FMAXP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 0, sa_vm, 6, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMAXP")
}

// FMAXV instruction have 2 forms across one single category:
//
// 1. Floating-point Maximum across Vector
//
//    FMAXV  <V><d>, <Vn>.<T>
//    FMAXV  <V><d>, <Vn>.<T>
//
// Floating-point Maximum across Vector. This instruction compares all the vector
// elements in the source SIMD&FP register, and writes the largest of the values as
// a scalar to the destination SIMD&FP register. All the values in this instruction
// are floating-point values.
//
// When FPCR .AH is 0, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either value is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either value is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows:
//
//     * If both values are zeros, regardless of the sign of either zero, the
//       result is the second value.
//     * If either value is a NaN, regardless of the value of FPCR .DN, the
//       result is the second value.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMAXV(v0, v1 interface{}) *Instruction {
    p := self.alloc("FMAXV", 2, asm.Operands { v0, v1 })
    // FMAXV  <V><d>, <Vn>.<T>
    if isHr(v0) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_d := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        return p.setins(asimdall(sa_t, 0, 0, 15, sa_vn, sa_d))
    }
    // FMAXV  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec4S {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_v_1 uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v_1 = 0b0
            default: panic("aarch64: invalid scalar operand size for FMAXV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4S: sa_t_1 = 0b10
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b00)
        size |= sa_v_1
        if sa_v_1 != mask(sa_t_1, 1) {
            panic("aarch64: invalid combination of operands for FMAXV")
        }
        return p.setins(asimdall(ubfx(sa_t_1, 1, 1), 1, size, 15, sa_vn, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMAXV")
}

// FMIN instruction have 5 forms across 2 categories:
//
// 1. Floating-point minimum (vector)
//
//    FMIN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMIN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point minimum (vector). This instruction compares corresponding
// elements in the vectors in the two source SIMD&FP registers, places the smaller
// of each of the two floating-point values into a vector, and writes the vector to
// the destination SIMD&FP register.
//
// When FPCR .AH is 0, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either element is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either element is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows:
//
//     * If both elements are zeros, regardless of the sign of either zero, the
//       result is the second element.
//     * If either element is a NaN, regardless of the value of FPCR .DN, the
//       result is the second element.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Minimum (scalar)
//
//    FMIN  <Dd>, <Dn>, <Dm>
//    FMIN  <Hd>, <Hn>, <Hm>
//    FMIN  <Sd>, <Sn>, <Sm>
//
// Floating-point Minimum (scalar). This instruction compares the first and second
// source SIMD&FP register values, and writes the smaller of the two floating-point
// values to the destination SIMD&FP register.
//
// When FPCR .AH is 0, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either value is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either value is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows:
//
//     * If both values are zeros, regardless of the sign of either zero, the
//       result is the second value.
//     * If either value is a NaN, regardless of the value of FPCR .DN, the
//       result is the second value.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMIN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMIN", 3, asm.Operands { v0, v1, v2 })
    // FMIN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 30, sa_vn, sa_vd))
    }
    // FMIN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 1, sa_vm, 6, sa_vn, sa_vd))
    }
    // FMIN  <Dd>, <Dn>, <Dm>
    if isDr(v0) && isDr(v1) && isDr(v2) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 1, sa_dm, 5, sa_dn, sa_dd))
    }
    // FMIN  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 3, sa_hm, 5, sa_hn, sa_hd))
    }
    // FMIN  <Sd>, <Sn>, <Sm>
    if isSr(v0) && isSr(v1) && isSr(v2) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 0, sa_sm, 5, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMIN")
}

// FMINNM instruction have 5 forms across 2 categories:
//
// 1. Floating-point Minimum Number (vector)
//
//    FMINNM  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMINNM  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Minimum Number (vector). This instruction compares corresponding
// vector elements in the two source SIMD&FP registers, writes the smaller of the
// two floating-point values into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Regardless of the value of FPCR .AH, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * If one element is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either element is a signaling NaN or if both
//       elements are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either element is a signaling NaN or if both
//       elements are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Minimum Number (scalar)
//
//    FMINNM  <Dd>, <Dn>, <Dm>
//    FMINNM  <Hd>, <Hn>, <Hm>
//    FMINNM  <Sd>, <Sn>, <Sm>
//
// Floating-point Minimum Number (scalar). This instruction compares the first and
// second source SIMD&FP register values, and writes the smaller of the two
// floating-point values to the destination SIMD&FP register.
//
// Regardless of the value of FPCR .AH, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * If one value is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either value is a signaling NaN or if both
//       values are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either value is a signaling NaN or if both
//       values are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMINNM(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMINNM", 3, asm.Operands { v0, v1, v2 })
    // FMINNM  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 24, sa_vn, sa_vd))
    }
    // FMINNM  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 1, sa_vm, 0, sa_vn, sa_vd))
    }
    // FMINNM  <Dd>, <Dn>, <Dm>
    if isDr(v0) && isDr(v1) && isDr(v2) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 1, sa_dm, 7, sa_dn, sa_dd))
    }
    // FMINNM  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 3, sa_hm, 7, sa_hn, sa_hd))
    }
    // FMINNM  <Sd>, <Sn>, <Sm>
    if isSr(v0) && isSr(v1) && isSr(v2) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 0, sa_sm, 7, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMINNM")
}

// FMINNMP instruction have 4 forms across 2 categories:
//
// 1. Floating-point Minimum Number of Pair of elements (scalar)
//
//    FMINNMP  <V><d>, <Vn>.<T>
//    FMINNMP  <V><d>, <Vn>.<T>
//
// Floating-point Minimum Number of Pair of elements (scalar). This instruction
// compares two vector elements in the source SIMD&FP register and writes the
// smallest of the floating-point values as a scalar to the destination SIMD&FP
// register.
//
// Regardless of the value of FPCR .AH, the behavior is as follows for each
// pairwise operation:
//
//     * Negative zero compares less than positive zero.
//     * If one element is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either element is a signaling NaN or if both
//       elements are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either element is a signaling NaN or if both
//       elements are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Minimum Number Pairwise (vector)
//
//    FMINNMP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMINNMP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Minimum Number Pairwise (vector). This instruction creates a
// vector by concatenating the vector elements of the first source SIMD&FP register
// after the vector elements of the second source SIMD&FP register, reads each pair
// of adjacent vector elements in the two source SIMD&FP registers, writes the
// smallest of each pair of floating-point values into a vector, and writes the
// vector to the destination SIMD&FP register. All the values in this instruction
// are floating-point values.
//
// Regardless of the value of FPCR .AH, the behavior is as follows for each
// pairwise operation:
//
//     * Negative zero compares less than positive zero.
//     * If one element is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either element is a signaling NaN or if both
//       elements are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either element is a signaling NaN or if both
//       elements are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMINNMP(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("FMINNMP", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("FMINNMP", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction FMINNMP takes 2 or 3 operands")
    }
    // FMINNMP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec2H {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b0
            default: panic("aarch64: invalid scalar operand size for FMINNMP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_t = 0b0
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b10)
        size |= sa_v
        if sa_v != sa_t {
            panic("aarch64: invalid combination of operands for FMINNMP")
        }
        return p.setins(asisdpair(0, size, 12, sa_vn, sa_d))
    }
    // FMINNMP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec2S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_v_1 uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v_1 = 0b0
            case DRegister: sa_v_1 = 0b1
            default: panic("aarch64: invalid scalar operand size for FMINNMP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2S: sa_t_1 = 0b0
            case Vec2D: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b10)
        size |= sa_v_1
        if sa_v_1 != sa_t_1 {
            panic("aarch64: invalid combination of operands for FMINNMP")
        }
        return p.setins(asisdpair(1, size, 12, sa_vn, sa_d))
    }
    // FMINNMP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 24, sa_vn, sa_vd))
    }
    // FMINNMP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 1, sa_vm, 0, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMINNMP")
}

// FMINNMV instruction have 2 forms across one single category:
//
// 1. Floating-point Minimum Number across Vector
//
//    FMINNMV  <V><d>, <Vn>.<T>
//    FMINNMV  <V><d>, <Vn>.<T>
//
// Floating-point Minimum Number across Vector. This instruction compares all the
// vector elements in the source SIMD&FP register, and writes the smallest of the
// values as a scalar to the destination SIMD&FP register. All the values in this
// instruction are floating-point values.
//
// Regardless of the value of FPCR .AH, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * If one value is numeric and the other is a quiet NaN, the result is
//       the numeric value.
//     * When FPCR .DN is 0, if either value is a signaling NaN or if both
//       values are NaNs, the result is a quiet NaN.
//     * When FPCR .DN is 1, if either value is a signaling NaN or if both
//       values are NaNs, the result is Default NaN.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMINNMV(v0, v1 interface{}) *Instruction {
    p := self.alloc("FMINNMV", 2, asm.Operands { v0, v1 })
    // FMINNMV  <V><d>, <Vn>.<T>
    if isHr(v0) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_d := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        return p.setins(asimdall(sa_t, 0, 2, 12, sa_vn, sa_d))
    }
    // FMINNMV  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec4S {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_v_1 uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v_1 = 0b0
            default: panic("aarch64: invalid scalar operand size for FMINNMV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4S: sa_t_1 = 0b10
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b10)
        size |= sa_v_1
        if sa_v_1 != mask(sa_t_1, 1) {
            panic("aarch64: invalid combination of operands for FMINNMV")
        }
        return p.setins(asimdall(ubfx(sa_t_1, 1, 1), 1, size, 12, sa_vn, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMINNMV")
}

// FMINP instruction have 4 forms across 2 categories:
//
// 1. Floating-point Minimum of Pair of elements (scalar)
//
//    FMINP  <V><d>, <Vn>.<T>
//    FMINP  <V><d>, <Vn>.<T>
//
// Floating-point Minimum of Pair of elements (scalar). This instruction compares
// two vector elements in the source SIMD&FP register and writes the smallest of
// the floating-point values as a scalar to the destination SIMD&FP register.
//
// When FPCR .AH is 0, the behavior is as follows for each pairwise operation:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either element is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either element is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows for each pairwise operation:
//
//     * If both elements are zeros, regardless of the sign of either zero, the
//       result is the second element.
//     * If either element is a NaN, regardless of the value of FPCR .DN, the
//       result is the second element.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Minimum Pairwise (vector)
//
//    FMINP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMINP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Minimum Pairwise (vector). This instruction creates a vector by
// concatenating the vector elements of the first source SIMD&FP register after the
// vector elements of the second source SIMD&FP register, reads each pair of
// adjacent vector elements from the concatenated vector, writes the smaller of
// each pair of values into a vector, and writes the vector to the destination
// SIMD&FP register. All the values in this instruction are floating-point values.
//
// When FPCR .AH is 0, the behavior is as follows for each pairwise operation:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either element is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either element is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows for each pairwise operation:
//
//     * If both elements are zeros, regardless of the sign of either zero, the
//       result is the second element.
//     * If either element is a NaN, regardless of the value of FPCR .DN, the
//       result is the second element.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMINP(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("FMINP", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("FMINP", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction FMINP takes 2 or 3 operands")
    }
    // FMINP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec2H {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b0
            default: panic("aarch64: invalid scalar operand size for FMINP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_t = 0b0
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b10)
        size |= sa_v
        if sa_v != sa_t {
            panic("aarch64: invalid combination of operands for FMINP")
        }
        return p.setins(asisdpair(0, size, 15, sa_vn, sa_d))
    }
    // FMINP  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec2S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_v_1 uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v_1 = 0b0
            case DRegister: sa_v_1 = 0b1
            default: panic("aarch64: invalid scalar operand size for FMINP")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2S: sa_t_1 = 0b0
            case Vec2D: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b10)
        size |= sa_v_1
        if sa_v_1 != sa_t_1 {
            panic("aarch64: invalid combination of operands for FMINP")
        }
        return p.setins(asisdpair(1, size, 15, sa_vn, sa_d))
    }
    // FMINP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 30, sa_vn, sa_vd))
    }
    // FMINP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 1, sa_vm, 6, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMINP")
}

// FMINV instruction have 2 forms across one single category:
//
// 1. Floating-point Minimum across Vector
//
//    FMINV  <V><d>, <Vn>.<T>
//    FMINV  <V><d>, <Vn>.<T>
//
// Floating-point Minimum across Vector. This instruction compares all the vector
// elements in the source SIMD&FP register, and writes the smallest of the values
// as a scalar to the destination SIMD&FP register. All the values in this
// instruction are floating-point values.
//
// When FPCR .AH is 0, the behavior is as follows:
//
//     * Negative zero compares less than positive zero.
//     * When FPCR .DN is 0, if either value is a NaN, the result is a quiet
//       NaN.
//     * When FPCR .DN is 1, if either value is a NaN, the result is Default
//       NaN.
//
// When FPCR .AH is 1, the behavior is as follows:
//
//     * If both values are zeros, regardless of the sign of either zero, the
//       result is the second value.
//     * If either value is a NaN, regardless of the value of FPCR .DN, the
//       result is the second value.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMINV(v0, v1 interface{}) *Instruction {
    p := self.alloc("FMINV", 2, asm.Operands { v0, v1 })
    // FMINV  <V><d>, <Vn>.<T>
    if isHr(v0) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_d := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        return p.setins(asimdall(sa_t, 0, 2, 15, sa_vn, sa_d))
    }
    // FMINV  <V><d>, <Vn>.<T>
    if isAdvSIMD(v0) && isVr(v1) && vfmt(v1) == Vec4S {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_v_1 uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v_1 = 0b0
            default: panic("aarch64: invalid scalar operand size for FMINV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4S: sa_t_1 = 0b10
            default: panic("aarch64: unreachable")
        }
        size := uint32(0b10)
        size |= sa_v_1
        if sa_v_1 != mask(sa_t_1, 1) {
            panic("aarch64: invalid combination of operands for FMINV")
        }
        return p.setins(asimdall(ubfx(sa_t_1, 1, 1), 1, size, 15, sa_vn, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMINV")
}

// FMLA instruction have 6 forms across 2 categories:
//
// 1. Floating-point fused Multiply-Add to accumulator (by element)
//
//    FMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]
//    FMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//    FMLA  <Hd>, <Hn>, <Vm>.H[<index>]
//    FMLA  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
//
// Floating-point fused Multiply-Add to accumulator (by element). This instruction
// multiplies the vector elements in the first source SIMD&FP register by the
// specified value in the second source SIMD&FP register, and accumulates the
// results in the vector elements of the destination SIMD&FP register. All the
// values in this instruction are floating-point values.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point fused Multiply-Add to accumulator (vector)
//
//    FMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point fused Multiply-Add to accumulator (vector). This instruction
// multiplies corresponding floating-point values in the vectors in the two source
// SIMD&FP registers, adds the product to the corresponding vector element of the
// destination SIMD&FP register, and writes the result to the destination SIMD&FP
// register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMLA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMLA", 3, asm.Operands { v0, v1, v2 })
    // FMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVri(v2) &&
       vmoder(v2) == ModeH &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asimdelem(
            sa_t,
            0,
            0,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            1,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b00
            case Vec4S: sa_t_1 = 0b10
            case Vec2D: sa_t_1 = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm_1 := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeS: sa_ts = 0b0
            case ModeD: sa_ts = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v2))
        size := uint32(0b10)
        size |= mask(sa_t_1, 1)
        if mask(sa_t_1, 1) != sa_ts || sa_ts != ubfx(sa_index_1, 2, 1) {
            panic("aarch64: invalid combination of operands for FMLA")
        }
        return p.setins(asimdelem(
            ubfx(sa_t_1, 1, 1),
            0,
            size,
            ubfx(sa_index_1, 1, 1),
            ubfx(sa_vm_1, 4, 1),
            mask(sa_vm_1, 4),
            1,
            mask(sa_index_1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMLA  <Hd>, <Hn>, <Vm>.H[<index>]
    if isHr(v0) && isHr(v1) && isVri(v2) && vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asisdelem(
            0,
            0,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            1,
            ubfx(sa_index, 2, 1),
            sa_hn,
            sa_hd,
        ))
    }
    // FMLA  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FMLA")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_vm_1 := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeS: sa_ts = 0b0
            case ModeD: sa_ts = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v2))
        size := uint32(0b10)
        size |= sa_v
        if sa_v != sa_ts || sa_ts != ubfx(sa_index_1, 2, 1) {
            panic("aarch64: invalid combination of operands for FMLA")
        }
        return p.setins(asisdelem(
            0,
            size,
            ubfx(sa_index_1, 1, 1),
            ubfx(sa_vm_1, 4, 1),
            mask(sa_vm_1, 4),
            1,
            mask(sa_index_1, 1),
            sa_n,
            sa_d,
        ))
    }
    // FMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 25, sa_vn, sa_vd))
    }
    // FMLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 0, sa_vm, 1, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMLA")
}

// FMLAL instruction have 2 forms across 2 categories:
//
// 1. Floating-point fused Multiply-Add Long to accumulator (by element)
//
//    FMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.H[<index>]
//
// Floating-point fused Multiply-Add Long to accumulator (by element). This
// instruction multiplies the vector elements in the first source SIMD&FP register
// by the specified value in the second source SIMD&FP register, and accumulates
// the product to the corresponding vector element of the destination SIMD&FP
// register. The instruction does not round the result of the multiply before the
// accumulation.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .FHM indicates whether this instruction is supported.
//
// 2. Floating-point fused Multiply-Add Long to accumulator (vector)
//
//    FMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Floating-point fused Multiply-Add Long to accumulator (vector). This instruction
// multiplies corresponding half-precision floating-point values in the vectors in
// the two source SIMD&FP registers, and accumulates the product to the
// corresponding vector element of the destination SIMD&FP register. The
// instruction does not round the result of the multiply before the accumulation.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .FHM indicates whether this instruction is supported.
//
func (self *Program) FMLAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMLAL", 3, asm.Operands { v0, v1, v2 })
    // FMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.H[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec2H, Vec4H) &&
       isVri(v2) &&
       vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_FHM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_tb = 0b0
            case Vec4H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for FMLAL")
        }
        return p.setins(asimdelem(
            sa_ta,
            0,
            2,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            0,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec2H, Vec4H) &&
       isVr(v2) &&
       isVfmt(v2, Vec2H, Vec4H) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FHM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_tb = 0b0
            case Vec4H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for FMLAL")
        }
        return p.setins(asimdsame(sa_ta, 0, 0, sa_vm, 29, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMLAL")
}

// FMLAL2 instruction have 2 forms across 2 categories:
//
// 1. Floating-point fused Multiply-Add Long to accumulator (by element)
//
//    FMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.H[<index>]
//
// Floating-point fused Multiply-Add Long to accumulator (by element). This
// instruction multiplies the vector elements in the first source SIMD&FP register
// by the specified value in the second source SIMD&FP register, and accumulates
// the product to the corresponding vector element of the destination SIMD&FP
// register. The instruction does not round the result of the multiply before the
// accumulation.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .FHM indicates whether this instruction is supported.
//
// 2. Floating-point fused Multiply-Add Long to accumulator (vector)
//
//    FMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Floating-point fused Multiply-Add Long to accumulator (vector). This instruction
// multiplies corresponding half-precision floating-point values in the vectors in
// the two source SIMD&FP registers, and accumulates the product to the
// corresponding vector element of the destination SIMD&FP register. The
// instruction does not round the result of the multiply before the accumulation.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .FHM indicates whether this instruction is supported.
//
func (self *Program) FMLAL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMLAL2", 3, asm.Operands { v0, v1, v2 })
    // FMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.H[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec2H, Vec4H) &&
       isVri(v2) &&
       vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_FHM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_tb = 0b0
            case Vec4H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for FMLAL2")
        }
        return p.setins(asimdelem(
            sa_ta,
            1,
            2,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            8,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec2H, Vec4H) &&
       isVr(v2) &&
       isVfmt(v2, Vec2H, Vec4H) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FHM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_tb = 0b0
            case Vec4H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for FMLAL2")
        }
        return p.setins(asimdsame(sa_ta, 1, 0, sa_vm, 25, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMLAL2")
}

// FMLS instruction have 6 forms across 2 categories:
//
// 1. Floating-point fused Multiply-Subtract from accumulator (by element)
//
//    FMLS  <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]
//    FMLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//    FMLS  <Hd>, <Hn>, <Vm>.H[<index>]
//    FMLS  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
//
// Floating-point fused Multiply-Subtract from accumulator (by element). This
// instruction multiplies the vector elements in the first source SIMD&FP register
// by the specified value in the second source SIMD&FP register, and subtracts the
// results from the vector elements of the destination SIMD&FP register. All the
// values in this instruction are floating-point values.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point fused Multiply-Subtract from accumulator (vector)
//
//    FMLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point fused Multiply-Subtract from accumulator (vector). This
// instruction multiplies corresponding floating-point values in the vectors in the
// two source SIMD&FP registers, negates the product, adds the result to the
// corresponding vector element of the destination SIMD&FP register, and writes the
// result to the destination SIMD&FP register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMLS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMLS", 3, asm.Operands { v0, v1, v2 })
    // FMLS  <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVri(v2) &&
       vmoder(v2) == ModeH &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asimdelem(
            sa_t,
            0,
            0,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            5,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b00
            case Vec4S: sa_t_1 = 0b10
            case Vec2D: sa_t_1 = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm_1 := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeS: sa_ts = 0b0
            case ModeD: sa_ts = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v2))
        size := uint32(0b10)
        size |= mask(sa_t_1, 1)
        if mask(sa_t_1, 1) != sa_ts || sa_ts != ubfx(sa_index_1, 2, 1) {
            panic("aarch64: invalid combination of operands for FMLS")
        }
        return p.setins(asimdelem(
            ubfx(sa_t_1, 1, 1),
            0,
            size,
            ubfx(sa_index_1, 1, 1),
            ubfx(sa_vm_1, 4, 1),
            mask(sa_vm_1, 4),
            5,
            mask(sa_index_1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMLS  <Hd>, <Hn>, <Vm>.H[<index>]
    if isHr(v0) && isHr(v1) && isVri(v2) && vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asisdelem(
            0,
            0,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            5,
            ubfx(sa_index, 2, 1),
            sa_hn,
            sa_hd,
        ))
    }
    // FMLS  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FMLS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_vm_1 := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeS: sa_ts = 0b0
            case ModeD: sa_ts = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v2))
        size := uint32(0b10)
        size |= sa_v
        if sa_v != sa_ts || sa_ts != ubfx(sa_index_1, 2, 1) {
            panic("aarch64: invalid combination of operands for FMLS")
        }
        return p.setins(asisdelem(
            0,
            size,
            ubfx(sa_index_1, 1, 1),
            ubfx(sa_vm_1, 4, 1),
            mask(sa_vm_1, 4),
            5,
            mask(sa_index_1, 1),
            sa_n,
            sa_d,
        ))
    }
    // FMLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 25, sa_vn, sa_vd))
    }
    // FMLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 1, sa_vm, 1, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMLS")
}

// FMLSL instruction have 2 forms across 2 categories:
//
// 1. Floating-point fused Multiply-Subtract Long from accumulator (by element)
//
//    FMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.H[<index>]
//
// Floating-point fused Multiply-Subtract Long from accumulator (by element). This
// instruction multiplies the negated vector elements in the first source SIMD&FP
// register by the specified value in the second source SIMD&FP register, and
// accumulates the product to the corresponding vector element of the destination
// SIMD&FP register. The instruction does not round the result of the multiply
// before the accumulation.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .FHM indicates whether this instruction is supported.
//
// 2. Floating-point fused Multiply-Subtract Long from accumulator (vector)
//
//    FMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Floating-point fused Multiply-Subtract Long from accumulator (vector). This
// instruction negates the values in the vector of one SIMD&FP register, multiplies
// these with the corresponding values in another vector, and accumulates the
// product to the corresponding vector element of the destination SIMD&FP register.
// The instruction does not round the result of the multiply before the
// accumulation.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .FHM indicates whether this instruction is supported.
//
func (self *Program) FMLSL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMLSL", 3, asm.Operands { v0, v1, v2 })
    // FMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.H[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec2H, Vec4H) &&
       isVri(v2) &&
       vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_FHM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_tb = 0b0
            case Vec4H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for FMLSL")
        }
        return p.setins(asimdelem(
            sa_ta,
            0,
            2,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            4,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec2H, Vec4H) &&
       isVr(v2) &&
       isVfmt(v2, Vec2H, Vec4H) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FHM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_tb = 0b0
            case Vec4H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for FMLSL")
        }
        return p.setins(asimdsame(sa_ta, 0, 2, sa_vm, 29, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMLSL")
}

// FMLSL2 instruction have 2 forms across 2 categories:
//
// 1. Floating-point fused Multiply-Subtract Long from accumulator (by element)
//
//    FMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.H[<index>]
//
// Floating-point fused Multiply-Subtract Long from accumulator (by element). This
// instruction multiplies the negated vector elements in the first source SIMD&FP
// register by the specified value in the second source SIMD&FP register, and
// accumulates the product to the corresponding vector element of the destination
// SIMD&FP register. The instruction does not round the result of the multiply
// before the accumulation.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .FHM indicates whether this instruction is supported.
//
// 2. Floating-point fused Multiply-Subtract Long from accumulator (vector)
//
//    FMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Floating-point fused Multiply-Subtract Long from accumulator (vector). This
// instruction negates the values in the vector of one SIMD&FP register, multiplies
// these with the corresponding values in another vector, and accumulates the
// product to the corresponding vector element of the destination SIMD&FP register.
// The instruction does not round the result of the multiply before the
// accumulation.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .FHM indicates whether this instruction is supported.
//
func (self *Program) FMLSL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMLSL2", 3, asm.Operands { v0, v1, v2 })
    // FMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.H[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec2H, Vec4H) &&
       isVri(v2) &&
       vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_FHM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_tb = 0b0
            case Vec4H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for FMLSL2")
        }
        return p.setins(asimdelem(
            sa_ta,
            1,
            2,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            12,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec2H, Vec4H) &&
       isVr(v2) &&
       isVfmt(v2, Vec2H, Vec4H) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FHM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec2H: sa_tb = 0b0
            case Vec4H: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for FMLSL2")
        }
        return p.setins(asimdsame(sa_ta, 1, 2, sa_vm, 25, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMLSL2")
}

// FMOV instruction have 19 forms across 4 categories:
//
// 1. Floating-point move immediate (vector)
//
//    FMOV  <Vd>.2D, #<imm>
//    FMOV  <Vd>.<T>, #<imm>
//    FMOV  <Vd>.<T>, #<imm>
//
// Floating-point move immediate (vector). This instruction copies an immediate
// floating-point constant into every element of the SIMD&FP destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Move register without conversion
//
//    FMOV  <Dd>, <Dn>
//    FMOV  <Hd>, <Hn>
//    FMOV  <Sd>, <Sn>
//
// Floating-point Move register without conversion. This instruction copies the
// floating-point value in the SIMD&FP source register to the SIMD&FP destination
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 3. Floating-point Move to or from general-purpose register without conversion
//
//    FMOV  <Wd>, <Hn>
//    FMOV  <Wd>, <Sn>
//    FMOV  <Xd>, <Dn>
//    FMOV  <Xd>, <Hn>
//    FMOV  <Xd>, <Vn>.D[1]
//    FMOV  <Dd>, <Xn>
//    FMOV  <Hd>, <Wn>
//    FMOV  <Hd>, <Xn>
//    FMOV  <Sd>, <Wn>
//    FMOV  <Vd>.D[1], <Xn>
//
// Floating-point Move to or from general-purpose register without conversion. This
// instruction transfers the contents of a SIMD&FP register to a general-purpose
// register, or the contents of a general-purpose register to a SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 4. Floating-point move immediate (scalar)
//
//    FMOV  <Dd>, #<imm>
//    FMOV  <Hd>, #<imm>
//    FMOV  <Sd>, #<imm>
//
// Floating-point move immediate (scalar). This instruction copies a floating-point
// immediate constant into the SIMD&FP destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMOV(v0, v1 interface{}) *Instruction {
    p := self.alloc("FMOV", 2, asm.Operands { v0, v1 })
    // FMOV  <Vd>.2D, #<imm>
    if isVr(v0) && vfmt(v0) == Vec2D && isFpImm8(v1) {
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_imm := asFpImm8(v1)
        return p.setins(asimdimm(
            1,
            1,
            ubfx(sa_imm, 7, 1),
            ubfx(sa_imm, 6, 1),
            ubfx(sa_imm, 5, 1),
            15,
            0,
            ubfx(sa_imm, 4, 1),
            ubfx(sa_imm, 3, 1),
            ubfx(sa_imm, 2, 1),
            ubfx(sa_imm, 1, 1),
            mask(sa_imm, 1),
            sa_vd,
        ))
    }
    // FMOV  <Vd>.<T>, #<imm>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isFpImm8(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm := asFpImm8(v1)
        return p.setins(asimdimm(
            sa_t_1,
            0,
            ubfx(sa_imm, 7, 1),
            ubfx(sa_imm, 6, 1),
            ubfx(sa_imm, 5, 1),
            15,
            1,
            ubfx(sa_imm, 4, 1),
            ubfx(sa_imm, 3, 1),
            ubfx(sa_imm, 2, 1),
            ubfx(sa_imm, 1, 1),
            mask(sa_imm, 1),
            sa_vd,
        ))
    }
    // FMOV  <Vd>.<T>, #<imm>
    if isVr(v0) && isVfmt(v0, Vec2S, Vec4S) && isFpImm8(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b0
            case Vec4S: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm := asFpImm8(v1)
        return p.setins(asimdimm(
            sa_t,
            0,
            ubfx(sa_imm, 7, 1),
            ubfx(sa_imm, 6, 1),
            ubfx(sa_imm, 5, 1),
            15,
            0,
            ubfx(sa_imm, 4, 1),
            ubfx(sa_imm, 3, 1),
            ubfx(sa_imm, 2, 1),
            ubfx(sa_imm, 1, 1),
            mask(sa_imm, 1),
            sa_vd,
        ))
    }
    // FMOV  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 0, sa_dn, sa_dd))
    }
    // FMOV  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 0, sa_hn, sa_hd))
    }
    // FMOV  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 0, sa_sn, sa_sd))
    }
    // FMOV  <Wd>, <Hn>
    if isWr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 0, 6, sa_hn, sa_wd))
    }
    // FMOV  <Wd>, <Sn>
    if isWr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 0, 6, sa_sn, sa_wd))
    }
    // FMOV  <Xd>, <Dn>
    if isXr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 0, 6, sa_dn, sa_xd))
    }
    // FMOV  <Xd>, <Hn>
    if isXr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 0, 6, sa_hn, sa_xd))
    }
    // FMOV  <Xd>, <Vn>.D[1]
    if isXr(v0) && isVri(v1) && vmoder(v1) == ModeD && vidxr(v1) == 1 {
        p.Domain = DomainFloat
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(VidxRegister).ID())
        return p.setins(float2int(1, 0, 2, 1, 6, sa_vn, sa_xd))
    }
    // FMOV  <Dd>, <Xn>
    if isDr(v0) && isXr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 0, 7, sa_xn, sa_dd))
    }
    // FMOV  <Hd>, <Wn>
    if isHr(v0) && isWr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 0, 7, sa_wn, sa_hd))
    }
    // FMOV  <Hd>, <Xn>
    if isHr(v0) && isXr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 0, 7, sa_xn, sa_hd))
    }
    // FMOV  <Sd>, <Wn>
    if isSr(v0) && isWr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 0, 7, sa_wn, sa_sd))
    }
    // FMOV  <Vd>.D[1], <Xn>
    if isVri(v0) && vmoder(v0) == ModeD && vidxr(v0) == 1 && isXr(v1) {
        p.Domain = DomainFloat
        sa_vd := uint32(v0.(VidxRegister).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 2, 1, 7, sa_xn, sa_vd))
    }
    // FMOV  <Dd>, #<imm>
    if isDr(v0) && isFpImm8(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_imm := asFpImm8(v1)
        return p.setins(floatimm(0, 0, 1, sa_imm, 0, sa_dd))
    }
    // FMOV  <Hd>, #<imm>
    if isHr(v0) && isFpImm8(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_imm := asFpImm8(v1)
        return p.setins(floatimm(0, 0, 3, sa_imm, 0, sa_hd))
    }
    // FMOV  <Sd>, #<imm>
    if isSr(v0) && isFpImm8(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_imm := asFpImm8(v1)
        return p.setins(floatimm(0, 0, 0, sa_imm, 0, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMOV")
}

// FMSUB instruction have 3 forms across one single category:
//
// 1. Floating-point Fused Multiply-Subtract (scalar)
//
//    FMSUB  <Dd>, <Dn>, <Dm>, <Da>
//    FMSUB  <Hd>, <Hn>, <Hm>, <Ha>
//    FMSUB  <Sd>, <Sn>, <Sm>, <Sa>
//
// Floating-point Fused Multiply-Subtract (scalar). This instruction multiplies the
// values of the first two SIMD&FP source registers, negates the product, adds that
// to the value of the third SIMD&FP source register, and writes the result to the
// SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMSUB(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("FMSUB", 4, asm.Operands { v0, v1, v2, v3 })
    // FMSUB  <Dd>, <Dn>, <Dm>, <Da>
    if isDr(v0) && isDr(v1) && isDr(v2) && isDr(v3) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        sa_da := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 1, 0, sa_dm, 1, sa_da, sa_dn, sa_dd))
    }
    // FMSUB  <Hd>, <Hn>, <Hm>, <Ha>
    if isHr(v0) && isHr(v1) && isHr(v2) && isHr(v3) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        sa_ha := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 3, 0, sa_hm, 1, sa_ha, sa_hn, sa_hd))
    }
    // FMSUB  <Sd>, <Sn>, <Sm>, <Sa>
    if isSr(v0) && isSr(v1) && isSr(v2) && isSr(v3) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        sa_sa := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 0, 0, sa_sm, 1, sa_sa, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMSUB")
}

// FMUL instruction have 9 forms across 3 categories:
//
// 1. Floating-point Multiply (by element)
//
//    FMUL  <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]
//    FMUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//    FMUL  <Hd>, <Hn>, <Vm>.H[<index>]
//    FMUL  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
//
// Floating-point Multiply (by element). This instruction multiplies the vector
// elements in the first source SIMD&FP register by the specified value in the
// second source SIMD&FP register, places the results in a vector, and writes the
// vector to the destination SIMD&FP register. All the values in this instruction
// are floating-point values.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Multiply (vector)
//
//    FMUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Multiply (vector). This instruction multiplies corresponding
// floating-point values in the vectors in the two source SIMD&FP registers, places
// the result in a vector, and writes the vector to the destination SIMD&FP
// register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 3. Floating-point Multiply (scalar)
//
//    FMUL  <Dd>, <Dn>, <Dm>
//    FMUL  <Hd>, <Hn>, <Hm>
//    FMUL  <Sd>, <Sn>, <Sm>
//
// Floating-point Multiply (scalar). This instruction multiplies the floating-point
// values of the two source SIMD&FP registers, and writes the result to the
// destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMUL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMUL", 3, asm.Operands { v0, v1, v2 })
    // FMUL  <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVri(v2) &&
       vmoder(v2) == ModeH &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asimdelem(
            sa_t,
            0,
            0,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            9,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b00
            case Vec4S: sa_t_1 = 0b10
            case Vec2D: sa_t_1 = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm_1 := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeS: sa_ts = 0b0
            case ModeD: sa_ts = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v2))
        size := uint32(0b10)
        size |= mask(sa_t_1, 1)
        if mask(sa_t_1, 1) != sa_ts || sa_ts != ubfx(sa_index_1, 2, 1) {
            panic("aarch64: invalid combination of operands for FMUL")
        }
        return p.setins(asimdelem(
            ubfx(sa_t_1, 1, 1),
            0,
            size,
            ubfx(sa_index_1, 1, 1),
            ubfx(sa_vm_1, 4, 1),
            mask(sa_vm_1, 4),
            9,
            mask(sa_index_1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMUL  <Hd>, <Hn>, <Vm>.H[<index>]
    if isHr(v0) && isHr(v1) && isVri(v2) && vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asisdelem(
            0,
            0,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            9,
            ubfx(sa_index, 2, 1),
            sa_hn,
            sa_hd,
        ))
    }
    // FMUL  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FMUL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_vm_1 := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeS: sa_ts = 0b0
            case ModeD: sa_ts = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v2))
        size := uint32(0b10)
        size |= sa_v
        if sa_v != sa_ts || sa_ts != ubfx(sa_index_1, 2, 1) {
            panic("aarch64: invalid combination of operands for FMUL")
        }
        return p.setins(asisdelem(
            0,
            size,
            ubfx(sa_index_1, 1, 1),
            ubfx(sa_vm_1, 4, 1),
            mask(sa_vm_1, 4),
            9,
            mask(sa_index_1, 1),
            sa_n,
            sa_d,
        ))
    }
    // FMUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 1, size, sa_vm, 27, sa_vn, sa_vd))
    }
    // FMUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 1, 0, sa_vm, 3, sa_vn, sa_vd))
    }
    // FMUL  <Dd>, <Dn>, <Dm>
    if isDr(v0) && isDr(v1) && isDr(v2) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 1, sa_dm, 0, sa_dn, sa_dd))
    }
    // FMUL  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 3, sa_hm, 0, sa_hn, sa_hd))
    }
    // FMUL  <Sd>, <Sn>, <Sm>
    if isSr(v0) && isSr(v1) && isSr(v2) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 0, sa_sm, 0, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMUL")
}

// FMULX instruction have 8 forms across 2 categories:
//
// 1. Floating-point Multiply extended (by element)
//
//    FMULX  <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]
//    FMULX  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//    FMULX  <Hd>, <Hn>, <Vm>.H[<index>]
//    FMULX  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
//
// Floating-point Multiply extended (by element). This instruction multiplies the
// floating-point values in the vector elements in the first source SIMD&FP
// register by the specified floating-point value in the second source SIMD&FP
// register, places the results in a vector, and writes the vector to the
// destination SIMD&FP register.
//
// If one value is zero and the other value is infinite, the result is 2.0. In this
// case, the result is negative if only one of the values is negative, otherwise
// the result is positive.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Multiply extended
//
//    FMULX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMULX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FMULX  <V><d>, <V><n>, <V><m>
//    FMULX  <Hd>, <Hn>, <Hm>
//
// Floating-point Multiply extended. This instruction multiplies corresponding
// floating-point values in the vectors of the two source SIMD&FP registers, places
// the resulting floating-point values in a vector, and writes the vector to the
// destination SIMD&FP register.
//
// If one value is zero and the other value is infinite, the result is 2.0. In this
// case, the result is negative if only one of the values is negative, otherwise
// the result is positive.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FMULX(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FMULX", 3, asm.Operands { v0, v1, v2 })
    // FMULX  <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVri(v2) &&
       vmoder(v2) == ModeH &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asimdelem(
            sa_t,
            1,
            0,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            9,
            ubfx(sa_index, 2, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMULX  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b00
            case Vec4S: sa_t_1 = 0b10
            case Vec2D: sa_t_1 = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm_1 := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeS: sa_ts = 0b0
            case ModeD: sa_ts = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v2))
        size := uint32(0b10)
        size |= mask(sa_t_1, 1)
        if mask(sa_t_1, 1) != sa_ts || sa_ts != ubfx(sa_index_1, 2, 1) {
            panic("aarch64: invalid combination of operands for FMULX")
        }
        return p.setins(asimdelem(
            ubfx(sa_t_1, 1, 1),
            1,
            size,
            ubfx(sa_index_1, 1, 1),
            ubfx(sa_vm_1, 4, 1),
            mask(sa_vm_1, 4),
            9,
            mask(sa_index_1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // FMULX  <Hd>, <Hn>, <Vm>.H[<index>]
    if isHr(v0) && isHr(v1) && isVri(v2) && vmoder(v2) == ModeH {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        return p.setins(asisdelem(
            1,
            0,
            ubfx(sa_index, 1, 1),
            mask(sa_index, 1),
            sa_vm,
            9,
            ubfx(sa_index, 2, 1),
            sa_hn,
            sa_hd,
        ))
    }
    // FMULX  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FMULX")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_vm_1 := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeS: sa_ts = 0b0
            case ModeD: sa_ts = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v2))
        size := uint32(0b10)
        size |= sa_v
        if sa_v != sa_ts || sa_ts != ubfx(sa_index_1, 2, 1) {
            panic("aarch64: invalid combination of operands for FMULX")
        }
        return p.setins(asisdelem(
            1,
            size,
            ubfx(sa_index_1, 1, 1),
            ubfx(sa_vm_1, 4, 1),
            mask(sa_vm_1, 4),
            9,
            mask(sa_index_1, 1),
            sa_n,
            sa_d,
        ))
    }
    // FMULX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 27, sa_vn, sa_vd))
    }
    // FMULX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 0, sa_vm, 3, sa_vn, sa_vd))
    }
    // FMULX  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FMULX")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdsame(0, size, sa_m, 27, sa_n, sa_d))
    }
    // FMULX  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsamefp16(0, 0, sa_hm, 3, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FMULX")
}

// FNEG instruction have 5 forms across 2 categories:
//
// 1. Floating-point Negate (vector)
//
//    FNEG  <Vd>.<T>, <Vn>.<T>
//    FNEG  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Negate (vector). This instruction negates the value of each
// vector element in the source SIMD&FP register, writes the result to a vector,
// and writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Negate (scalar)
//
//    FNEG  <Dd>, <Dn>
//    FNEG  <Hd>, <Hn>
//    FNEG  <Sd>, <Sn>
//
// Floating-point Negate (scalar). This instruction negates the value in the
// SIMD&FP source register and writes the result to the SIMD&FP destination
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FNEG(v0, v1 interface{}) *Instruction {
    p := self.alloc("FNEG", 2, asm.Operands { v0, v1 })
    // FNEG  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 15, sa_vn, sa_vd))
    }
    // FNEG  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 1, 15, sa_vn, sa_vd))
    }
    // FNEG  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 2, sa_dn, sa_dd))
    }
    // FNEG  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 2, sa_hn, sa_hd))
    }
    // FNEG  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 2, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FNEG")
}

// FNMADD instruction have 3 forms across one single category:
//
// 1. Floating-point Negated fused Multiply-Add (scalar)
//
//    FNMADD  <Dd>, <Dn>, <Dm>, <Da>
//    FNMADD  <Hd>, <Hn>, <Hm>, <Ha>
//    FNMADD  <Sd>, <Sn>, <Sm>, <Sa>
//
// Floating-point Negated fused Multiply-Add (scalar). This instruction multiplies
// the values of the first two SIMD&FP source registers, negates the product,
// subtracts the value of the third SIMD&FP source register, and writes the result
// to the destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FNMADD(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("FNMADD", 4, asm.Operands { v0, v1, v2, v3 })
    // FNMADD  <Dd>, <Dn>, <Dm>, <Da>
    if isDr(v0) && isDr(v1) && isDr(v2) && isDr(v3) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        sa_da := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 1, 1, sa_dm, 0, sa_da, sa_dn, sa_dd))
    }
    // FNMADD  <Hd>, <Hn>, <Hm>, <Ha>
    if isHr(v0) && isHr(v1) && isHr(v2) && isHr(v3) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        sa_ha := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 3, 1, sa_hm, 0, sa_ha, sa_hn, sa_hd))
    }
    // FNMADD  <Sd>, <Sn>, <Sm>, <Sa>
    if isSr(v0) && isSr(v1) && isSr(v2) && isSr(v3) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        sa_sa := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 0, 1, sa_sm, 0, sa_sa, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FNMADD")
}

// FNMSUB instruction have 3 forms across one single category:
//
// 1. Floating-point Negated fused Multiply-Subtract (scalar)
//
//    FNMSUB  <Dd>, <Dn>, <Dm>, <Da>
//    FNMSUB  <Hd>, <Hn>, <Hm>, <Ha>
//    FNMSUB  <Sd>, <Sn>, <Sm>, <Sa>
//
// Floating-point Negated fused Multiply-Subtract (scalar). This instruction
// multiplies the values of the first two SIMD&FP source registers, subtracts the
// value of the third SIMD&FP source register, and writes the result to the
// destination SIMD&FP register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FNMSUB(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("FNMSUB", 4, asm.Operands { v0, v1, v2, v3 })
    // FNMSUB  <Dd>, <Dn>, <Dm>, <Da>
    if isDr(v0) && isDr(v1) && isDr(v2) && isDr(v3) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        sa_da := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 1, 1, sa_dm, 1, sa_da, sa_dn, sa_dd))
    }
    // FNMSUB  <Hd>, <Hn>, <Hm>, <Ha>
    if isHr(v0) && isHr(v1) && isHr(v2) && isHr(v3) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        sa_ha := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 3, 1, sa_hm, 1, sa_ha, sa_hn, sa_hd))
    }
    // FNMSUB  <Sd>, <Sn>, <Sm>, <Sa>
    if isSr(v0) && isSr(v1) && isSr(v2) && isSr(v3) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        sa_sa := uint32(v3.(asm.Register).ID())
        return p.setins(floatdp3(0, 0, 0, 1, sa_sm, 1, sa_sa, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FNMSUB")
}

// FNMUL instruction have 3 forms across one single category:
//
// 1. Floating-point Multiply-Negate (scalar)
//
//    FNMUL  <Dd>, <Dn>, <Dm>
//    FNMUL  <Hd>, <Hn>, <Hm>
//    FNMUL  <Sd>, <Sn>, <Sm>
//
// Floating-point Multiply-Negate (scalar). This instruction multiplies the
// floating-point values of the two source SIMD&FP registers, and writes the
// negation of the result to the destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FNMUL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FNMUL", 3, asm.Operands { v0, v1, v2 })
    // FNMUL  <Dd>, <Dn>, <Dm>
    if isDr(v0) && isDr(v1) && isDr(v2) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 1, sa_dm, 8, sa_dn, sa_dd))
    }
    // FNMUL  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 3, sa_hm, 8, sa_hn, sa_hd))
    }
    // FNMUL  <Sd>, <Sn>, <Sm>
    if isSr(v0) && isSr(v1) && isSr(v2) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 0, sa_sm, 8, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FNMUL")
}

// FRECPE instruction have 4 forms across one single category:
//
// 1. Floating-point Reciprocal Estimate
//
//    FRECPE  <Vd>.<T>, <Vn>.<T>
//    FRECPE  <Vd>.<T>, <Vn>.<T>
//    FRECPE  <V><d>, <V><n>
//    FRECPE  <Hd>, <Hn>
//
// Floating-point Reciprocal Estimate. This instruction finds an approximate
// reciprocal estimate for each vector element in the source SIMD&FP register,
// places the result in a vector, and writes the vector to the destination SIMD&FP
// register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRECPE(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRECPE", 2, asm.Operands { v0, v1 })
    // FRECPE  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 29, sa_vn, sa_vd))
    }
    // FRECPE  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 1, 29, sa_vn, sa_vd))
    }
    // FRECPE  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FRECPE")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 29, sa_n, sa_d))
    }
    // FRECPE  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 1, 29, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRECPE")
}

// FRECPS instruction have 4 forms across one single category:
//
// 1. Floating-point Reciprocal Step
//
//    FRECPS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FRECPS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FRECPS  <V><d>, <V><n>, <V><m>
//    FRECPS  <Hd>, <Hn>, <Hm>
//
// Floating-point Reciprocal Step. This instruction multiplies the corresponding
// floating-point values in the vectors of the two source SIMD&FP registers,
// subtracts each of the products from 2.0, places the resulting floating-point
// values in a vector, and writes the vector to the destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRECPS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FRECPS", 3, asm.Operands { v0, v1, v2 })
    // FRECPS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 31, sa_vn, sa_vd))
    }
    // FRECPS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 0, sa_vm, 7, sa_vn, sa_vd))
    }
    // FRECPS  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FRECPS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdsame(0, size, sa_m, 31, sa_n, sa_d))
    }
    // FRECPS  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsamefp16(0, 0, sa_hm, 7, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRECPS")
}

// FRECPX instruction have 2 forms across one single category:
//
// 1. Floating-point Reciprocal exponent (scalar)
//
//    FRECPX  <V><d>, <V><n>
//    FRECPX  <Hd>, <Hn>
//
// Floating-point Reciprocal exponent (scalar). This instruction finds an
// approximate reciprocal exponent for the source SIMD&FP register and writes the
// result to the destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRECPX(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRECPX", 2, asm.Operands { v0, v1 })
    // FRECPX  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FRECPX")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 31, sa_n, sa_d))
    }
    // FRECPX  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 1, 31, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRECPX")
}

// FRINT32X instruction have 3 forms across 2 categories:
//
// 1. Floating-point Round to 32-bit Integer, using current rounding mode (vector)
//
//    FRINT32X  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to 32-bit Integer, using current rounding mode (vector).
// This instruction rounds a vector of floating-point values in the SIMD&FP source
// register to integral floating-point values that fit into a 32-bit integer size
// using the rounding mode that is determined by the FPCR , and writes the result
// to the SIMD&FP destination register.
//
// A zero input returns a zero result with the same sign. When one of the result
// values is not numerically equal to the corresponding input value, an Inexact
// exception is raised. When an input is infinite, NaN or out-of-range, the
// instruction returns for the corresponding result value the most negative integer
// representable in the destination size, and an Invalid Operation floating-point
// exception is raised.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to 32-bit Integer, using current rounding mode (scalar)
//
//    FRINT32X  <Dd>, <Dn>
//    FRINT32X  <Sd>, <Sn>
//
// Floating-point Round to 32-bit Integer, using current rounding mode (scalar).
// This instruction rounds a floating-point value in the SIMD&FP source register to
// an integral floating-point value that fits into a 32-bit integer size using the
// rounding mode that is determined by the FPCR , and writes the result to the
// SIMD&FP destination register.
//
// A zero input returns a zero result with the same sign. When the result value is
// not numerically equal to the input value, an Inexact exception is raised. When
// the input is infinite, NaN or out-of-range, the instruction returns {for the
// corresponding result value} the most negative integer representable in the
// destination size, and an Invalid Operation floating-point exception is raised.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINT32X(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINT32X", 2, asm.Operands { v0, v1 })
    // FRINT32X  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 30, sa_vn, sa_vd))
    }
    // FRINT32X  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 17, sa_dn, sa_dd))
    }
    // FRINT32X  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 17, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINT32X")
}

// FRINT32Z instruction have 3 forms across 2 categories:
//
// 1. Floating-point Round to 32-bit Integer toward Zero (vector)
//
//    FRINT32Z  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to 32-bit Integer toward Zero (vector). This instruction
// rounds a vector of floating-point values in the SIMD&FP source register to
// integral floating-point values that fit into a 32-bit integer size using the
// Round towards Zero rounding mode, and writes the result to the SIMD&FP
// destination register.
//
// A zero input returns a zero result with the same sign. When one of the result
// values is not numerically equal to the corresponding input value, an Inexact
// exception is raised. When an input is infinite, NaN or out-of-range, the
// instruction returns for the corresponding result value the most negative integer
// representable in the destination size, and an Invalid Operation floating-point
// exception is raised.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to 32-bit Integer toward Zero (scalar)
//
//    FRINT32Z  <Dd>, <Dn>
//    FRINT32Z  <Sd>, <Sn>
//
// Floating-point Round to 32-bit Integer toward Zero (scalar). This instruction
// rounds a floating-point value in the SIMD&FP source register to an integral
// floating-point value that fits into a 32-bit integer size using the Round
// towards Zero rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A zero input returns a zero result with the same sign. When the result value is
// not numerically equal to the {corresponding} input value, an Inexact exception
// is raised. When the input is infinite, NaN or out-of-range, the instruction
// returns {for the corresponding result value} the most negative integer
// representable in the destination size, and an Invalid Operation floating-point
// exception is raised.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINT32Z(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINT32Z", 2, asm.Operands { v0, v1 })
    // FRINT32Z  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 30, sa_vn, sa_vd))
    }
    // FRINT32Z  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 16, sa_dn, sa_dd))
    }
    // FRINT32Z  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 16, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINT32Z")
}

// FRINT64X instruction have 3 forms across 2 categories:
//
// 1. Floating-point Round to 64-bit Integer, using current rounding mode (vector)
//
//    FRINT64X  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to 64-bit Integer, using current rounding mode (vector).
// This instruction rounds a vector of floating-point values in the SIMD&FP source
// register to integral floating-point values that fit into a 64-bit integer size
// using the rounding mode that is determined by the FPCR , and writes the result
// to the SIMD&FP destination register.
//
// A zero input returns a zero result with the same sign. When one of the result
// values is not numerically equal to the corresponding input value, an Inexact
// exception is raised. When an input is infinite, NaN or out-of-range, the
// instruction returns for the corresponding result value the most negative integer
// representable in the destination size, and an Invalid Operation floating-point
// exception is raised.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to 64-bit Integer, using current rounding mode (scalar)
//
//    FRINT64X  <Dd>, <Dn>
//    FRINT64X  <Sd>, <Sn>
//
// Floating-point Round to 64-bit Integer, using current rounding mode (scalar).
// This instruction rounds a floating-point value in the SIMD&FP source register to
// an integral floating-point value that fits into a 64-bit integer size using the
// rounding mode that is determined by the FPCR , and writes the result to the
// SIMD&FP destination register.
//
// A zero input returns a zero result with the same sign. When the result value is
// not numerically equal to the input value, an Inexact exception is raised. When
// the input is infinite, NaN or out-of-range, the instruction returns {for the
// corresponding result value} the most negative integer representable in the
// destination size, and an Invalid Operation floating-point exception is raised.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINT64X(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINT64X", 2, asm.Operands { v0, v1 })
    // FRINT64X  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 31, sa_vn, sa_vd))
    }
    // FRINT64X  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 19, sa_dn, sa_dd))
    }
    // FRINT64X  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 19, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINT64X")
}

// FRINT64Z instruction have 3 forms across 2 categories:
//
// 1. Floating-point Round to 64-bit Integer toward Zero (vector)
//
//    FRINT64Z  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to 64-bit Integer toward Zero (vector). This instruction
// rounds a vector of floating-point values in the SIMD&FP source register to
// integral floating-point values that fit into a 64-bit integer size using the
// Round towards Zero rounding mode, and writes the result to the SIMD&FP
// destination register.
//
// A zero input returns a zero result with the same sign. When one of the result
// values is not numerically equal to the corresponding input value, an Inexact
// exception is raised. When an input is infinite, NaN or out-of-range, the
// instruction returns for the corresponding result value the most negative integer
// representable in the destination size, and an Invalid Operation floating-point
// exception is raised.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to 64-bit Integer toward Zero (scalar)
//
//    FRINT64Z  <Dd>, <Dn>
//    FRINT64Z  <Sd>, <Sn>
//
// Floating-point Round to 64-bit Integer toward Zero (scalar). This instruction
// rounds a floating-point value in the SIMD&FP source register to an integral
// floating-point value that fits into a 64-bit integer size using the Round
// towards Zero rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A zero input returns a zero result with the same sign. When the result value is
// not numerically equal to the {corresponding} input value, an Inexact exception
// is raised. When the input is infinite, NaN or out-of-range, the instruction
// returns {for the corresponding result value} the most negative integer
// representable in the destination size, and an Invalid Operation floating-point
// exception is raised.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINT64Z(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINT64Z", 2, asm.Operands { v0, v1 })
    // FRINT64Z  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 31, sa_vn, sa_vd))
    }
    // FRINT64Z  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 18, sa_dn, sa_dd))
    }
    // FRINT64Z  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        self.Arch.Require(FEAT_FRINTTS)
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 18, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINT64Z")
}

// FRINTA instruction have 5 forms across 2 categories:
//
// 1. Floating-point Round to Integral, to nearest with ties to Away (vector)
//
//    FRINTA  <Vd>.<T>, <Vn>.<T>
//    FRINTA  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to Integral, to nearest with ties to Away (vector). This
// instruction rounds a vector of floating-point values in the SIMD&FP source
// register to integral floating-point values of the same size using the Round to
// Nearest with Ties to Away rounding mode, and writes the result to the SIMD&FP
// destination register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to Integral, to nearest with ties to Away (scalar)
//
//    FRINTA  <Dd>, <Dn>
//    FRINTA  <Hd>, <Hn>
//    FRINTA  <Sd>, <Sn>
//
// Floating-point Round to Integral, to nearest with ties to Away (scalar). This
// instruction rounds a floating-point value in the SIMD&FP source register to an
// integral floating-point value of the same size using the Round to Nearest with
// Ties to Away rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINTA(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINTA", 2, asm.Operands { v0, v1 })
    // FRINTA  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 24, sa_vn, sa_vd))
    }
    // FRINTA  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 0, 24, sa_vn, sa_vd))
    }
    // FRINTA  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 12, sa_dn, sa_dd))
    }
    // FRINTA  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 12, sa_hn, sa_hd))
    }
    // FRINTA  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 12, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINTA")
}

// FRINTI instruction have 5 forms across 2 categories:
//
// 1. Floating-point Round to Integral, using current rounding mode (vector)
//
//    FRINTI  <Vd>.<T>, <Vn>.<T>
//    FRINTI  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to Integral, using current rounding mode (vector). This
// instruction rounds a vector of floating-point values in the SIMD&FP source
// register to integral floating-point values of the same size using the rounding
// mode that is determined by the FPCR , and writes the result to the SIMD&FP
// destination register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to Integral, using current rounding mode (scalar)
//
//    FRINTI  <Dd>, <Dn>
//    FRINTI  <Hd>, <Hn>
//    FRINTI  <Sd>, <Sn>
//
// Floating-point Round to Integral, using current rounding mode (scalar). This
// instruction rounds a floating-point value in the SIMD&FP source register to an
// integral floating-point value of the same size using the rounding mode that is
// determined by the FPCR , and writes the result to the SIMD&FP destination
// register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINTI(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINTI", 2, asm.Operands { v0, v1 })
    // FRINTI  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 25, sa_vn, sa_vd))
    }
    // FRINTI  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 1, 25, sa_vn, sa_vd))
    }
    // FRINTI  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 15, sa_dn, sa_dd))
    }
    // FRINTI  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 15, sa_hn, sa_hd))
    }
    // FRINTI  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 15, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINTI")
}

// FRINTM instruction have 5 forms across 2 categories:
//
// 1. Floating-point Round to Integral, toward Minus infinity (vector)
//
//    FRINTM  <Vd>.<T>, <Vn>.<T>
//    FRINTM  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to Integral, toward Minus infinity (vector). This
// instruction rounds a vector of floating-point values in the SIMD&FP source
// register to integral floating-point values of the same size using the Round
// towards Minus Infinity rounding mode, and writes the result to the SIMD&FP
// destination register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to Integral, toward Minus infinity (scalar)
//
//    FRINTM  <Dd>, <Dn>
//    FRINTM  <Hd>, <Hn>
//    FRINTM  <Sd>, <Sn>
//
// Floating-point Round to Integral, toward Minus infinity (scalar). This
// instruction rounds a floating-point value in the SIMD&FP source register to an
// integral floating-point value of the same size using the Round towards Minus
// Infinity rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINTM(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINTM", 2, asm.Operands { v0, v1 })
    // FRINTM  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 25, sa_vn, sa_vd))
    }
    // FRINTM  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 0, 25, sa_vn, sa_vd))
    }
    // FRINTM  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 10, sa_dn, sa_dd))
    }
    // FRINTM  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 10, sa_hn, sa_hd))
    }
    // FRINTM  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 10, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINTM")
}

// FRINTN instruction have 5 forms across 2 categories:
//
// 1. Floating-point Round to Integral, to nearest with ties to even (vector)
//
//    FRINTN  <Vd>.<T>, <Vn>.<T>
//    FRINTN  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to Integral, to nearest with ties to even (vector). This
// instruction rounds a vector of floating-point values in the SIMD&FP source
// register to integral floating-point values of the same size using the Round to
// Nearest rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to Integral, to nearest with ties to even (scalar)
//
//    FRINTN  <Dd>, <Dn>
//    FRINTN  <Hd>, <Hn>
//    FRINTN  <Sd>, <Sn>
//
// Floating-point Round to Integral, to nearest with ties to even (scalar). This
// instruction rounds a floating-point value in the SIMD&FP source register to an
// integral floating-point value of the same size using the Round to Nearest
// rounding mode, and writes the result to the SIMD&FP destination register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINTN(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINTN", 2, asm.Operands { v0, v1 })
    // FRINTN  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 24, sa_vn, sa_vd))
    }
    // FRINTN  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 0, 24, sa_vn, sa_vd))
    }
    // FRINTN  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 8, sa_dn, sa_dd))
    }
    // FRINTN  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 8, sa_hn, sa_hd))
    }
    // FRINTN  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 8, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINTN")
}

// FRINTP instruction have 5 forms across 2 categories:
//
// 1. Floating-point Round to Integral, toward Plus infinity (vector)
//
//    FRINTP  <Vd>.<T>, <Vn>.<T>
//    FRINTP  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to Integral, toward Plus infinity (vector). This
// instruction rounds a vector of floating-point values in the SIMD&FP source
// register to integral floating-point values of the same size using the Round
// towards Plus Infinity rounding mode, and writes the result to the SIMD&FP
// destination register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to Integral, toward Plus infinity (scalar)
//
//    FRINTP  <Dd>, <Dn>
//    FRINTP  <Hd>, <Hn>
//    FRINTP  <Sd>, <Sn>
//
// Floating-point Round to Integral, toward Plus infinity (scalar). This
// instruction rounds a floating-point value in the SIMD&FP source register to an
// integral floating-point value of the same size using the Round towards Plus
// Infinity rounding mode, and writes the result to the SIMD&FP destination
// register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINTP(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINTP", 2, asm.Operands { v0, v1 })
    // FRINTP  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 24, sa_vn, sa_vd))
    }
    // FRINTP  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 1, 24, sa_vn, sa_vd))
    }
    // FRINTP  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 9, sa_dn, sa_dd))
    }
    // FRINTP  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 9, sa_hn, sa_hd))
    }
    // FRINTP  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 9, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINTP")
}

// FRINTX instruction have 5 forms across 2 categories:
//
// 1. Floating-point Round to Integral exact, using current rounding mode (vector)
//
//    FRINTX  <Vd>.<T>, <Vn>.<T>
//    FRINTX  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to Integral exact, using current rounding mode (vector).
// This instruction rounds a vector of floating-point values in the SIMD&FP source
// register to integral floating-point values of the same size using the rounding
// mode that is determined by the FPCR , and writes the result to the SIMD&FP
// destination register.
//
// When a result value is not numerically equal to the corresponding input value,
// an Inexact exception is raised. A zero input gives a zero result with the same
// sign, an infinite input gives an infinite result with the same sign, and a NaN
// is propagated as for normal arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to Integral exact, using current rounding mode (scalar)
//
//    FRINTX  <Dd>, <Dn>
//    FRINTX  <Hd>, <Hn>
//    FRINTX  <Sd>, <Sn>
//
// Floating-point Round to Integral exact, using current rounding mode (scalar).
// This instruction rounds a floating-point value in the SIMD&FP source register to
// an integral floating-point value of the same size using the rounding mode that
// is determined by the FPCR , and writes the result to the SIMD&FP destination
// register.
//
// When the result value is not numerically equal to the input value, an Inexact
// exception is raised. A zero input gives a zero result with the same sign, an
// infinite input gives an infinite result with the same sign, and a NaN is
// propagated as for normal arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINTX(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINTX", 2, asm.Operands { v0, v1 })
    // FRINTX  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 25, sa_vn, sa_vd))
    }
    // FRINTX  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 0, 25, sa_vn, sa_vd))
    }
    // FRINTX  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 14, sa_dn, sa_dd))
    }
    // FRINTX  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 14, sa_hn, sa_hd))
    }
    // FRINTX  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 14, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINTX")
}

// FRINTZ instruction have 5 forms across 2 categories:
//
// 1. Floating-point Round to Integral, toward Zero (vector)
//
//    FRINTZ  <Vd>.<T>, <Vn>.<T>
//    FRINTZ  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Round to Integral, toward Zero (vector). This instruction rounds
// a vector of floating-point values in the SIMD&FP source register to integral
// floating-point values of the same size using the Round towards Zero rounding
// mode, and writes the result to the SIMD&FP destination register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Round to Integral, toward Zero (scalar)
//
//    FRINTZ  <Dd>, <Dn>
//    FRINTZ  <Hd>, <Hn>
//    FRINTZ  <Sd>, <Sn>
//
// Floating-point Round to Integral, toward Zero (scalar). This instruction rounds
// a floating-point value in the SIMD&FP source register to an integral floating-
// point value of the same size using the Round towards Zero rounding mode, and
// writes the result to the SIMD&FP destination register.
//
// A zero input gives a zero result with the same sign, an infinite input gives an
// infinite result with the same sign, and a NaN is propagated as for normal
// arithmetic.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRINTZ(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRINTZ", 2, asm.Operands { v0, v1 })
    // FRINTZ  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 25, sa_vn, sa_vd))
    }
    // FRINTZ  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 1, 25, sa_vn, sa_vd))
    }
    // FRINTZ  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 11, sa_dn, sa_dd))
    }
    // FRINTZ  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 11, sa_hn, sa_hd))
    }
    // FRINTZ  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 11, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRINTZ")
}

// FRSQRTE instruction have 4 forms across one single category:
//
// 1. Floating-point Reciprocal Square Root Estimate
//
//    FRSQRTE  <Vd>.<T>, <Vn>.<T>
//    FRSQRTE  <Vd>.<T>, <Vn>.<T>
//    FRSQRTE  <V><d>, <V><n>
//    FRSQRTE  <Hd>, <Hn>
//
// Floating-point Reciprocal Square Root Estimate. This instruction calculates an
// approximate square root for each vector element in the source SIMD&FP register,
// places the result in a vector, and writes the vector to the destination SIMD&FP
// register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRSQRTE(v0, v1 interface{}) *Instruction {
    p := self.alloc("FRSQRTE", 2, asm.Operands { v0, v1 })
    // FRSQRTE  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 29, sa_vn, sa_vd))
    }
    // FRSQRTE  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 1, 29, sa_vn, sa_vd))
    }
    // FRSQRTE  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FRSQRTE")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdmisc(1, size, 29, sa_n, sa_d))
    }
    // FRSQRTE  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(1, 1, 29, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRSQRTE")
}

// FRSQRTS instruction have 4 forms across one single category:
//
// 1. Floating-point Reciprocal Square Root Step
//
//    FRSQRTS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FRSQRTS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FRSQRTS  <V><d>, <V><n>, <V><m>
//    FRSQRTS  <Hd>, <Hn>, <Hm>
//
// Floating-point Reciprocal Square Root Step. This instruction multiplies
// corresponding floating-point values in the vectors of the two source SIMD&FP
// registers, subtracts each of the products from 3.0, divides these results by
// 2.0, places the results into a vector, and writes the vector to the destination
// SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FRSQRTS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FRSQRTS", 3, asm.Operands { v0, v1, v2 })
    // FRSQRTS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 31, sa_vn, sa_vd))
    }
    // FRSQRTS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 1, sa_vm, 7, sa_vn, sa_vd))
    }
    // FRSQRTS  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for FRSQRTS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= sa_v
        return p.setins(asisdsame(0, size, sa_m, 31, sa_n, sa_d))
    }
    // FRSQRTS  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsamefp16(0, 1, sa_hm, 7, sa_hn, sa_hd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FRSQRTS")
}

// FSQRT instruction have 5 forms across 2 categories:
//
// 1. Floating-point Square Root (vector)
//
//    FSQRT  <Vd>.<T>, <Vn>.<T>
//    FSQRT  <Vd>.<T>, <Vn>.<T>
//
// Floating-point Square Root (vector). This instruction calculates the square root
// for each vector element in the source SIMD&FP register, places the result in a
// vector, and writes the vector to the destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR or a
// synchronous exception being generated. For more information, see Floating-point
// exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Square Root (scalar)
//
//    FSQRT  <Dd>, <Dn>
//    FSQRT  <Hd>, <Hn>
//    FSQRT  <Sd>, <Sn>
//
// Floating-point Square Root (scalar). This instruction calculates the square root
// of the value in the SIMD&FP source register and writes the result to the SIMD&FP
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FSQRT(v0, v1 interface{}) *Instruction {
    p := self.alloc("FSQRT", 2, asm.Operands { v0, v1 })
    // FSQRT  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 31, sa_vn, sa_vd))
    }
    // FSQRT  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 1, 31, sa_vn, sa_vd))
    }
    // FSQRT  <Dd>, <Dn>
    if isDr(v0) && isDr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 1, 3, sa_dn, sa_dd))
    }
    // FSQRT  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 3, 3, sa_hn, sa_hd))
    }
    // FSQRT  <Sd>, <Sn>
    if isSr(v0) && isSr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(floatdp1(0, 0, 0, 3, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FSQRT")
}

// FSUB instruction have 5 forms across 2 categories:
//
// 1. Floating-point Subtract (vector)
//
//    FSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    FSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Floating-point Subtract (vector). This instruction subtracts the elements in the
// vector in the second source SIMD&FP register, from the corresponding elements in
// the vector in the first source SIMD&FP register, places each result into
// elements of a vector, and writes the vector to the destination SIMD&FP register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Floating-point Subtract (scalar)
//
//    FSUB  <Dd>, <Dn>, <Dm>
//    FSUB  <Hd>, <Hn>, <Hm>
//    FSUB  <Sd>, <Sn>, <Sm>
//
// Floating-point Subtract (scalar). This instruction subtracts the floating-point
// value of the second source SIMD&FP register from the floating-point value of the
// first source SIMD&FP register, and writes the result to the destination SIMD&FP
// register.
//
// This instruction can generate a floating-point exception. Depending on the
// settings in FPCR , the exception results in either a flag being set in FPSR , or
// a synchronous exception being generated. For more information, see Floating-
// point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) FSUB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("FSUB", 3, asm.Operands { v0, v1, v2 })
    // FSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdsame(mask(sa_t, 1), 0, size, sa_vm, 26, sa_vn, sa_vd))
    }
    // FSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsamefp16(sa_t_1, 0, 1, sa_vm, 2, sa_vn, sa_vd))
    }
    // FSUB  <Dd>, <Dn>, <Dm>
    if isDr(v0) && isDr(v1) && isDr(v2) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_dn := uint32(v1.(asm.Register).ID())
        sa_dm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 1, sa_dm, 3, sa_dn, sa_dd))
    }
    // FSUB  <Hd>, <Hn>, <Hm>
    if isHr(v0) && isHr(v1) && isHr(v2) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        sa_hm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 3, sa_hm, 3, sa_hn, sa_hd))
    }
    // FSUB  <Sd>, <Sn>, <Sm>
    if isSr(v0) && isSr(v1) && isSr(v2) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_sm := uint32(v2.(asm.Register).ID())
        return p.setins(floatdp2(0, 0, 0, sa_sm, 3, sa_sn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for FSUB")
}

// GCSB instruction have one single form across one single category:
//
// 1. Guarded Control Stack Barrier
//
//    GCSB DSYNC
//
// Guarded Control Stack Barrier. This instruction generates a Guarded control
// stack data synchronization event.
//
// If FEAT_GCS is not implemented, this instruction executes as a NOP .
//
func (self *Program) GCSB(v0 interface{}) *Instruction {
    p := self.alloc("GCSB", 1, asm.Operands { v0 })
    if v0 == DSYNC {
        self.Arch.Require(FEAT_GCS)
        p.Domain = DomainSystem
        return p.setins(hints(2, 3))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSB")
}

// GCSPOPCX instruction have one single form across one single category:
//
// 1. Guarded Control Stack Pop and Compare exception return record
//
//    GCSPOPCX  {<Xt>}
//
// Guarded Control Stack Pop and Compare exception return record loads an exception
// return record from the location indicated by the current Guarded control stack
// pointer register, compares the loaded values with the current ELR_ELx, SPSR_ELx,
// and LR, and increments the pointer by the size of a Guarded control stack
// exception return record.
//
func (self *Program) GCSPOPCX(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("GCSPOPCX", 0, asm.Operands {})
        case 1  : p = self.alloc("GCSPOPCX", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction GCSPOPCX takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isXr(vv[0])) {
        self.Arch.Require(FEAT_GCS)
        p.Domain = DomainSystem
        sa_xt := uint32(0b11111)
        if len(vv) >= 1 {
            sa_xt = uint32(vv[0].(asm.Register).ID())
        }
        return p.setins(systeminstrs(0, 0, 7, 7, 5, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSPOPCX")
}

// GCSPOPM instruction have one single form across one single category:
//
// 1. Guarded Control Stack Pop
//
//    GCSPOPM  <Xt>
//
// Guarded Control Stack Pop loads the 64-bit doubleword that is pointed to by the
// current Guarded control stack pointer, writes it to the destination register,
// and increments the current Guarded control stack pointer register by the size of
// a Guarded control stack procedure return record.
//
func (self *Program) GCSPOPM(v0 interface{}) *Instruction {
    p := self.alloc("GCSPOPM", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_GCS)
        p.Domain = DomainSystem
        sa_xt := uint32(v0.(asm.Register).ID())
        return p.setins(systeminstrs(1, 3, 7, 7, 1, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSPOPM")
}

// GCSPOPX instruction have one single form across one single category:
//
// 1. Guarded Control Stack Pop exception return record
//
//    GCSPOPX  {<Xt>}
//
// Guarded Control Stack Pop exception return record loads an exception return
// record from the location indicated by the current Guarded control stack pointer
// register, checks that the record is an exception return record, and increments
// the pointer by the size of a Guarded control stack exception return record.
//
func (self *Program) GCSPOPX(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("GCSPOPX", 0, asm.Operands {})
        case 1  : p = self.alloc("GCSPOPX", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction GCSPOPX takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isXr(vv[0])) {
        self.Arch.Require(FEAT_GCS)
        p.Domain = DomainSystem
        sa_xt := uint32(0b11111)
        if len(vv) >= 1 {
            sa_xt = uint32(vv[0].(asm.Register).ID())
        }
        return p.setins(systeminstrs(0, 0, 7, 7, 6, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSPOPX")
}

// GCSPUSHM instruction have one single form across one single category:
//
// 1. Guarded Control Stack Push
//
//    GCSPUSHM  <Xt>
//
// Guarded Control Stack Push decrements the current Guarded control stack pointer
// register by the size of a Guarded control procedure return record and stores an
// entry to the Guarded control stack.
//
func (self *Program) GCSPUSHM(v0 interface{}) *Instruction {
    p := self.alloc("GCSPUSHM", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_GCS)
        p.Domain = DomainSystem
        sa_xt_1 := uint32(v0.(asm.Register).ID())
        return p.setins(systeminstrs(0, 3, 7, 7, 0, sa_xt_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSPUSHM")
}

// GCSPUSHX instruction have one single form across one single category:
//
// 1. Guarded Control Stack Push exception return record
//
//    GCSPUSHX  {<Xt>}
//
// Guarded Control Stack Push exception return record decrements the current
// Guarded control stack pointer register by the size of a Guarded control stack
// exception return record and stores an exception return record to the Guarded
// control stack.
//
func (self *Program) GCSPUSHX(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("GCSPUSHX", 0, asm.Operands {})
        case 1  : p = self.alloc("GCSPUSHX", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction GCSPUSHX takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isXr(vv[0])) {
        self.Arch.Require(FEAT_GCS)
        p.Domain = DomainSystem
        sa_xt := uint32(0b11111)
        if len(vv) >= 1 {
            sa_xt = uint32(vv[0].(asm.Register).ID())
        }
        return p.setins(systeminstrs(0, 0, 7, 7, 4, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSPUSHX")
}

// GCSSS1 instruction have one single form across one single category:
//
// 1. Guarded Control Stack Switch Stack 1
//
//    GCSSS1  <Xt>
//
// Guarded Control Stack Switch Stack 1 validates that the stack being switched to
// contains a Valid cap entry, stores an In-progress cap entry to the stack that is
// being switched to, and sets the current Guarded control stack pointer to the
// stack that is being switched to.
//
func (self *Program) GCSSS1(v0 interface{}) *Instruction {
    p := self.alloc("GCSSS1", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_GCS)
        p.Domain = DomainSystem
        sa_xt_1 := uint32(v0.(asm.Register).ID())
        return p.setins(systeminstrs(0, 3, 7, 7, 2, sa_xt_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSSS1")
}

// GCSSS2 instruction have one single form across one single category:
//
// 1. Guarded Control Stack Switch Stack 2
//
//    GCSSS2  <Xt>
//
// Guarded Control Stack Switch Stack 2 validates that the most recent entry of the
// Guarded control stack being switched to contains an In-progress cap entry,
// stores a Valid cap entry to the Guarded control stack that is being switched
// from, and sets Xt to the Guarded control stack pointer that is being switched
// from.
//
func (self *Program) GCSSS2(v0 interface{}) *Instruction {
    p := self.alloc("GCSSS2", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_GCS)
        p.Domain = DomainSystem
        sa_xt := uint32(v0.(asm.Register).ID())
        return p.setins(systeminstrs(1, 3, 7, 7, 3, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSSS2")
}

// GCSSTR instruction have one single form across one single category:
//
// 1. Guarded Control Stack Store
//
//    GCSSTR  <Xt>, [<Xn|SP>]
//
// Guarded Control Stack Store stores a doubleword from a register to memory. The
// address that is used for the store is calculated from a base register.
//
func (self *Program) GCSSTR(v0, v1 interface{}) *Instruction {
    p := self.alloc("GCSSTR", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_GCS)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldst_gcs(0, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSSTR")
}

// GCSSTTR instruction have one single form across one single category:
//
// 1. Guarded Control Stack unprivileged Store
//
//    GCSSTTR  <Xt>, [<Xn|SP>]
//
// Guarded Control Stack unprivileged Store stores a doubleword from a register to
// memory. The address that is used for the store is calculated from a base
// register.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1 and HCR_EL2 .{NV, NV1} is not {1,
//       1}.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed.
//
func (self *Program) GCSSTTR(v0, v1 interface{}) *Instruction {
    p := self.alloc("GCSSTTR", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_GCS)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldst_gcs(1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GCSSTTR")
}

// GMI instruction have one single form across one single category:
//
// 1. Tag Mask Insert
//
//    GMI  <Xd>, <Xn|SP>, <Xm>
//
// Tag Mask Insert inserts the tag in the first source register into the excluded
// set specified in the second source register, writing the new excluded set to the
// destination register.
//
func (self *Program) GMI(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("GMI", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isXrOrSP(v1) && isXr(v2) {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        Rm := uint32(0b00000)
        Rm |= sa_xm
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rd := uint32(0b00000)
        Rd |= sa_xd
        return p.setins(dp_2src(1, 0, Rm, 5, Rn, Rd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for GMI")
}

// HINT instruction have one single form across one single category:
//
// 1. Hint instruction
//
//    HINT  #<imm>
//
// Hint instruction is for the instruction set space that is reserved for
// architectural hint instructions.
//
// Some encodings described here are not allocated in this revision of the
// architecture, and behave as NOPs. These encodings might be allocated to other
// hint functionality in future revisions of the architecture and therefore must
// not be used by software.
//
func (self *Program) HINT(v0 interface{}) *Instruction {
    p := self.alloc("HINT", 1, asm.Operands { v0 })
    if isInRange(v0, 0, 127) {
        p.Domain = DomainSystem
        sa_imm := asUimm7(v0)
        return p.setins(hints(ubfx(sa_imm, 3, 4), mask(sa_imm, 3)))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for HINT")
}

// HLT instruction have one single form across one single category:
//
// 1. Halt instruction
//
//    HLT  #<imm>
//
// Halt instruction. An HLT instruction can generate a Halt Instruction debug
// event, which causes entry into Debug state.
//
func (self *Program) HLT(v0 interface{}) *Instruction {
    p := self.alloc("HLT", 1, asm.Operands { v0 })
    if isInRange(v0, 0, 65535) {
        p.Domain = DomainSystem
        sa_imm := asUimm16(v0)
        return p.setins(exception(2, sa_imm, 0, 0))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for HLT")
}

// HVC instruction have one single form across one single category:
//
// 1. Hypervisor Call
//
//    HVC  #<imm>
//
// Hypervisor Call causes an exception to EL2. Software executing at EL1 can use
// this instruction to call the hypervisor to request a service.
//
// The HVC instruction is undefined :
//
//     * When EL3 is implemented and SCR_EL3 .HCE is set to 0.
//     * When EL3 is not implemented and HCR_EL2 .HCD is set to 1.
//     * When EL2 is not implemented.
//     * At EL1 if EL2 is not enabled in the current Security state.
//     * At EL0.
//
// On executing an HVC instruction, the PE records the exception as a Hypervisor
// Call exception in ESR_ELx , using the EC value 0x16 , and the value of the
// immediate argument.
//
func (self *Program) HVC(v0 interface{}) *Instruction {
    p := self.alloc("HVC", 1, asm.Operands { v0 })
    if isInRange(v0, 0, 65535) {
        p.Domain = DomainSystem
        sa_imm := asUimm16(v0)
        return p.setins(exception(0, sa_imm, 0, 2))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for HVC")
}

// IC instruction have one single form across one single category:
//
// 1. Instruction Cache operation
//
//    IC  <ic_op>{, <Xt>}
//
// Instruction Cache operation. For more information, see op0==0b01, cache
// maintenance, TLB maintenance, and address translation instructions .
//
func (self *Program) IC(v0 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("IC", 1, asm.Operands { v0 })
        case 1  : p = self.alloc("IC", 2, asm.Operands { v0, vv[0] })
        default : panic("aarch64: instruction IC takes 1 or 2 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && isICOption(v0) && (len(vv) == 0 || isXr(vv[0])) {
        p.Domain = DomainSystem
        sa_xt := uint32(0b11111)
        sa_ic_op := uint32(v0.(ICOption))
        if len(vv) >= 1 {
            sa_xt = uint32(vv[0].(asm.Register).ID())
        }
        return p.setins(systeminstrs(0, ubfx(sa_ic_op, 7, 3), 7, ubfx(sa_ic_op, 3, 4), mask(sa_ic_op, 3), sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for IC")
}

// INS instruction have 2 forms across 2 categories:
//
// 1. Insert vector element from another vector element
//
//    INS  <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]
//
// Insert vector element from another vector element. This instruction copies the
// vector element of the source SIMD&FP register to the specified vector element of
// the destination SIMD&FP register.
//
// This instruction can insert data into individual elements within a SIMD&FP
// register without clearing the remaining bits to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Insert vector element from general-purpose register
//
//    INS  <Vd>.<Ts>[<index>], <R><n>
//
// Insert vector element from general-purpose register. This instruction copies the
// contents of the source general-purpose register to the specified vector element
// in the destination SIMD&FP register.
//
// This instruction can insert data into individual elements within a SIMD&FP
// register without clearing the remaining bits to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) INS(v0, v1 interface{}) *Instruction {
    p := self.alloc("INS", 2, asm.Operands { v0, v1 })
    // INS  <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]
    if isVri(v0) && isVri(v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_ts__bit_mask uint32
        sa_vd := uint32(v0.(VidxRegister).ID())
        switch vmoder(v0) {
            case ModeB: sa_ts = 0b00001
            case ModeH: sa_ts = 0b00010
            case ModeS: sa_ts = 0b00100
            case ModeD: sa_ts = 0b01000
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v0) {
            case ModeB: sa_ts__bit_mask = 0b00001
            case ModeH: sa_ts__bit_mask = 0b00011
            case ModeS: sa_ts__bit_mask = 0b00111
            case ModeD: sa_ts__bit_mask = 0b01111
            default: panic("aarch64: unreachable")
        }
        sa_index1 := uint32(vidxr(v0))
        sa_vn := uint32(v1.(VidxRegister).ID())
        sa_index2 := uint32(vidxr(v1))
        if sa_index1 != ubfx(sa_index2, 4, 5) || ubfx(sa_index2, 4, 5) != sa_ts & sa_ts__bit_mask {
            panic("aarch64: invalid combination of operands for INS")
        }
        return p.setins(asimdins(1, 1, sa_index1, mask(sa_index2, 4), sa_vn, sa_vd))
    }
    // INS  <Vd>.<Ts>[<index>], <R><n>
    if isVri(v0) && isWrOrXr(v1) {
        p.Domain = DomainAdvSimd
        var sa_r [3]uint32
        var sa_r__bit_mask [3]uint32
        var sa_ts uint32
        var sa_ts__bit_mask uint32
        sa_vd := uint32(v0.(VidxRegister).ID())
        switch vmoder(v0) {
            case ModeB: sa_ts = 0b00001
            case ModeH: sa_ts = 0b00010
            case ModeS: sa_ts = 0b00100
            case ModeD: sa_ts = 0b01000
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v0) {
            case ModeB: sa_ts__bit_mask = 0b00001
            case ModeH: sa_ts__bit_mask = 0b00011
            case ModeS: sa_ts__bit_mask = 0b00111
            case ModeD: sa_ts__bit_mask = 0b01111
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v0))
        sa_n := uint32(v1.(asm.Register).ID())
        switch true {
            case isWr(v1): sa_r = [3]uint32{0b00100, 0b00010, 0b00001}
            case isXr(v1): sa_r = [3]uint32{0b01000}
            default: panic("aarch64: unreachable")
        }
        switch true {
            case isWr(v1): sa_r__bit_mask = [3]uint32{0b00111, 0b00011, 0b00001}
            case isXr(v1): sa_r__bit_mask = [3]uint32{0b01111}
            default: panic("aarch64: unreachable")
        }
        if sa_index != sa_ts & sa_ts__bit_mask || !matchany(sa_ts & sa_ts__bit_mask, &sa_r[0], &sa_r__bit_mask[0], 3) {
            panic("aarch64: invalid combination of operands for INS")
        }
        return p.setins(asimdins(1, 0, sa_index, 3, sa_n, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for INS")
}

// IRG instruction have one single form across one single category:
//
// 1. Insert Random Tag
//
//    IRG  <Xd|SP>, <Xn|SP>{, <Xm>}
//
// Insert Random Tag inserts a random Logical Address Tag into the address in the
// first source register, and writes the result to the destination register. Any
// tags specified in the optional second source register or in GCR_EL1.Exclude are
// excluded from the selection of the random Logical Address Tag.
//
func (self *Program) IRG(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("IRG", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("IRG", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction IRG takes 2 or 3 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isXrOrSP(v1) &&
       (len(vv) == 0 || isXr(vv[0])) &&
       (v0 == SP || v1 == SP) {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xm := uint32(XZR.ID())
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            sa_xm = uint32(vv[0].(asm.Register).ID())
        }
        Rm := uint32(0b00000)
        Rm |= sa_xm
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rd := uint32(0b00000)
        Rd |= sa_xd_sp
        return p.setins(dp_2src(1, 0, Rm, 4, Rn, Rd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for IRG")
}

// ISB instruction have one single form across one single category:
//
// 1. Instruction Synchronization Barrier
//
//    ISB  {<option>|#<imm>}
//
// Instruction Synchronization Barrier flushes the pipeline in the PE and is a
// context synchronization event. For more information, see Instruction
// Synchronization Barrier (ISB) .
//
func (self *Program) ISB(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("ISB", 0, asm.Operands {})
        case 1  : p = self.alloc("ISB", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction ISB takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isOption(vv[0])) {
        p.Domain = DomainSystem
        sa_option := uint32(SY)
        if len(vv) >= 1 {
            sa_option = asBarrierOption(vv[0])
        }
        sa_imm := sa_option
        if sa_imm != sa_option {
            panic("aarch64: invalid combination of operands for ISB")
        }
        return p.setins(barriers(sa_imm, 6, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ISB")
}

// LD1 instruction have 24 forms across 2 categories:
//
// 1. Load multiple single-element structures to one, two, three, or four registers
//
//    LD1  { <Vt>.<T> }, [<Xn|SP>]
//    LD1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
//    LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
//    LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
//    LD1  { <Vt>.<T> }, [<Xn|SP>], <imm>
//    LD1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
//    LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
//    LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
//    LD1  { <Vt>.<T> }, [<Xn|SP>], <Xm>
//    LD1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
//    LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
//    LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
//
// Load multiple single-element structures to one, two, three, or four registers.
// This instruction loads multiple single-element structures from memory and writes
// the result to one, two, three, or four SIMD&FP registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Load one single-element structure to one lane of one register
//
//    LD1  { <Vt>.B }[<index>], [<Xn|SP>]
//    LD1  { <Vt>.D }[<index>], [<Xn|SP>]
//    LD1  { <Vt>.H }[<index>], [<Xn|SP>]
//    LD1  { <Vt>.S }[<index>], [<Xn|SP>]
//    LD1  { <Vt>.B }[<index>], [<Xn|SP>], #1
//    LD1  { <Vt>.B }[<index>], [<Xn|SP>], <Xm>
//    LD1  { <Vt>.D }[<index>], [<Xn|SP>], #8
//    LD1  { <Vt>.D }[<index>], [<Xn|SP>], <Xm>
//    LD1  { <Vt>.H }[<index>], [<Xn|SP>], #2
//    LD1  { <Vt>.H }[<index>], [<Xn|SP>], <Xm>
//    LD1  { <Vt>.S }[<index>], [<Xn|SP>], #4
//    LD1  { <Vt>.S }[<index>], [<Xn|SP>], <Xm>
//
// Load one single-element structure to one lane of one register. This instruction
// loads a single-element structure from memory and writes the result to the
// specified lane of the SIMD&FP register without affecting the other bits of the
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) LD1(v0, v1 interface{}) *Instruction {
    p := self.alloc("LD1", 2, asm.Operands { v0, v1 })
    // LD1  { <Vt>.<T> }, [<Xn|SP>]
    if isVec1(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 1, 7, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 1, 10, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 1, 6, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 1, 2, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T> }, [<Xn|SP>], <imm>
    if isVec1(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for LD1")
        }
        return p.setins(asisdlsep(sa_imm, 1, 31, 7, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm_1 := uint32(moffs(v1))
        if sa_imm_1 != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for LD1")
        }
        return p.setins(asisdlsep(sa_imm_1, 1, 31, 10, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm_2 := uint32(moffs(v1))
        if sa_imm_2 != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for LD1")
        }
        return p.setins(asisdlsep(sa_imm_2, 1, 31, 6, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm_3 := uint32(moffs(v1))
        if sa_imm_3 != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for LD1")
        }
        return p.setins(asisdlsep(sa_imm_3, 1, 31, 2, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T> }, [<Xn|SP>], <Xm>
    if isVec1(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 1, sa_xm, 7, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 1, sa_xm, 10, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 1, sa_xm, 6, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 1, sa_xm, 2, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.B }[<index>], [<Xn|SP>]
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index, 3, 1),
            1,
            0,
            0,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD1  { <Vt>.D }[<index>], [<Xn|SP>]
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index_1, 1, 0, 0, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.H }[<index>], [<Xn|SP>]
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index_2, 3, 1),
            1,
            0,
            0,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD1  { <Vt>.S }[<index>], [<Xn|SP>]
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(ubfx(sa_index_3, 1, 1), 1, 0, 0, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.B }[<index>], [<Xn|SP>], #1
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 1 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            1,
            0,
            31,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD1  { <Vt>.B }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            1,
            0,
            sa_xm,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD1  { <Vt>.D }[<index>], [<Xn|SP>], #8
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 8 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 1, 0, 31, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.D }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 1, 0, sa_xm, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.H }[<index>], [<Xn|SP>], #2
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 2 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            1,
            0,
            31,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD1  { <Vt>.H }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            1,
            0,
            sa_xm,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD1  { <Vt>.S }[<index>], [<Xn|SP>], #4
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 4 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 1, 0, 31, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // LD1  { <Vt>.S }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 1, 0, sa_xm, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LD1")
}

// LD1R instruction have 3 forms across one single category:
//
// 1. Load one single-element structure and Replicate to all lanes (of one
//    register)
//
//    LD1R  { <Vt>.<T> }, [<Xn|SP>]
//    LD1R  { <Vt>.<T> }, [<Xn|SP>], <imm>
//    LD1R  { <Vt>.<T> }, [<Xn|SP>], <Xm>
//
// Load one single-element structure and Replicate to all lanes (of one register).
// This instruction loads a single-element structure from memory and replicates the
// structure to all the lanes of the SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) LD1R(v0, v1 interface{}) *Instruction {
    p := self.alloc("LD1R", 2, asm.Operands { v0, v1 })
    // LD1R  { <Vt>.<T> }, [<Xn|SP>]
    if isVec1(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(mask(sa_t, 1), 1, 0, 0, 6, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD1R  { <Vt>.<T> }, [<Xn|SP>], <imm>
    if isVec1(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != ubfx(sa_t, 1, 2) {
            panic("aarch64: invalid combination of operands for LD1R")
        }
        return p.setins(asisdlsop(mask(sa_t, 1), 1, 0, 31, 6, 0, sa_imm, sa_xn_sp, sa_vt))
    }
    // LD1R  { <Vt>.<T> }, [<Xn|SP>], <Xm>
    if isVec1(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD1R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(mask(sa_t, 1), 1, 0, sa_xm, 6, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LD1R")
}

// LD2 instruction have 15 forms across 2 categories:
//
// 1. Load multiple 2-element structures to two registers
//
//    LD2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
//    LD2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
//    LD2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
//
// Load multiple 2-element structures to two registers. This instruction loads
// multiple 2-element structures from memory and writes the result to the two
// SIMD&FP registers, with de-interleaving.
//
// For an example of de-interleaving, see LD3 (multiple structures) .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Load single 2-element structure to one lane of two registers
//
//    LD2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>]
//    LD2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>]
//    LD2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>]
//    LD2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>]
//    LD2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], #2
//    LD2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], <Xm>
//    LD2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], #16
//    LD2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], <Xm>
//    LD2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], #4
//    LD2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], <Xm>
//    LD2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], #8
//    LD2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], <Xm>
//
// Load single 2-element structure to one lane of two registers. This instruction
// loads a 2-element structure from memory and writes the result to the
// corresponding elements of the two SIMD&FP registers without affecting the other
// bits of the registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) LD2(v0, v1 interface{}) *Instruction {
    p := self.alloc("LD2", 2, asm.Operands { v0, v1 })
    // LD2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD2")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 1, 8, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD2")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for LD2")
        }
        return p.setins(asisdlsep(sa_imm, 1, 31, 8, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD2")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 1, sa_xm, 8, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>]
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index, 3, 1),
            1,
            1,
            0,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>]
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index_1, 1, 1, 0, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>]
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index_2, 3, 1),
            1,
            1,
            0,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>]
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(ubfx(sa_index_3, 1, 1), 1, 1, 0, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // LD2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], #2
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 2 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            1,
            1,
            31,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            1,
            1,
            sa_xm,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], #16
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 16 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 1, 1, 31, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 1, 1, sa_xm, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], #4
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 4 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            1,
            1,
            31,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            1,
            1,
            sa_xm,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], #8
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 8 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 1, 1, 31, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // LD2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 1, 1, sa_xm, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LD2")
}

// LD2R instruction have 3 forms across one single category:
//
// 1. Load single 2-element structure and Replicate to all lanes of two registers
//
//    LD2R  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
//    LD2R  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
//    LD2R  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
//
// Load single 2-element structure and Replicate to all lanes of two registers.
// This instruction loads a 2-element structure from memory and replicates the
// structure to all the lanes of the two SIMD&FP registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) LD2R(v0, v1 interface{}) *Instruction {
    p := self.alloc("LD2R", 2, asm.Operands { v0, v1 })
    // LD2R  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD2R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(mask(sa_t, 1), 1, 1, 0, 6, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD2R  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD2R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != ubfx(sa_t, 1, 2) {
            panic("aarch64: invalid combination of operands for LD2R")
        }
        return p.setins(asisdlsop(mask(sa_t, 1), 1, 1, 31, 6, 0, sa_imm, sa_xn_sp, sa_vt))
    }
    // LD2R  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD2R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(mask(sa_t, 1), 1, 1, sa_xm, 6, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LD2R")
}

// LD3 instruction have 15 forms across 2 categories:
//
// 1. Load multiple 3-element structures to three registers
//
//    LD3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
//    LD3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
//    LD3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
//
// Load multiple 3-element structures to three registers. This instruction loads
// multiple 3-element structures from memory and writes the result to the three
// SIMD&FP registers, with de-interleaving.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.deinterleaving_an_array_of_3_element_structures.svg]
// de-interleaving of a LD3.16 (multiple 3-element structures) instruction:
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Load single 3-element structure to one lane of three registers
//
//    LD3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>]
//    LD3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>]
//    LD3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>]
//    LD3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>]
//    LD3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], #3
//    LD3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], <Xm>
//    LD3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], #24
//    LD3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], <Xm>
//    LD3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], #6
//    LD3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], <Xm>
//    LD3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], #12
//    LD3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], <Xm>
//
// Load single 3-element structure to one lane of three registers. This instruction
// loads a 3-element structure from memory and writes the result to the
// corresponding elements of the three SIMD&FP registers without affecting the
// other bits of the registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) LD3(v0, v1 interface{}) *Instruction {
    p := self.alloc("LD3", 2, asm.Operands { v0, v1 })
    // LD3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD3")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 1, 4, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD3")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for LD3")
        }
        return p.setins(asisdlsep(sa_imm, 1, 31, 4, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD3")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 1, sa_xm, 4, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>]
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index, 3, 1),
            1,
            0,
            0,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>]
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index_1, 1, 0, 0, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>]
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index_2, 3, 1),
            1,
            0,
            0,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>]
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(ubfx(sa_index_3, 1, 1), 1, 0, 0, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // LD3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], #3
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 3 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            1,
            0,
            31,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            1,
            0,
            sa_xm,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], #24
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 24 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 1, 0, 31, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 1, 0, sa_xm, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], #6
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 6 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            1,
            0,
            31,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            1,
            0,
            sa_xm,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], #12
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 12 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 1, 0, 31, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // LD3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 1, 0, sa_xm, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LD3")
}

// LD3R instruction have 3 forms across one single category:
//
// 1. Load single 3-element structure and Replicate to all lanes of three registers
//
//    LD3R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
//    LD3R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
//    LD3R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
//
// Load single 3-element structure and Replicate to all lanes of three registers.
// This instruction loads a 3-element structure from memory and replicates the
// structure to all the lanes of the three SIMD&FP registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) LD3R(v0, v1 interface{}) *Instruction {
    p := self.alloc("LD3R", 2, asm.Operands { v0, v1 })
    // LD3R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD3R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(mask(sa_t, 1), 1, 0, 0, 7, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD3R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD3R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != ubfx(sa_t, 1, 2) {
            panic("aarch64: invalid combination of operands for LD3R")
        }
        return p.setins(asisdlsop(mask(sa_t, 1), 1, 0, 31, 7, 0, sa_imm, sa_xn_sp, sa_vt))
    }
    // LD3R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD3R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(mask(sa_t, 1), 1, 0, sa_xm, 7, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LD3R")
}

// LD4 instruction have 15 forms across 2 categories:
//
// 1. Load multiple 4-element structures to four registers
//
//    LD4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
//    LD4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
//    LD4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
//
// Load multiple 4-element structures to four registers. This instruction loads
// multiple 4-element structures from memory and writes the result to the four
// SIMD&FP registers, with de-interleaving.
//
// For an example of de-interleaving, see LD3 (multiple structures) .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Load single 4-element structure to one lane of four registers
//
//    LD4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>]
//    LD4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>]
//    LD4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>]
//    LD4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>]
//    LD4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], #4
//    LD4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], <Xm>
//    LD4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], #32
//    LD4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], <Xm>
//    LD4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], #8
//    LD4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], <Xm>
//    LD4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], #16
//    LD4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], <Xm>
//
// Load single 4-element structure to one lane of four registers. This instruction
// loads a 4-element structure from memory and writes the result to the
// corresponding elements of the four SIMD&FP registers without affecting the other
// bits of the registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) LD4(v0, v1 interface{}) *Instruction {
    p := self.alloc("LD4", 2, asm.Operands { v0, v1 })
    // LD4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD4")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 1, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD4")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for LD4")
        }
        return p.setins(asisdlsep(sa_imm, 1, 31, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD4")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 1, sa_xm, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>]
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index, 3, 1),
            1,
            1,
            0,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>]
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index_1, 1, 1, 0, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>]
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index_2, 3, 1),
            1,
            1,
            0,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>]
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(ubfx(sa_index_3, 1, 1), 1, 1, 0, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // LD4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], #4
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 4 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            1,
            1,
            31,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            1,
            1,
            sa_xm,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], #32
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 32 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 1, 1, 31, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 1, 1, sa_xm, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // LD4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], #8
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 8 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            1,
            1,
            31,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            1,
            1,
            sa_xm,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // LD4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], #16
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 16 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 1, 1, 31, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // LD4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 1, 1, sa_xm, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LD4")
}

// LD4R instruction have 3 forms across one single category:
//
// 1. Load single 4-element structure and Replicate to all lanes of four registers
//
//    LD4R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
//    LD4R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
//    LD4R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
//
// Load single 4-element structure and Replicate to all lanes of four registers.
// This instruction loads a 4-element structure from memory and replicates the
// structure to all the lanes of the four SIMD&FP registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) LD4R(v0, v1 interface{}) *Instruction {
    p := self.alloc("LD4R", 2, asm.Operands { v0, v1 })
    // LD4R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD4R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(mask(sa_t, 1), 1, 1, 0, 7, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // LD4R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD4R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != ubfx(sa_t, 1, 2) {
            panic("aarch64: invalid combination of operands for LD4R")
        }
        return p.setins(asisdlsop(mask(sa_t, 1), 1, 1, 31, 7, 0, sa_imm, sa_xn_sp, sa_vt))
    }
    // LD4R  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for LD4R")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(mask(sa_t, 1), 1, 1, sa_xm, 7, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LD4R")
}

// LD64B instruction have one single form across one single category:
//
// 1. Single-copy Atomic 64-byte Load
//
//    LD64B  <Xt>, [<Xn|SP> {,#0}]
//
// Single-copy Atomic 64-byte Load derives an address from a base register value,
// loads eight 64-bit doublewords from a memory location, and writes them to
// consecutive registers, Xt to X(t+7) . The data that is loaded is atomic and is
// required to be 64-byte aligned.
//
func (self *Program) LD64B(v0, v1 interface{}) *Instruction {
    p := self.alloc("LD64B", 2, asm.Operands { v0, v1 })
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LS64)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, 31, 1, 5, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LD64B")
}

// LDADD instruction have 2 forms across one single category:
//
// 1. Atomic add on word or doubleword in memory
//
//    LDADD  <Ws>, <Wt>, [<Xn|SP>]
//    LDADD  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic add on word or doubleword in memory atomically loads a 32-bit word or
// 64-bit doubleword from memory, adds the value held in a register to it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDADDA and
//       LDADDAL load from memory with acquire semantics.
//     * LDADDL and LDADDAL store to memory with release semantics.
//     * LDADD has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADD", 3, asm.Operands { v0, v1, v2 })
    // LDADD  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    // LDADD  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDADD")
}

// LDADDA instruction have 2 forms across one single category:
//
// 1. Atomic add on word or doubleword in memory
//
//    LDADDA  <Ws>, <Wt>, [<Xn|SP>]
//    LDADDA  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic add on word or doubleword in memory atomically loads a 32-bit word or
// 64-bit doubleword from memory, adds the value held in a register to it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDADDA and
//       LDADDAL load from memory with acquire semantics.
//     * LDADDL and LDADDAL store to memory with release semantics.
//     * LDADD has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDA", 3, asm.Operands { v0, v1, v2 })
    // LDADDA  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 0, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    // LDADDA  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 0, sa_xs, 0, 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDA")
}

// LDADDAB instruction have one single form across one single category:
//
// 1. Atomic add on byte in memory
//
//    LDADDAB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic add on byte in memory atomically loads an 8-bit byte from memory, adds
// the value held in a register to it, and stores the result back to memory. The
// value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDADDAB and LDADDALB load
//       from memory with acquire semantics.
//     * LDADDLB and LDADDALB store to memory with release semantics.
//     * LDADDB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDAB")
}

// LDADDAH instruction have one single form across one single category:
//
// 1. Atomic add on halfword in memory
//
//    LDADDAH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic add on halfword in memory atomically loads a 16-bit halfword from memory,
// adds the value held in a register to it, and stores the result back to memory.
// The value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDADDAH and LDADDALH load
//       from memory with acquire semantics.
//     * LDADDLH and LDADDALH store to memory with release semantics.
//     * LDADDH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDAH")
}

// LDADDAL instruction have 2 forms across one single category:
//
// 1. Atomic add on word or doubleword in memory
//
//    LDADDAL  <Ws>, <Wt>, [<Xn|SP>]
//    LDADDAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic add on word or doubleword in memory atomically loads a 32-bit word or
// 64-bit doubleword from memory, adds the value held in a register to it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDADDA and
//       LDADDAL load from memory with acquire semantics.
//     * LDADDL and LDADDAL store to memory with release semantics.
//     * LDADD has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDAL", 3, asm.Operands { v0, v1, v2 })
    // LDADDAL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 1, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    // LDADDAL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 1, sa_xs, 0, 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDAL")
}

// LDADDALB instruction have one single form across one single category:
//
// 1. Atomic add on byte in memory
//
//    LDADDALB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic add on byte in memory atomically loads an 8-bit byte from memory, adds
// the value held in a register to it, and stores the result back to memory. The
// value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDADDAB and LDADDALB load
//       from memory with acquire semantics.
//     * LDADDLB and LDADDALB store to memory with release semantics.
//     * LDADDB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDALB")
}

// LDADDALH instruction have one single form across one single category:
//
// 1. Atomic add on halfword in memory
//
//    LDADDALH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic add on halfword in memory atomically loads a 16-bit halfword from memory,
// adds the value held in a register to it, and stores the result back to memory.
// The value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDADDAH and LDADDALH load
//       from memory with acquire semantics.
//     * LDADDLH and LDADDALH store to memory with release semantics.
//     * LDADDH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDALH")
}

// LDADDB instruction have one single form across one single category:
//
// 1. Atomic add on byte in memory
//
//    LDADDB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic add on byte in memory atomically loads an 8-bit byte from memory, adds
// the value held in a register to it, and stores the result back to memory. The
// value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDADDAB and LDADDALB load
//       from memory with acquire semantics.
//     * LDADDLB and LDADDALB store to memory with release semantics.
//     * LDADDB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDB")
}

// LDADDH instruction have one single form across one single category:
//
// 1. Atomic add on halfword in memory
//
//    LDADDH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic add on halfword in memory atomically loads a 16-bit halfword from memory,
// adds the value held in a register to it, and stores the result back to memory.
// The value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDADDAH and LDADDALH load
//       from memory with acquire semantics.
//     * LDADDLH and LDADDALH store to memory with release semantics.
//     * LDADDH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDH")
}

// LDADDL instruction have 2 forms across one single category:
//
// 1. Atomic add on word or doubleword in memory
//
//    LDADDL  <Ws>, <Wt>, [<Xn|SP>]
//    LDADDL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic add on word or doubleword in memory atomically loads a 32-bit word or
// 64-bit doubleword from memory, adds the value held in a register to it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDADDA and
//       LDADDAL load from memory with acquire semantics.
//     * LDADDL and LDADDAL store to memory with release semantics.
//     * LDADD has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDL", 3, asm.Operands { v0, v1, v2 })
    // LDADDL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    // LDADDL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDL")
}

// LDADDLB instruction have one single form across one single category:
//
// 1. Atomic add on byte in memory
//
//    LDADDLB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic add on byte in memory atomically loads an 8-bit byte from memory, adds
// the value held in a register to it, and stores the result back to memory. The
// value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDADDAB and LDADDALB load
//       from memory with acquire semantics.
//     * LDADDLB and LDADDALB store to memory with release semantics.
//     * LDADDB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDLB")
}

// LDADDLH instruction have one single form across one single category:
//
// 1. Atomic add on halfword in memory
//
//    LDADDLH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic add on halfword in memory atomically loads a 16-bit halfword from memory,
// adds the value held in a register to it, and stores the result back to memory.
// The value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDADDAH and LDADDALH load
//       from memory with acquire semantics.
//     * LDADDLH and LDADDALH store to memory with release semantics.
//     * LDADDH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDADDLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDADDLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDADDLH")
}

// LDAP1 instruction have one single form across one single category:
//
// 1. Load-Acquire RCpc one single-element structure to one lane of one register
//
//    LDAP1  { <Vt>.D }[<index>], [<Xn|SP>]
//
// Load-Acquire RCpc one single-element structure to one lane of one register. This
// instruction loads a single-element structure from memory and writes the result
// to the specified lane of the SIMD&FP register without affecting the other bits
// of the register.
//
// The instruction has memory ordering semantics, as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) LDAP1(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAP1", 2, asm.Operands { v0, v1 })
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index, 1, 0, 1, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDAP1")
}

// LDAPR instruction have 4 forms across one single category:
//
// 1. Load-Acquire RCpc Register
//
//    LDAPR  <Wt>, [<Xn|SP>], #4
//    LDAPR  <Wt>, [<Xn|SP> {,#0}]
//    LDAPR  <Xt>, [<Xn|SP>], #8
//    LDAPR  <Xt>, [<Xn|SP> {,#0}]
//
// Load-Acquire RCpc Register derives an address from a base register value, loads
// a 32-bit word or 64-bit doubleword from the derived address in memory, and
// writes it to a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAPR(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAPR", 2, asm.Operands { v0, v1 })
    // LDAPR  <Wt>, [<Xn|SP>], #4
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 4 && mext(v1) == PostIndex {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldapstl_writeback(2, 1, sa_xn_sp, sa_wt))
    }
    // LDAPR  <Wt>, [<Xn|SP> {,#0}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 1, 0, 31, 1, 4, sa_xn_sp, sa_wt))
    }
    // LDAPR  <Xt>, [<Xn|SP>], #8
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 8 && mext(v1) == PostIndex {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldapstl_writeback(3, 1, sa_xn_sp, sa_xt))
    }
    // LDAPR  <Xt>, [<Xn|SP> {,#0}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 1, 0, 31, 1, 4, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDAPR")
}

// LDAPRB instruction have one single form across one single category:
//
// 1. Load-Acquire RCpc Register Byte
//
//    LDAPRB  <Wt>, [<Xn|SP> {,#0}]
//
// Load-Acquire RCpc Register Byte derives an address from a base register value,
// loads a byte from the derived address in memory, zero-extends it and writes it
// to a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAPRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAPRB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 1, 0, 31, 1, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDAPRB")
}

// LDAPRH instruction have one single form across one single category:
//
// 1. Load-Acquire RCpc Register Halfword
//
//    LDAPRH  <Wt>, [<Xn|SP> {,#0}]
//
// Load-Acquire RCpc Register Halfword derives an address from a base register
// value, loads a halfword from the derived address in memory, zero-extends it and
// writes it to a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAPRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAPRH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 1, 0, 31, 1, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDAPRH")
}

// LDAPUR instruction have 7 forms across 2 categories:
//
// 1. Load-Acquire RCpc SIMD&FP Register (unscaled offset)
//
//    LDAPUR  <Bt>, [<Xn|SP>{, #<simm>}]
//    LDAPUR  <Dt>, [<Xn|SP>{, #<simm>}]
//    LDAPUR  <Ht>, [<Xn|SP>{, #<simm>}]
//    LDAPUR  <Qt>, [<Xn|SP>{, #<simm>}]
//    LDAPUR  <St>, [<Xn|SP>{, #<simm>}]
//
// Load-Acquire RCpc SIMD&FP Register (unscaled offset). This instruction loads a
// SIMD&FP register from memory. The address that is used for the load is
// calculated from a base register value and an optional immediate offset.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Load-Acquire RCpc Register (unscaled)
//
//    LDAPUR  <Wt>, [<Xn|SP>{, #<simm>}]
//    LDAPUR  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load-Acquire RCpc Register (unscaled) calculates an address from a base register
// and an immediate offset, loads a 32-bit word or 64-bit doubleword from memory,
// zero-extends it, and writes it to a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAPUR(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAPUR", 2, asm.Operands { v0, v1 })
    // LDAPUR  <Bt>, [<Xn|SP>{, #<simm>}]
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(0, 1, sa_simm, sa_xn_sp, sa_bt))
    }
    // LDAPUR  <Dt>, [<Xn|SP>{, #<simm>}]
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(3, 1, sa_simm, sa_xn_sp, sa_dt))
    }
    // LDAPUR  <Ht>, [<Xn|SP>{, #<simm>}]
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(1, 1, sa_simm, sa_xn_sp, sa_ht))
    }
    // LDAPUR  <Qt>, [<Xn|SP>{, #<simm>}]
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(0, 3, sa_simm, sa_xn_sp, sa_qt))
    }
    // LDAPUR  <St>, [<Xn|SP>{, #<simm>}]
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(2, 1, sa_simm, sa_xn_sp, sa_st))
    }
    // LDAPUR  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(2, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDAPUR  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(3, 1, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDAPUR")
}

// LDAPURB instruction have one single form across one single category:
//
// 1. Load-Acquire RCpc Register Byte (unscaled)
//
//    LDAPURB  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Load-Acquire RCpc Register Byte (unscaled) calculates an address from a base
// register and an immediate offset, loads a byte from memory, zero-extends it, and
// writes it to a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAPURB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAPURB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDAPURB")
}

// LDAPURH instruction have one single form across one single category:
//
// 1. Load-Acquire RCpc Register Halfword (unscaled)
//
//    LDAPURH  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Load-Acquire RCpc Register Halfword (unscaled) calculates an address from a base
// register and an immediate offset, loads a halfword from memory, zero-extends it,
// and writes it to a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAPURH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAPURH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(1, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDAPURH")
}

// LDAPURSB instruction have 2 forms across one single category:
//
// 1. Load-Acquire RCpc Register Signed Byte (unscaled)
//
//    LDAPURSB  <Wt>, [<Xn|SP>{, #<simm>}]
//    LDAPURSB  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load-Acquire RCpc Register Signed Byte (unscaled) calculates an address from a
// base register and an immediate offset, loads a signed byte from memory, sign-
// extends it, and writes it to a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAPURSB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAPURSB", 2, asm.Operands { v0, v1 })
    // LDAPURSB  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(0, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDAPURSB  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDAPURSB")
}

// LDAPURSH instruction have 2 forms across one single category:
//
// 1. Load-Acquire RCpc Register Signed Halfword (unscaled)
//
//    LDAPURSH  <Wt>, [<Xn|SP>{, #<simm>}]
//    LDAPURSH  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load-Acquire RCpc Register Signed Halfword (unscaled) calculates an address from
// a base register and an immediate offset, loads a signed halfword from memory,
// sign-extends it, and writes it to a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAPURSH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAPURSH", 2, asm.Operands { v0, v1 })
    // LDAPURSH  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(1, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDAPURSH  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(1, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDAPURSH")
}

// LDAPURSW instruction have one single form across one single category:
//
// 1. Load-Acquire RCpc Register Signed Word (unscaled)
//
//    LDAPURSW  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load-Acquire RCpc Register Signed Word (unscaled) calculates an address from a
// base register and an immediate offset, loads a signed word from memory, sign-
// extends it, and writes it to a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release , except that:
//
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// This difference in memory ordering is not described in the pseudocode.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAPURSW(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAPURSW", 2, asm.Operands { v0, v1 })
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(2, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDAPURSW")
}

// LDAR instruction have 2 forms across one single category:
//
// 1. Load-Acquire Register
//
//    LDAR  <Wt>, [<Xn|SP>{,#0}]
//    LDAR  <Xt>, [<Xn|SP>{,#0}]
//
// Load-Acquire Register derives an address from a base register value, loads a
// 32-bit word or 64-bit doubleword from memory, and writes it to a register. The
// instruction also has memory ordering semantics as described in Load-Acquire,
// Store-Release . For information about memory accesses, see Load/Store addressing
// modes .
//
// NOTE: 
//     For this instruction, if the destination is WZR/XZR, it is impossible
//     for software to observe the presence of the acquire semantic other than
//     its effect on the arrival at endpoints.
//
func (self *Program) LDAR(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAR", 2, asm.Operands { v0, v1 })
    // LDAR  <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(2, 1, 31, 1, 31, sa_xn_sp, sa_wt))
    }
    // LDAR  <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(3, 1, 31, 1, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDAR")
}

// LDARB instruction have one single form across one single category:
//
// 1. Load-Acquire Register Byte
//
//    LDARB  <Wt>, [<Xn|SP>{,#0}]
//
// Load-Acquire Register Byte derives an address from a base register value, loads
// a byte from memory, zero-extends it and writes it to a register. The instruction
// also has memory ordering semantics as described in Load-Acquire, Store-Release .
// For information about memory accesses, see Load/Store addressing modes .
//
// NOTE: 
//     For this instruction, if the destination is WZR/XZR, it is impossible
//     for software to observe the presence of the acquire semantic other than
//     its effect on the arrival at endpoints.
//
func (self *Program) LDARB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDARB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(0, 1, 31, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDARB")
}

// LDARH instruction have one single form across one single category:
//
// 1. Load-Acquire Register Halfword
//
//    LDARH  <Wt>, [<Xn|SP>{,#0}]
//
// Load-Acquire Register Halfword derives an address from a base register value,
// loads a halfword from memory, zero-extends it, and writes it to a register. The
// instruction also has memory ordering semantics as described in Load-Acquire,
// Store-Release . For information about memory accesses, see Load/Store addressing
// modes .
//
// NOTE: 
//     For this instruction, if the destination is WZR/XZR, it is impossible
//     for software to observe the presence of the acquire semantic other than
//     its effect on the arrival at endpoints.
//
func (self *Program) LDARH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDARH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(1, 1, 31, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDARH")
}

// LDAXP instruction have 2 forms across one single category:
//
// 1. Load-Acquire Exclusive Pair of Registers
//
//    LDAXP  <Wt1>, <Wt2>, [<Xn|SP>{,#0}]
//    LDAXP  <Xt1>, <Xt2>, [<Xn|SP>{,#0}]
//
// Load-Acquire Exclusive Pair of Registers derives an address from a base register
// value, loads two 32-bit words or two 64-bit doublewords from memory, and writes
// them to two registers. For information on single-copy atomicity and alignment
// requirements, see Requirements for single-copy atomicity and Alignment of data
// accesses . The PE marks the physical address being accessed as an exclusive
// access. This exclusive access mark is checked by Store Exclusive instructions.
// See Synchronization and semaphores . The instruction also has memory ordering
// semantics, as described in Load-Acquire, Store-Release . For information about
// memory accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDAXP .
//
func (self *Program) LDAXP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDAXP", 3, asm.Operands { v0, v1, v2 })
    // LDAXP  <Wt1>, <Wt2>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclp(0, 1, 31, 1, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // LDAXP  <Xt1>, <Xt2>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclp(1, 1, 31, 1, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDAXP")
}

// LDAXR instruction have 2 forms across one single category:
//
// 1. Load-Acquire Exclusive Register
//
//    LDAXR  <Wt>, [<Xn|SP>{,#0}]
//    LDAXR  <Xt>, [<Xn|SP>{,#0}]
//
// Load-Acquire Exclusive Register derives an address from a base register value,
// loads a 32-bit word or 64-bit doubleword from memory, and writes it to a
// register. The memory access is atomic. The PE marks the physical address being
// accessed as an exclusive access. This exclusive access mark is checked by Store
// Exclusive instructions. See Synchronization and semaphores . The instruction
// also has memory ordering semantics as described in Load-Acquire, Store-Release .
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAXR(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAXR", 2, asm.Operands { v0, v1 })
    // LDAXR  <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstexclr(2, 1, 31, 1, 31, sa_xn_sp, sa_wt))
    }
    // LDAXR  <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstexclr(3, 1, 31, 1, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDAXR")
}

// LDAXRB instruction have one single form across one single category:
//
// 1. Load-Acquire Exclusive Register Byte
//
//    LDAXRB  <Wt>, [<Xn|SP>{,#0}]
//
// Load-Acquire Exclusive Register Byte derives an address from a base register
// value, loads a byte from memory, zero-extends it and writes it to a register.
// The memory access is atomic. The PE marks the physical address being accessed as
// an exclusive access. This exclusive access mark is checked by Store Exclusive
// instructions. See Synchronization and semaphores . The instruction also has
// memory ordering semantics as described in Load-Acquire, Store-Release . For
// information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAXRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAXRB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstexclr(0, 1, 31, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDAXRB")
}

// LDAXRH instruction have one single form across one single category:
//
// 1. Load-Acquire Exclusive Register Halfword
//
//    LDAXRH  <Wt>, [<Xn|SP>{,#0}]
//
// Load-Acquire Exclusive Register Halfword derives an address from a base register
// value, loads a halfword from memory, zero-extends it and writes it to a
// register. The memory access is atomic. The PE marks the physical address being
// accessed as an exclusive access. This exclusive access mark is checked by Store
// Exclusive instructions. See Synchronization and semaphores . The instruction
// also has memory ordering semantics as described in Load-Acquire, Store-Release .
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDAXRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDAXRH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstexclr(1, 1, 31, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDAXRH")
}

// LDCLR instruction have 2 forms across one single category:
//
// 1. Atomic bit clear on word or doubleword in memory
//
//    LDCLR  <Ws>, <Wt>, [<Xn|SP>]
//    LDCLR  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic bit clear on word or doubleword in memory atomically loads a 32-bit word
// or 64-bit doubleword from memory, performs a bitwise AND with the complement of
// the value held in a register on it, and stores the result back to memory. The
// value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDCLRA and
//       LDCLRAL load from memory with acquire semantics.
//     * LDCLRL and LDCLRAL store to memory with release semantics.
//     * LDCLR has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLR", 3, asm.Operands { v0, v1, v2 })
    // LDCLR  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    // LDCLR  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 1, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLR")
}

// LDCLRA instruction have 2 forms across one single category:
//
// 1. Atomic bit clear on word or doubleword in memory
//
//    LDCLRA  <Ws>, <Wt>, [<Xn|SP>]
//    LDCLRA  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic bit clear on word or doubleword in memory atomically loads a 32-bit word
// or 64-bit doubleword from memory, performs a bitwise AND with the complement of
// the value held in a register on it, and stores the result back to memory. The
// value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDCLRA and
//       LDCLRAL load from memory with acquire semantics.
//     * LDCLRL and LDCLRAL store to memory with release semantics.
//     * LDCLR has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRA", 3, asm.Operands { v0, v1, v2 })
    // LDCLRA  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 0, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    // LDCLRA  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 0, sa_xs, 0, 1, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRA")
}

// LDCLRAB instruction have one single form across one single category:
//
// 1. Atomic bit clear on byte in memory
//
//    LDCLRAB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit clear on byte in memory atomically loads an 8-bit byte from memory,
// performs a bitwise AND with the complement of the value held in a register on
// it, and stores the result back to memory. The value initially loaded from memory
// is returned in the destination register.
//
//     * If the destination register is not WZR , LDCLRAB and LDCLRALB load
//       from memory with acquire semantics.
//     * LDCLRLB and LDCLRALB store to memory with release semantics.
//     * LDCLRB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRAB")
}

// LDCLRAH instruction have one single form across one single category:
//
// 1. Atomic bit clear on halfword in memory
//
//    LDCLRAH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit clear on halfword in memory atomically loads a 16-bit halfword from
// memory, performs a bitwise AND with the complement of the value held in a
// register on it, and stores the result back to memory. The value initially loaded
// from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDCLRAH and LDCLRALH load
//       from memory with acquire semantics.
//     * LDCLRLH and LDCLRALH store to memory with release semantics.
//     * LDCLRH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRAH")
}

// LDCLRAL instruction have 2 forms across one single category:
//
// 1. Atomic bit clear on word or doubleword in memory
//
//    LDCLRAL  <Ws>, <Wt>, [<Xn|SP>]
//    LDCLRAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic bit clear on word or doubleword in memory atomically loads a 32-bit word
// or 64-bit doubleword from memory, performs a bitwise AND with the complement of
// the value held in a register on it, and stores the result back to memory. The
// value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDCLRA and
//       LDCLRAL load from memory with acquire semantics.
//     * LDCLRL and LDCLRAL store to memory with release semantics.
//     * LDCLR has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRAL", 3, asm.Operands { v0, v1, v2 })
    // LDCLRAL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 1, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    // LDCLRAL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 1, sa_xs, 0, 1, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRAL")
}

// LDCLRALB instruction have one single form across one single category:
//
// 1. Atomic bit clear on byte in memory
//
//    LDCLRALB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit clear on byte in memory atomically loads an 8-bit byte from memory,
// performs a bitwise AND with the complement of the value held in a register on
// it, and stores the result back to memory. The value initially loaded from memory
// is returned in the destination register.
//
//     * If the destination register is not WZR , LDCLRAB and LDCLRALB load
//       from memory with acquire semantics.
//     * LDCLRLB and LDCLRALB store to memory with release semantics.
//     * LDCLRB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRALB")
}

// LDCLRALH instruction have one single form across one single category:
//
// 1. Atomic bit clear on halfword in memory
//
//    LDCLRALH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit clear on halfword in memory atomically loads a 16-bit halfword from
// memory, performs a bitwise AND with the complement of the value held in a
// register on it, and stores the result back to memory. The value initially loaded
// from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDCLRAH and LDCLRALH load
//       from memory with acquire semantics.
//     * LDCLRLH and LDCLRALH store to memory with release semantics.
//     * LDCLRH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRALH")
}

// LDCLRB instruction have one single form across one single category:
//
// 1. Atomic bit clear on byte in memory
//
//    LDCLRB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit clear on byte in memory atomically loads an 8-bit byte from memory,
// performs a bitwise AND with the complement of the value held in a register on
// it, and stores the result back to memory. The value initially loaded from memory
// is returned in the destination register.
//
//     * If the destination register is not WZR , LDCLRAB and LDCLRALB load
//       from memory with acquire semantics.
//     * LDCLRLB and LDCLRALB store to memory with release semantics.
//     * LDCLRB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRB")
}

// LDCLRH instruction have one single form across one single category:
//
// 1. Atomic bit clear on halfword in memory
//
//    LDCLRH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit clear on halfword in memory atomically loads a 16-bit halfword from
// memory, performs a bitwise AND with the complement of the value held in a
// register on it, and stores the result back to memory. The value initially loaded
// from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDCLRAH and LDCLRALH load
//       from memory with acquire semantics.
//     * LDCLRLH and LDCLRALH store to memory with release semantics.
//     * LDCLRH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRH")
}

// LDCLRL instruction have 2 forms across one single category:
//
// 1. Atomic bit clear on word or doubleword in memory
//
//    LDCLRL  <Ws>, <Wt>, [<Xn|SP>]
//    LDCLRL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic bit clear on word or doubleword in memory atomically loads a 32-bit word
// or 64-bit doubleword from memory, performs a bitwise AND with the complement of
// the value held in a register on it, and stores the result back to memory. The
// value initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDCLRA and
//       LDCLRAL load from memory with acquire semantics.
//     * LDCLRL and LDCLRAL store to memory with release semantics.
//     * LDCLR has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRL", 3, asm.Operands { v0, v1, v2 })
    // LDCLRL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    // LDCLRL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 1, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRL")
}

// LDCLRLB instruction have one single form across one single category:
//
// 1. Atomic bit clear on byte in memory
//
//    LDCLRLB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit clear on byte in memory atomically loads an 8-bit byte from memory,
// performs a bitwise AND with the complement of the value held in a register on
// it, and stores the result back to memory. The value initially loaded from memory
// is returned in the destination register.
//
//     * If the destination register is not WZR , LDCLRAB and LDCLRALB load
//       from memory with acquire semantics.
//     * LDCLRLB and LDCLRALB store to memory with release semantics.
//     * LDCLRB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRLB")
}

// LDCLRLH instruction have one single form across one single category:
//
// 1. Atomic bit clear on halfword in memory
//
//    LDCLRLH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit clear on halfword in memory atomically loads a 16-bit halfword from
// memory, performs a bitwise AND with the complement of the value held in a
// register on it, and stores the result back to memory. The value initially loaded
// from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDCLRAH and LDCLRALH load
//       from memory with acquire semantics.
//     * LDCLRLH and LDCLRALH store to memory with release semantics.
//     * LDCLRH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDCLRLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 1, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRLH")
}

// LDCLRP instruction have one single form across one single category:
//
// 1. Atomic bit clear on quadword in memory
//
//    LDCLRP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Atomic bit clear on quadword in memory atomically loads a 128-bit quadword from
// memory, performs a bitwise AND with the complement of the value held in a pair
// of registers on it, and stores the result back to memory. The value initially
// loaded from memory is returned in the same pair of registers.
//
//     * LDCLRPA and LDCLRPAL load from memory with acquire semantics.
//     * LDCLRPL and LDCLRPAL store to memory with release semantics.
//     * LDCLRP has neither acquire nor release semantics.
//
func (self *Program) LDCLRP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 0, sa_xt2, 0, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRP")
}

// LDCLRPA instruction have one single form across one single category:
//
// 1. Atomic bit clear on quadword in memory
//
//    LDCLRPA  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Atomic bit clear on quadword in memory atomically loads a 128-bit quadword from
// memory, performs a bitwise AND with the complement of the value held in a pair
// of registers on it, and stores the result back to memory. The value initially
// loaded from memory is returned in the same pair of registers.
//
//     * LDCLRPA and LDCLRPAL load from memory with acquire semantics.
//     * LDCLRPL and LDCLRPAL store to memory with release semantics.
//     * LDCLRP has neither acquire nor release semantics.
//
func (self *Program) LDCLRPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 0, sa_xt2, 0, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRPA")
}

// LDCLRPAL instruction have one single form across one single category:
//
// 1. Atomic bit clear on quadword in memory
//
//    LDCLRPAL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Atomic bit clear on quadword in memory atomically loads a 128-bit quadword from
// memory, performs a bitwise AND with the complement of the value held in a pair
// of registers on it, and stores the result back to memory. The value initially
// loaded from memory is returned in the same pair of registers.
//
//     * LDCLRPA and LDCLRPAL load from memory with acquire semantics.
//     * LDCLRPL and LDCLRPAL store to memory with release semantics.
//     * LDCLRP has neither acquire nor release semantics.
//
func (self *Program) LDCLRPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 1, sa_xt2, 0, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRPAL")
}

// LDCLRPL instruction have one single form across one single category:
//
// 1. Atomic bit clear on quadword in memory
//
//    LDCLRPL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Atomic bit clear on quadword in memory atomically loads a 128-bit quadword from
// memory, performs a bitwise AND with the complement of the value held in a pair
// of registers on it, and stores the result back to memory. The value initially
// loaded from memory is returned in the same pair of registers.
//
//     * LDCLRPA and LDCLRPAL load from memory with acquire semantics.
//     * LDCLRPL and LDCLRPAL store to memory with release semantics.
//     * LDCLRP has neither acquire nor release semantics.
//
func (self *Program) LDCLRPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDCLRPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 1, sa_xt2, 0, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDCLRPL")
}

// LDEOR instruction have 2 forms across one single category:
//
// 1. Atomic Exclusive-OR on word or doubleword in memory
//
//    LDEOR  <Ws>, <Wt>, [<Xn|SP>]
//    LDEOR  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, performs an exclusive-OR with the value
// held in a register on it, and stores the result back to memory. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDEORA and
//       LDEORAL load from memory with acquire semantics.
//     * LDEORL and LDEORAL store to memory with release semantics.
//     * LDEOR has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEOR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEOR", 3, asm.Operands { v0, v1, v2 })
    // LDEOR  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    // LDEOR  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 2, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDEOR")
}

// LDEORA instruction have 2 forms across one single category:
//
// 1. Atomic Exclusive-OR on word or doubleword in memory
//
//    LDEORA  <Ws>, <Wt>, [<Xn|SP>]
//    LDEORA  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, performs an exclusive-OR with the value
// held in a register on it, and stores the result back to memory. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDEORA and
//       LDEORAL load from memory with acquire semantics.
//     * LDEORL and LDEORAL store to memory with release semantics.
//     * LDEOR has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORA", 3, asm.Operands { v0, v1, v2 })
    // LDEORA  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 0, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    // LDEORA  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 0, sa_xs, 0, 2, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORA")
}

// LDEORAB instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on byte in memory
//
//    LDEORAB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on byte in memory atomically loads an 8-bit byte from
// memory, performs an exclusive-OR with the value held in a register on it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDEORAB and LDEORALB load
//       from memory with acquire semantics.
//     * LDEORLB and LDEORALB store to memory with release semantics.
//     * LDEORB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORAB")
}

// LDEORAH instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on halfword in memory
//
//    LDEORAH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on halfword in memory atomically loads a 16-bit halfword
// from memory, performs an exclusive-OR with the value held in a register on it,
// and stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDEORAH and LDEORALH load
//       from memory with acquire semantics.
//     * LDEORLH and LDEORALH store to memory with release semantics.
//     * LDEORH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORAH")
}

// LDEORAL instruction have 2 forms across one single category:
//
// 1. Atomic Exclusive-OR on word or doubleword in memory
//
//    LDEORAL  <Ws>, <Wt>, [<Xn|SP>]
//    LDEORAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, performs an exclusive-OR with the value
// held in a register on it, and stores the result back to memory. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDEORA and
//       LDEORAL load from memory with acquire semantics.
//     * LDEORL and LDEORAL store to memory with release semantics.
//     * LDEOR has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORAL", 3, asm.Operands { v0, v1, v2 })
    // LDEORAL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 1, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    // LDEORAL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 1, sa_xs, 0, 2, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORAL")
}

// LDEORALB instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on byte in memory
//
//    LDEORALB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on byte in memory atomically loads an 8-bit byte from
// memory, performs an exclusive-OR with the value held in a register on it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDEORAB and LDEORALB load
//       from memory with acquire semantics.
//     * LDEORLB and LDEORALB store to memory with release semantics.
//     * LDEORB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORALB")
}

// LDEORALH instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on halfword in memory
//
//    LDEORALH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on halfword in memory atomically loads a 16-bit halfword
// from memory, performs an exclusive-OR with the value held in a register on it,
// and stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDEORAH and LDEORALH load
//       from memory with acquire semantics.
//     * LDEORLH and LDEORALH store to memory with release semantics.
//     * LDEORH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORALH")
}

// LDEORB instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on byte in memory
//
//    LDEORB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on byte in memory atomically loads an 8-bit byte from
// memory, performs an exclusive-OR with the value held in a register on it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDEORAB and LDEORALB load
//       from memory with acquire semantics.
//     * LDEORLB and LDEORALB store to memory with release semantics.
//     * LDEORB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORB")
}

// LDEORH instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on halfword in memory
//
//    LDEORH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on halfword in memory atomically loads a 16-bit halfword
// from memory, performs an exclusive-OR with the value held in a register on it,
// and stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDEORAH and LDEORALH load
//       from memory with acquire semantics.
//     * LDEORLH and LDEORALH store to memory with release semantics.
//     * LDEORH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORH")
}

// LDEORL instruction have 2 forms across one single category:
//
// 1. Atomic Exclusive-OR on word or doubleword in memory
//
//    LDEORL  <Ws>, <Wt>, [<Xn|SP>]
//    LDEORL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, performs an exclusive-OR with the value
// held in a register on it, and stores the result back to memory. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDEORA and
//       LDEORAL load from memory with acquire semantics.
//     * LDEORL and LDEORAL store to memory with release semantics.
//     * LDEOR has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORL", 3, asm.Operands { v0, v1, v2 })
    // LDEORL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    // LDEORL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 2, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORL")
}

// LDEORLB instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on byte in memory
//
//    LDEORLB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on byte in memory atomically loads an 8-bit byte from
// memory, performs an exclusive-OR with the value held in a register on it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDEORAB and LDEORALB load
//       from memory with acquire semantics.
//     * LDEORLB and LDEORALB store to memory with release semantics.
//     * LDEORB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORLB")
}

// LDEORLH instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on halfword in memory
//
//    LDEORLH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic Exclusive-OR on halfword in memory atomically loads a 16-bit halfword
// from memory, performs an exclusive-OR with the value held in a register on it,
// and stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDEORAH and LDEORALH load
//       from memory with acquire semantics.
//     * LDEORLH and LDEORALH store to memory with release semantics.
//     * LDEORH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDEORLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDEORLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 2, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDEORLH")
}

// LDG instruction have one single form across one single category:
//
// 1. Load Allocation Tag
//
//    LDG  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Allocation Tag loads an Allocation Tag from a memory address, generates a
// Logical Address Tag from the Allocation Tag and merges it into the destination
// register. The address used for the load is calculated from the base register and
// an immediate signed offset scaled by the Tag granule.
//
func (self *Program) LDG(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDG", 2, asm.Operands { v0, v1 })
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt
        return p.setins(ldsttags(1, sa_simm, 0, Rn, Rt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDG")
}

// LDGM instruction have one single form across one single category:
//
// 1. Load Tag Multiple
//
//    LDGM  <Xt>, [<Xn|SP>]
//
// Load Tag Multiple reads a naturally aligned block of N Allocation Tags, where
// the size of N is identified in GMID_EL1.BS, and writes the Allocation Tag read
// from address A to the destination register at 4*A<7:4>+3:4*A<7:4>. Bits of the
// destination register not written with an Allocation Tag are set to 0.
//
// This instruction is undefined at EL0.
//
// This instruction generates an Unchecked access.
//
func (self *Program) LDGM(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDGM", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_MTE2)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt
        return p.setins(ldsttags(3, 0, 0, Rn, Rt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDGM")
}

// LDIAPP instruction have 4 forms across one single category:
//
// 1. Load-Acquire RCpc ordered Pair of registers
//
//    LDIAPP  <Wt1>, <Wt2>, [<Xn|SP>], #8
//    LDIAPP  <Wt1>, <Wt2>, [<Xn|SP>]
//    LDIAPP  <Xt1>, <Xt2>, [<Xn|SP>], #16
//    LDIAPP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Load-Acquire RCpc ordered Pair of registers calculates an address from a base
// register value and an optional offset, loads two 32-bit words or two 64-bit
// doublewords from memory, and writes them to two registers. For information on
// single-copy atomicity and alignment requirements, see Requirements for single-
// copy atomicity and Alignment of data accesses . The instruction also has memory
// ordering semantics, as described in Load-Acquire, Load-AcquirePC, and Store-
// Release , except that:
//
//     * The Memory effects associated with Xt1/Wt1 are Ordered-before the
//       Memory effects associated with Xt2/Wt2.
//     * There is no ordering requirement, separate from the requirements of a
//       Load-AcquirePC or a Store-Release, created by having a Store-Release
//       followed by a Load-AcquirePC instruction.
//     * The reading of a value written by a Store-Release by a Load-AcquirePC
//       instruction by the same observer does not make the write of the Store-
//       Release globally observed.
//
// For information about memory accesses, see Load/Store addressing modes .
//
// LDIAPP has the same constrained unpredictable behavior as LDP . For information
// about this constrained unpredictable behavior, see Architectural Constraints on
// UNPREDICTABLE behaviors , and particularly LDP .
//
func (self *Program) LDIAPP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDIAPP", 3, asm.Operands { v0, v1, v2 })
    // LDIAPP  <Wt1>, <Wt2>, [<Xn|SP>], #8
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 8 &&
       mext(v2) == PostIndex {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldiappstilp(2, 1, sa_wt2, 0, sa_xn_sp, sa_wt1))
    }
    // LDIAPP  <Wt1>, <Wt2>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldiappstilp(2, 1, sa_wt2, 1, sa_xn_sp, sa_wt1))
    }
    // LDIAPP  <Xt1>, <Xt2>, [<Xn|SP>], #16
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 16 &&
       mext(v2) == PostIndex {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldiappstilp(3, 1, sa_xt2, 0, sa_xn_sp, sa_xt1))
    }
    // LDIAPP  <Xt1>, <Xt2>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldiappstilp(3, 1, sa_xt2, 1, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDIAPP")
}

// LDLAR instruction have 2 forms across one single category:
//
// 1. Load LOAcquire Register
//
//    LDLAR  <Wt>, [<Xn|SP>{,#0}]
//    LDLAR  <Xt>, [<Xn|SP>{,#0}]
//
// Load LOAcquire Register loads a 32-bit word or 64-bit doubleword from memory,
// and writes it to a register. The instruction also has memory ordering semantics
// as described in Load LOAcquire, Store LORelease . For information about memory
// accesses, see Load/Store addressing modes .
//
// NOTE: 
//     For this instruction, if the destination is WZR/XZR, it is impossible
//     for software to observe the presence of the acquire semantic other than
//     its effect on the arrival at endpoints.
//
func (self *Program) LDLAR(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDLAR", 2, asm.Operands { v0, v1 })
    // LDLAR  <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LOR)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(2, 1, 31, 0, 31, sa_xn_sp, sa_wt))
    }
    // LDLAR  <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LOR)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(3, 1, 31, 0, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDLAR")
}

// LDLARB instruction have one single form across one single category:
//
// 1. Load LOAcquire Register Byte
//
//    LDLARB  <Wt>, [<Xn|SP>{,#0}]
//
// Load LOAcquire Register Byte loads a byte from memory, zero-extends it and
// writes it to a register. The instruction also has memory ordering semantics as
// described in Load LOAcquire, Store LORelease . For information about memory
// accesses, see Load/Store addressing modes .
//
// NOTE: 
//     For this instruction, if the destination is WZR/XZR, it is impossible
//     for software to observe the presence of the acquire semantic other than
//     its effect on the arrival at endpoints.
//
func (self *Program) LDLARB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDLARB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LOR)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(0, 1, 31, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDLARB")
}

// LDLARH instruction have one single form across one single category:
//
// 1. Load LOAcquire Register Halfword
//
//    LDLARH  <Wt>, [<Xn|SP>{,#0}]
//
// Load LOAcquire Register Halfword loads a halfword from memory, zero-extends it,
// and writes it to a register. The instruction also has memory ordering semantics
// as described in Load LOAcquire, Store LORelease . For information about memory
// accesses, see Load/Store addressing modes .
//
// NOTE: 
//     For this instruction, if the destination is WZR/XZR, it is impossible
//     for software to observe the presence of the acquire semantic other than
//     its effect on the arrival at endpoints.
//
func (self *Program) LDLARH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDLARH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LOR)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(1, 1, 31, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDLARH")
}

// LDNP instruction have 5 forms across 2 categories:
//
// 1. Load Pair of SIMD&FP registers, with Non-temporal hint
//
//    LDNP  <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]
//    LDNP  <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]
//    LDNP  <St1>, <St2>, [<Xn|SP>{, #<imm>}]
//
// Load Pair of SIMD&FP registers, with Non-temporal hint. This instruction loads a
// pair of SIMD&FP registers from memory, issuing a hint to the memory system that
// the access is non-temporal. The address that is used for the load is calculated
// from a base register value and an optional immediate offset.
//
// For information about non-temporal pair instructions, see Load/Store SIMD and
// Floating-point Non-temporal pair .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDNP (SIMD&FP) .
//
// 2. Load Pair of Registers, with non-temporal hint
//
//    LDNP  <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]
//    LDNP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
//
// Load Pair of Registers, with non-temporal hint, calculates an address from a
// base register value and an immediate offset, loads two 32-bit words or two
// 64-bit doublewords from memory, and writes them to two registers.
//
// For information about memory accesses, see Load/Store addressing modes . For
// information about Non-temporal pair instructions, see Load/Store Non-temporal
// pair .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDNP .
//
func (self *Program) LDNP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDNP", 3, asm.Operands { v0, v1, v2 })
    // LDNP  <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]
    if isDr(v0) &&
       isDr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_dt1 := uint32(v0.(asm.Register).ID())
        sa_dt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2) / 8)
        return p.setins(ldstnapair_offs(1, 1, 1, sa_imm, sa_dt2, sa_xn_sp, sa_dt1))
    }
    // LDNP  <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]
    if isQr(v0) &&
       isQr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_qt1 := uint32(v0.(asm.Register).ID())
        sa_qt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 16)
        return p.setins(ldstnapair_offs(2, 1, 1, sa_imm_1, sa_qt2, sa_xn_sp, sa_qt1))
    }
    // LDNP  <St1>, <St2>, [<Xn|SP>{, #<imm>}]
    if isSr(v0) &&
       isSr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_st1 := uint32(v0.(asm.Register).ID())
        sa_st2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_2 := uint32(moffs(v2) / 4)
        return p.setins(ldstnapair_offs(0, 1, 1, sa_imm_2, sa_st2, sa_xn_sp, sa_st1))
    }
    // LDNP  <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2) / 4)
        return p.setins(ldstnapair_offs(0, 0, 1, sa_imm, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // LDNP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 8)
        return p.setins(ldstnapair_offs(2, 0, 1, sa_imm_1, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDNP")
}

// LDP instruction have 15 forms across 2 categories:
//
// 1. Load Pair of SIMD&FP registers
//
//    LDP  <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]
//    LDP  <Dt1>, <Dt2>, [<Xn|SP>], #<imm>
//    LDP  <Dt1>, <Dt2>, [<Xn|SP>, #<imm>]!
//    LDP  <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]
//    LDP  <Qt1>, <Qt2>, [<Xn|SP>], #<imm>
//    LDP  <Qt1>, <Qt2>, [<Xn|SP>, #<imm>]!
//    LDP  <St1>, <St2>, [<Xn|SP>{, #<imm>}]
//    LDP  <St1>, <St2>, [<Xn|SP>], #<imm>
//    LDP  <St1>, <St2>, [<Xn|SP>, #<imm>]!
//
// Load Pair of SIMD&FP registers. This instruction loads a pair of SIMD&FP
// registers from memory. The address that is used for the load is calculated from
// a base register value and an optional immediate offset.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDP (SIMD&FP) .
//
// 2. Load Pair of Registers
//
//    LDP  <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]
//    LDP  <Wt1>, <Wt2>, [<Xn|SP>], #<imm>
//    LDP  <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!
//    LDP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
//    LDP  <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
//    LDP  <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
//
// Load Pair of Registers calculates an address from a base register value and an
// immediate offset, loads two 32-bit words or two 64-bit doublewords from memory,
// and writes them to two registers. For information about memory accesses, see
// Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDP .
//
func (self *Program) LDP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDP", 3, asm.Operands { v0, v1, v2 })
    // LDP  <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]
    if isDr(v0) &&
       isDr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_dt1 := uint32(v0.(asm.Register).ID())
        sa_dt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_off(1, 1, 1, sa_imm, sa_dt2, sa_xn_sp, sa_dt1))
    }
    // LDP  <Dt1>, <Dt2>, [<Xn|SP>], #<imm>
    if isDr(v0) &&
       isDr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == PostIndex {
        p.Domain = DomainFpSimd
        sa_dt1 := uint32(v0.(asm.Register).ID())
        sa_dt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_post(1, 1, 1, sa_imm_1, sa_dt2, sa_xn_sp, sa_dt1))
    }
    // LDP  <Dt1>, <Dt2>, [<Xn|SP>, #<imm>]!
    if isDr(v0) &&
       isDr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == PreIndex {
        p.Domain = DomainFpSimd
        sa_dt1 := uint32(v0.(asm.Register).ID())
        sa_dt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_pre(1, 1, 1, sa_imm_1, sa_dt2, sa_xn_sp, sa_dt1))
    }
    // LDP  <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]
    if isQr(v0) &&
       isQr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_qt1 := uint32(v0.(asm.Register).ID())
        sa_qt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_2 := uint32(moffs(v2) / 16)
        return p.setins(ldstpair_off(2, 1, 1, sa_imm_2, sa_qt2, sa_xn_sp, sa_qt1))
    }
    // LDP  <Qt1>, <Qt2>, [<Xn|SP>], #<imm>
    if isQr(v0) &&
       isQr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == PostIndex {
        p.Domain = DomainFpSimd
        sa_qt1 := uint32(v0.(asm.Register).ID())
        sa_qt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_3 := uint32(moffs(v2) / 16)
        return p.setins(ldstpair_post(2, 1, 1, sa_imm_3, sa_qt2, sa_xn_sp, sa_qt1))
    }
    // LDP  <Qt1>, <Qt2>, [<Xn|SP>, #<imm>]!
    if isQr(v0) &&
       isQr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == PreIndex {
        p.Domain = DomainFpSimd
        sa_qt1 := uint32(v0.(asm.Register).ID())
        sa_qt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_3 := uint32(moffs(v2) / 16)
        return p.setins(ldstpair_pre(2, 1, 1, sa_imm_3, sa_qt2, sa_xn_sp, sa_qt1))
    }
    // LDP  <St1>, <St2>, [<Xn|SP>{, #<imm>}]
    if isSr(v0) &&
       isSr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_st1 := uint32(v0.(asm.Register).ID())
        sa_st2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_4 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_off(0, 1, 1, sa_imm_4, sa_st2, sa_xn_sp, sa_st1))
    }
    // LDP  <St1>, <St2>, [<Xn|SP>], #<imm>
    if isSr(v0) &&
       isSr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PostIndex {
        p.Domain = DomainFpSimd
        sa_st1 := uint32(v0.(asm.Register).ID())
        sa_st2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_5 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_post(0, 1, 1, sa_imm_5, sa_st2, sa_xn_sp, sa_st1))
    }
    // LDP  <St1>, <St2>, [<Xn|SP>, #<imm>]!
    if isSr(v0) &&
       isSr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PreIndex {
        p.Domain = DomainFpSimd
        sa_st1 := uint32(v0.(asm.Register).ID())
        sa_st2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_5 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_pre(0, 1, 1, sa_imm_5, sa_st2, sa_xn_sp, sa_st1))
    }
    // LDP  <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_off(0, 0, 1, sa_imm, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // LDP  <Wt1>, <Wt2>, [<Xn|SP>], #<imm>
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_post(0, 0, 1, sa_imm_1, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // LDP  <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_pre(0, 0, 1, sa_imm_1, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // LDP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_2 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_off(2, 0, 1, sa_imm_2, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // LDP  <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_3 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_post(2, 0, 1, sa_imm_3, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // LDP  <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_3 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_pre(2, 0, 1, sa_imm_3, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDP")
}

// LDPSW instruction have 3 forms across one single category:
//
// 1. Load Pair of Registers Signed Word
//
//    LDPSW  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
//    LDPSW  <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
//    LDPSW  <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
//
// Load Pair of Registers Signed Word calculates an address from a base register
// value and an immediate offset, loads two 32-bit words from memory, sign-extends
// them, and writes them to two registers. For information about memory accesses,
// see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDPSW .
//
func (self *Program) LDPSW(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDPSW", 3, asm.Operands { v0, v1, v2 })
    // LDPSW  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_off(1, 0, 1, sa_imm, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // LDPSW  <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_post(1, 0, 1, sa_imm_1, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // LDPSW  <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_pre(1, 0, 1, sa_imm_1, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDPSW")
}

// LDR instruction have 39 forms across 6 categories:
//
// 1. Load SIMD&FP Register (immediate offset)
//
//    LDR  <Bt>, [<Xn|SP>], #<simm>
//    LDR  <Bt>, [<Xn|SP>, #<simm>]!
//    LDR  <Bt>, [<Xn|SP>{, #<pimm>}]
//    LDR  <Dt>, [<Xn|SP>], #<simm>
//    LDR  <Dt>, [<Xn|SP>, #<simm>]!
//    LDR  <Dt>, [<Xn|SP>{, #<pimm>}]
//    LDR  <Ht>, [<Xn|SP>], #<simm>
//    LDR  <Ht>, [<Xn|SP>, #<simm>]!
//    LDR  <Ht>, [<Xn|SP>{, #<pimm>}]
//    LDR  <Qt>, [<Xn|SP>], #<simm>
//    LDR  <Qt>, [<Xn|SP>, #<simm>]!
//    LDR  <Qt>, [<Xn|SP>{, #<pimm>}]
//    LDR  <St>, [<Xn|SP>], #<simm>
//    LDR  <St>, [<Xn|SP>, #<simm>]!
//    LDR  <St>, [<Xn|SP>{, #<pimm>}]
//
// Load SIMD&FP Register (immediate offset). This instruction loads an element from
// memory, and writes the result as a scalar to the SIMD&FP register. The address
// that is used for the load is calculated from a base register value, a signed
// immediate offset, and an optional offset that is a multiple of the element size.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Load Register (immediate)
//
//    LDR  <Wt>, [<Xn|SP>], #<simm>
//    LDR  <Wt>, [<Xn|SP>, #<simm>]!
//    LDR  <Wt>, [<Xn|SP>{, #<pimm>}]
//    LDR  <Xt>, [<Xn|SP>], #<simm>
//    LDR  <Xt>, [<Xn|SP>, #<simm>]!
//    LDR  <Xt>, [<Xn|SP>{, #<pimm>}]
//
// Load Register (immediate) loads a word or doubleword from memory and writes it
// to a register. The address that is used for the load is calculated from a base
// register and an immediate offset. For information about memory accesses, see
// Load/Store addressing modes . The Unsigned offset variant scales the immediate
// offset value by the size of the value accessed before adding it to the base
// register value.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDR (immediate) .
//
// 3. Load SIMD&FP Register (PC-relative literal)
//
//    LDR  <Dt>, <label>
//    LDR  <Dt>, .±<offs>
//    LDR  <Qt>, <label>
//    LDR  <Qt>, .±<offs>
//    LDR  <St>, <label>
//    LDR  <St>, .±<offs>
//
// Load SIMD&FP Register (PC-relative literal). This instruction loads a SIMD&FP
// register from memory. The address that is used for the load is calculated from
// the PC value and an immediate offset.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 4. Load Register (literal)
//
//    LDR  <Wt>, <label>
//    LDR  <Wt>, .±<offs>
//    LDR  <Xt>, <label>
//    LDR  <Xt>, .±<offs>
//
// Load Register (literal) calculates an address from the PC value and an immediate
// offset, loads a word from memory, and writes it to a register. For information
// about memory accesses, see Load/Store addressing modes .
//
// 5. Load SIMD&FP Register (register offset)
//
//    LDR  <Bt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
//    LDR  <Bt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
//    LDR  <Dt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//    LDR  <Ht>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//    LDR  <Qt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//    LDR  <St>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//
// Load SIMD&FP Register (register offset). This instruction loads a SIMD&FP
// register from memory. The address that is used for the load is calculated from a
// base register value and an offset register value. The offset can be optionally
// shifted and extended.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 6. Load Register (register)
//
//    LDR  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//    LDR  <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//
// Load Register (register) calculates an address from a base register value and an
// offset register value, loads a word from memory, and writes it to a register.
// The offset register value can optionally be shifted and extended. For
// information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDR(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDR", 2, asm.Operands { v0, v1 })
    // LDR  <Bt>, [<Xn|SP>], #<simm>
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(0, 1, 1, sa_simm, sa_xn_sp, sa_bt))
    }
    // LDR  <Bt>, [<Xn|SP>, #<simm>]!
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(0, 1, 1, sa_simm, sa_xn_sp, sa_bt))
    }
    // LDR  <Bt>, [<Xn|SP>{, #<pimm>}]
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 4095) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1))
        return p.setins(ldst_pos(0, 1, 1, sa_pimm, sa_xn_sp, sa_bt))
    }
    // LDR  <Dt>, [<Xn|SP>], #<simm>
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(3, 1, 1, sa_simm, sa_xn_sp, sa_dt))
    }
    // LDR  <Dt>, [<Xn|SP>, #<simm>]!
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(3, 1, 1, sa_simm, sa_xn_sp, sa_dt))
    }
    // LDR  <Dt>, [<Xn|SP>{, #<pimm>}]
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 32760) &&
       isMultipleOf(moffs(v1), 8) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_1 := uint32(moffs(v1) / 8)
        return p.setins(ldst_pos(3, 1, 1, sa_pimm_1, sa_xn_sp, sa_dt))
    }
    // LDR  <Ht>, [<Xn|SP>], #<simm>
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(1, 1, 1, sa_simm, sa_xn_sp, sa_ht))
    }
    // LDR  <Ht>, [<Xn|SP>, #<simm>]!
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(1, 1, 1, sa_simm, sa_xn_sp, sa_ht))
    }
    // LDR  <Ht>, [<Xn|SP>{, #<pimm>}]
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 8190) &&
       isMultipleOf(moffs(v1), 2) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_2 := uint32(moffs(v1) / 2)
        return p.setins(ldst_pos(1, 1, 1, sa_pimm_2, sa_xn_sp, sa_ht))
    }
    // LDR  <Qt>, [<Xn|SP>], #<simm>
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(0, 1, 3, sa_simm, sa_xn_sp, sa_qt))
    }
    // LDR  <Qt>, [<Xn|SP>, #<simm>]!
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(0, 1, 3, sa_simm, sa_xn_sp, sa_qt))
    }
    // LDR  <Qt>, [<Xn|SP>{, #<pimm>}]
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 65520) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_3 := uint32(moffs(v1) / 16)
        return p.setins(ldst_pos(0, 1, 3, sa_pimm_3, sa_xn_sp, sa_qt))
    }
    // LDR  <St>, [<Xn|SP>], #<simm>
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(2, 1, 1, sa_simm, sa_xn_sp, sa_st))
    }
    // LDR  <St>, [<Xn|SP>, #<simm>]!
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(2, 1, 1, sa_simm, sa_xn_sp, sa_st))
    }
    // LDR  <St>, [<Xn|SP>{, #<pimm>}]
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 16380) &&
       isMultipleOf(moffs(v1), 4) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_4 := uint32(moffs(v1) / 4)
        return p.setins(ldst_pos(2, 1, 1, sa_pimm_4, sa_xn_sp, sa_st))
    }
    // LDR  <Wt>, [<Xn|SP>], #<simm>
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(2, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDR  <Wt>, [<Xn|SP>, #<simm>]!
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(2, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDR  <Wt>, [<Xn|SP>{, #<pimm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 16380) &&
       isMultipleOf(moffs(v1), 4) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1) / 4)
        return p.setins(ldst_pos(2, 0, 1, sa_pimm, sa_xn_sp, sa_wt))
    }
    // LDR  <Xt>, [<Xn|SP>], #<simm>
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(3, 0, 1, sa_simm, sa_xn_sp, sa_xt))
    }
    // LDR  <Xt>, [<Xn|SP>, #<simm>]!
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(3, 0, 1, sa_simm, sa_xn_sp, sa_xt))
    }
    // LDR  <Xt>, [<Xn|SP>{, #<pimm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 32760) &&
       isMultipleOf(moffs(v1), 8) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_1 := uint32(moffs(v1) / 8)
        return p.setins(ldst_pos(3, 0, 1, sa_pimm_1, sa_xn_sp, sa_xt))
    }
    // LDR  <Dt>, <label>
    if isDr(v0) && isLabel(v1) {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return loadlit(1, 1, pcrel19(sa_label, pc), sa_dt)
        })
    }
    // LDR  <Dt>, .±<offs>
    if isDr(v0) && isPCrel(v1) {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(loadlit(1, 1, rel19(ra_pcrel), sa_dt))
    }
    // LDR  <Qt>, <label>
    if isQr(v0) && isLabel(v1) {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return loadlit(2, 1, pcrel19(sa_label, pc), sa_qt)
        })
    }
    // LDR  <Qt>, .±<offs>
    if isQr(v0) && isPCrel(v1) {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(loadlit(2, 1, rel19(ra_pcrel), sa_qt))
    }
    // LDR  <St>, <label>
    if isSr(v0) && isLabel(v1) {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return loadlit(0, 1, pcrel19(sa_label, pc), sa_st)
        })
    }
    // LDR  <St>, .±<offs>
    if isSr(v0) && isPCrel(v1) {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(loadlit(0, 1, rel19(ra_pcrel), sa_st))
    }
    // LDR  <Wt>, <label>
    if isWr(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return loadlit(0, 0, pcrel19(sa_label, pc), sa_wt)
        })
    }
    // LDR  <Wt>, .±<offs>
    if isWr(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(loadlit(0, 0, rel19(ra_pcrel), sa_wt))
    }
    // LDR  <Xt>, <label>
    if isXr(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return loadlit(1, 0, pcrel19(sa_label, pc), sa_xt)
        })
    }
    // LDR  <Xt>, .±<offs>
    if isXr(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(loadlit(1, 0, rel19(ra_pcrel), sa_xt))
    }
    // LDR  <Bt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       (mext(v1) == Basic || modt(mext(v1)) == ModLSL) {
        p.Domain = DomainFpSimd
        var sa_amount uint32
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            sa_amount = uint32(mext(v1).(Modifier).Amount())
        }
        return p.setins(ldst_regoff(0, 1, 1, sa_xm, 3, sa_amount, sa_xn_sp, sa_bt))
    }
    // LDR  <Bt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
    if isBr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isWrOrXr(midx(v1)) && isMod(mext(v1)) {
        p.Domain = DomainFpSimd
        var sa_extend uint32
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        switch mext(v1).(Modifier).Type() {
            case ModUXTW: sa_extend = 0b010
            case ModSXTW: sa_extend = 0b110
            case ModSXTX: sa_extend = 0b111
            default: panic("aarch64: invalid modifier flags")
        }
        sa_amount := uint32(mext(v1).(Modifier).Amount())
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDR")
        }
        return p.setins(ldst_regoff(0, 1, 1, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_bt))
    }
    // LDR  <Dt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = DomainFpSimd
        var sa_amount_1 uint32
        sa_extend_1 := uint32(0b011)
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_1 = 0b0
            case 3: sa_amount_1 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend_1 & 1 != 0 || isXr(sa_xm) && sa_extend_1 & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDR")
        }
        return p.setins(ldst_regoff(3, 1, 1, sa_xm, sa_extend_1, sa_amount_1, sa_xn_sp, sa_dt))
    }
    // LDR  <Ht>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = DomainFpSimd
        var sa_amount_2 uint32
        sa_extend_1 := uint32(0b011)
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_2 = 0b0
            case 1: sa_amount_2 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend_1 & 1 != 0 || isXr(sa_xm) && sa_extend_1 & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDR")
        }
        return p.setins(ldst_regoff(1, 1, 1, sa_xm, sa_extend_1, sa_amount_2, sa_xn_sp, sa_ht))
    }
    // LDR  <Qt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = DomainFpSimd
        var sa_amount_3 uint32
        sa_extend_1 := uint32(0b011)
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_3 = 0b0
            case 4: sa_amount_3 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend_1 & 1 != 0 || isXr(sa_xm) && sa_extend_1 & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDR")
        }
        return p.setins(ldst_regoff(0, 1, 3, sa_xm, sa_extend_1, sa_amount_3, sa_xn_sp, sa_qt))
    }
    // LDR  <St>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = DomainFpSimd
        var sa_amount_4 uint32
        sa_extend_1 := uint32(0b011)
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_4 = 0b0
            case 2: sa_amount_4 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend_1 & 1 != 0 || isXr(sa_xm) && sa_extend_1 & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDR")
        }
        return p.setins(ldst_regoff(2, 1, 1, sa_xm, sa_extend_1, sa_amount_4, sa_xn_sp, sa_st))
    }
    // LDR  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_extend := uint32(0b011)
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 2: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDR")
        }
        return p.setins(ldst_regoff(2, 0, 1, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_wt))
    }
    // LDR  <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount_1 uint32
        sa_extend := uint32(0b011)
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_1 = 0b0
            case 3: sa_amount_1 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDR")
        }
        return p.setins(ldst_regoff(3, 0, 1, sa_xm, sa_extend, sa_amount_1, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDR")
}

// LDRAA instruction have 2 forms across one single category:
//
// 1. Load Register, with pointer authentication
//
//    LDRAA  <Xt>, [<Xn|SP>{, #<simm>}]!
//    LDRAA  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register, with pointer authentication. This instruction authenticates an
// address from a base register using a modifier of zero and the specified key,
// adds an immediate offset to the authenticated address, and loads a 64-bit
// doubleword from memory at this resulting address into a register.
//
// Key A is used for LDRAA . Key B is used for LDRAB .
//
// If the authentication passes, the PE behaves the same as for an LDR instruction.
// For information on behavior if the authentication fails, see Faulting on pointer
// authentication .
//
// The authenticated address is not written back to the base register, unless the
// pre-indexed variant of the instruction is used. In this case, the address that
// is written back to the base register does not include the pointer authentication
// code.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDRAA(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDRAA", 2, asm.Operands { v0, v1 })
    // LDRAA  <Xt>, [<Xn|SP>{, #<simm>}]!
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4088) &&
       isMultipleOf(moffs(v1), 8) &&
       mext(v1) == PreIndex {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1) / 8)
        return p.setins(ldst_pac(3, 0, 0, ubfx(sa_simm, 9, 1), mask(sa_simm, 9), 1, sa_xn_sp, sa_xt))
    }
    // LDRAA  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4088) &&
       isMultipleOf(moffs(v1), 8) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1) / 8)
        return p.setins(ldst_pac(3, 0, 0, ubfx(sa_simm, 9, 1), mask(sa_simm, 9), 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDRAA")
}

// LDRAB instruction have 2 forms across one single category:
//
// 1. Load Register, with pointer authentication
//
//    LDRAB  <Xt>, [<Xn|SP>{, #<simm>}]!
//    LDRAB  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register, with pointer authentication. This instruction authenticates an
// address from a base register using a modifier of zero and the specified key,
// adds an immediate offset to the authenticated address, and loads a 64-bit
// doubleword from memory at this resulting address into a register.
//
// Key A is used for LDRAA . Key B is used for LDRAB .
//
// If the authentication passes, the PE behaves the same as for an LDR instruction.
// For information on behavior if the authentication fails, see Faulting on pointer
// authentication .
//
// The authenticated address is not written back to the base register, unless the
// pre-indexed variant of the instruction is used. In this case, the address that
// is written back to the base register does not include the pointer authentication
// code.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDRAB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDRAB", 2, asm.Operands { v0, v1 })
    // LDRAB  <Xt>, [<Xn|SP>{, #<simm>}]!
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4088) &&
       isMultipleOf(moffs(v1), 8) &&
       mext(v1) == PreIndex {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1) / 8)
        return p.setins(ldst_pac(3, 0, 1, ubfx(sa_simm, 9, 1), mask(sa_simm, 9), 1, sa_xn_sp, sa_xt))
    }
    // LDRAB  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4088) &&
       isMultipleOf(moffs(v1), 8) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1) / 8)
        return p.setins(ldst_pac(3, 0, 1, ubfx(sa_simm, 9, 1), mask(sa_simm, 9), 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDRAB")
}

// LDRB instruction have 5 forms across 2 categories:
//
// 1. Load Register Byte (immediate)
//
//    LDRB  <Wt>, [<Xn|SP>], #<simm>
//    LDRB  <Wt>, [<Xn|SP>, #<simm>]!
//    LDRB  <Wt>, [<Xn|SP>{, #<pimm>}]
//
// Load Register Byte (immediate) loads a byte from memory, zero-extends it, and
// writes the result to a register. The address that is used for the load is
// calculated from a base register and an immediate offset. For information about
// memory accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDRH (immediate) .
//
// 2. Load Register Byte (register)
//
//    LDRB  <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
//    LDRB  <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
//
// Load Register Byte (register) calculates an address from a base register value
// and an offset register value, loads a byte from memory, zero-extends it, and
// writes it to a register. For information about memory accesses, see Load/Store
// addressing modes .
//
func (self *Program) LDRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDRB", 2, asm.Operands { v0, v1 })
    // LDRB  <Wt>, [<Xn|SP>], #<simm>
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(0, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDRB  <Wt>, [<Xn|SP>, #<simm>]!
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(0, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDRB  <Wt>, [<Xn|SP>{, #<pimm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 4095) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1))
        return p.setins(ldst_pos(0, 0, 1, sa_pimm, sa_xn_sp, sa_wt))
    }
    // LDRB  <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       (mext(v1) == Basic || modt(mext(v1)) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            sa_amount = uint32(mext(v1).(Modifier).Amount())
        }
        return p.setins(ldst_regoff(0, 0, 1, sa_xm, 3, sa_amount, sa_xn_sp, sa_wt))
    }
    // LDRB  <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isWrOrXr(midx(v1)) && isMod(mext(v1)) {
        p.Domain = asm.DomainGeneric
        var sa_extend uint32
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        switch mext(v1).(Modifier).Type() {
            case ModUXTW: sa_extend = 0b010
            case ModSXTW: sa_extend = 0b110
            case ModSXTX: sa_extend = 0b111
            default: panic("aarch64: invalid modifier flags")
        }
        sa_amount := uint32(mext(v1).(Modifier).Amount())
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDRB")
        }
        return p.setins(ldst_regoff(0, 0, 1, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_wt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDRB")
}

// LDRH instruction have 4 forms across 2 categories:
//
// 1. Load Register Halfword (immediate)
//
//    LDRH  <Wt>, [<Xn|SP>], #<simm>
//    LDRH  <Wt>, [<Xn|SP>, #<simm>]!
//    LDRH  <Wt>, [<Xn|SP>{, #<pimm>}]
//
// Load Register Halfword (immediate) loads a halfword from memory, zero-extends
// it, and writes the result to a register. The address that is used for the load
// is calculated from a base register and an immediate offset. For information
// about memory accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDRH (immediate) .
//
// 2. Load Register Halfword (register)
//
//    LDRH  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//
// Load Register Halfword (register) calculates an address from a base register
// value and an offset register value, loads a halfword from memory, zero-extends
// it, and writes it to a register. For information about memory accesses, see
// Load/Store addressing modes .
//
func (self *Program) LDRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDRH", 2, asm.Operands { v0, v1 })
    // LDRH  <Wt>, [<Xn|SP>], #<simm>
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(1, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDRH  <Wt>, [<Xn|SP>, #<simm>]!
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(1, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDRH  <Wt>, [<Xn|SP>{, #<pimm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 8190) &&
       isMultipleOf(moffs(v1), 2) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1) / 2)
        return p.setins(ldst_pos(1, 0, 1, sa_pimm, sa_xn_sp, sa_wt))
    }
    // LDRH  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_extend := uint32(0b011)
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 1: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDRH")
        }
        return p.setins(ldst_regoff(1, 0, 1, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_wt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDRH")
}

// LDRSB instruction have 10 forms across 2 categories:
//
// 1. Load Register Signed Byte (immediate)
//
//    LDRSB  <Wt>, [<Xn|SP>], #<simm>
//    LDRSB  <Wt>, [<Xn|SP>, #<simm>]!
//    LDRSB  <Wt>, [<Xn|SP>{, #<pimm>}]
//    LDRSB  <Xt>, [<Xn|SP>], #<simm>
//    LDRSB  <Xt>, [<Xn|SP>, #<simm>]!
//    LDRSB  <Xt>, [<Xn|SP>{, #<pimm>}]
//
// Load Register Signed Byte (immediate) loads a byte from memory, sign-extends it
// to either 32 bits or 64 bits, and writes the result to a register. The address
// that is used for the load is calculated from a base register and an immediate
// offset. For information about memory accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDRSB (immediate) .
//
// 2. Load Register Signed Byte (register)
//
//    LDRSB  <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
//    LDRSB  <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
//    LDRSB  <Xt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
//    LDRSB  <Xt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
//
// Load Register Signed Byte (register) calculates an address from a base register
// value and an offset register value, loads a byte from memory, sign-extends it,
// and writes it to a register. For information about memory accesses, see
// Load/Store addressing modes .
//
func (self *Program) LDRSB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDRSB", 2, asm.Operands { v0, v1 })
    // LDRSB  <Wt>, [<Xn|SP>], #<simm>
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(0, 0, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDRSB  <Wt>, [<Xn|SP>, #<simm>]!
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(0, 0, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDRSB  <Wt>, [<Xn|SP>{, #<pimm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 4095) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1))
        return p.setins(ldst_pos(0, 0, 3, sa_pimm, sa_xn_sp, sa_wt))
    }
    // LDRSB  <Xt>, [<Xn|SP>], #<simm>
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(0, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // LDRSB  <Xt>, [<Xn|SP>, #<simm>]!
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(0, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // LDRSB  <Xt>, [<Xn|SP>{, #<pimm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 4095) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1))
        return p.setins(ldst_pos(0, 0, 2, sa_pimm, sa_xn_sp, sa_xt))
    }
    // LDRSB  <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       (mext(v1) == Basic || modt(mext(v1)) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            sa_amount = uint32(mext(v1).(Modifier).Amount())
        }
        return p.setins(ldst_regoff(0, 0, 3, sa_xm, 3, sa_amount, sa_xn_sp, sa_wt))
    }
    // LDRSB  <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isWrOrXr(midx(v1)) && isMod(mext(v1)) {
        p.Domain = asm.DomainGeneric
        var sa_extend uint32
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        switch mext(v1).(Modifier).Type() {
            case ModUXTW: sa_extend = 0b010
            case ModSXTW: sa_extend = 0b110
            case ModSXTX: sa_extend = 0b111
            default: panic("aarch64: invalid modifier flags")
        }
        sa_amount := uint32(mext(v1).(Modifier).Amount())
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDRSB")
        }
        return p.setins(ldst_regoff(0, 0, 3, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_wt))
    }
    // LDRSB  <Xt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       (mext(v1) == Basic || modt(mext(v1)) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            sa_amount = uint32(mext(v1).(Modifier).Amount())
        }
        return p.setins(ldst_regoff(0, 0, 2, sa_xm, 3, sa_amount, sa_xn_sp, sa_xt))
    }
    // LDRSB  <Xt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isWrOrXr(midx(v1)) && isMod(mext(v1)) {
        p.Domain = asm.DomainGeneric
        var sa_extend uint32
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        switch mext(v1).(Modifier).Type() {
            case ModUXTW: sa_extend = 0b010
            case ModSXTW: sa_extend = 0b110
            case ModSXTX: sa_extend = 0b111
            default: panic("aarch64: invalid modifier flags")
        }
        sa_amount := uint32(mext(v1).(Modifier).Amount())
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDRSB")
        }
        return p.setins(ldst_regoff(0, 0, 2, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDRSB")
}

// LDRSH instruction have 8 forms across 2 categories:
//
// 1. Load Register Signed Halfword (immediate)
//
//    LDRSH  <Wt>, [<Xn|SP>], #<simm>
//    LDRSH  <Wt>, [<Xn|SP>, #<simm>]!
//    LDRSH  <Wt>, [<Xn|SP>{, #<pimm>}]
//    LDRSH  <Xt>, [<Xn|SP>], #<simm>
//    LDRSH  <Xt>, [<Xn|SP>, #<simm>]!
//    LDRSH  <Xt>, [<Xn|SP>{, #<pimm>}]
//
// Load Register Signed Halfword (immediate) loads a halfword from memory, sign-
// extends it to 32 bits or 64 bits, and writes the result to a register. The
// address that is used for the load is calculated from a base register and an
// immediate offset. For information about memory accesses, see Load/Store
// addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDRSH (immediate) .
//
// 2. Load Register Signed Halfword (register)
//
//    LDRSH  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//    LDRSH  <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//
// Load Register Signed Halfword (register) calculates an address from a base
// register value and an offset register value, loads a halfword from memory, sign-
// extends it, and writes it to a register. For information about memory accesses,
// see Load/Store addressing modes .
//
func (self *Program) LDRSH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDRSH", 2, asm.Operands { v0, v1 })
    // LDRSH  <Wt>, [<Xn|SP>], #<simm>
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(1, 0, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDRSH  <Wt>, [<Xn|SP>, #<simm>]!
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(1, 0, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDRSH  <Wt>, [<Xn|SP>{, #<pimm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 8190) &&
       isMultipleOf(moffs(v1), 2) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1) / 2)
        return p.setins(ldst_pos(1, 0, 3, sa_pimm, sa_xn_sp, sa_wt))
    }
    // LDRSH  <Xt>, [<Xn|SP>], #<simm>
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(1, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // LDRSH  <Xt>, [<Xn|SP>, #<simm>]!
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(1, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // LDRSH  <Xt>, [<Xn|SP>{, #<pimm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 8190) &&
       isMultipleOf(moffs(v1), 2) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1) / 2)
        return p.setins(ldst_pos(1, 0, 2, sa_pimm, sa_xn_sp, sa_xt))
    }
    // LDRSH  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_extend := uint32(0b011)
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 1: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDRSH")
        }
        return p.setins(ldst_regoff(1, 0, 3, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_wt))
    }
    // LDRSH  <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_extend := uint32(0b011)
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 1: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDRSH")
        }
        return p.setins(ldst_regoff(1, 0, 2, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDRSH")
}

// LDRSW instruction have 6 forms across 3 categories:
//
// 1. Load Register Signed Word (immediate)
//
//    LDRSW  <Xt>, [<Xn|SP>], #<simm>
//    LDRSW  <Xt>, [<Xn|SP>, #<simm>]!
//    LDRSW  <Xt>, [<Xn|SP>{, #<pimm>}]
//
// Load Register Signed Word (immediate) loads a word from memory, sign-extends it
// to 64 bits, and writes the result to a register. The address that is used for
// the load is calculated from a base register and an immediate offset. For
// information about memory accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDRSW (immediate) .
//
// 2. Load Register Signed Word (literal)
//
//    LDRSW  <Xt>, <label>
//    LDRSW  <Xt>, .±<offs>
//
// Load Register Signed Word (literal) calculates an address from the PC value and
// an immediate offset, loads a word from memory, and writes it to a register. For
// information about memory accesses, see Load/Store addressing modes .
//
// 3. Load Register Signed Word (register)
//
//    LDRSW  <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//
// Load Register Signed Word (register) calculates an address from a base register
// value and an offset register value, loads a word from memory, sign-extends it to
// form a 64-bit value, and writes it to a register. The offset register value can
// be shifted left by 0 or 2 bits. For information about memory accesses, see
// Load/Store addressing modes .
//
func (self *Program) LDRSW(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDRSW", 2, asm.Operands { v0, v1 })
    // LDRSW  <Xt>, [<Xn|SP>], #<simm>
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(2, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // LDRSW  <Xt>, [<Xn|SP>, #<simm>]!
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(2, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // LDRSW  <Xt>, [<Xn|SP>{, #<pimm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 16380) &&
       isMultipleOf(moffs(v1), 4) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1) / 4)
        return p.setins(ldst_pos(2, 0, 2, sa_pimm, sa_xn_sp, sa_xt))
    }
    // LDRSW  <Xt>, <label>
    if isXr(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return loadlit(2, 0, pcrel19(sa_label, pc), sa_xt)
        })
    }
    // LDRSW  <Xt>, .±<offs>
    if isXr(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(loadlit(2, 0, rel19(ra_pcrel), sa_xt))
    }
    // LDRSW  <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_extend := uint32(0b011)
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 2: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for LDRSW")
        }
        return p.setins(ldst_regoff(2, 0, 2, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDRSW")
}

// LDSET instruction have 2 forms across one single category:
//
// 1. Atomic bit set on word or doubleword in memory
//
//    LDSET  <Ws>, <Wt>, [<Xn|SP>]
//    LDSET  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic bit set on word or doubleword in memory atomically loads a 32-bit word or
// 64-bit doubleword from memory, performs a bitwise OR with the value held in a
// register on it, and stores the result back to memory. The value initially loaded
// from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSETA and
//       LDSETAL load from memory with acquire semantics.
//     * LDSETL and LDSETAL store to memory with release semantics.
//     * LDSET has neither acquire nor release semantics.
//
// For more information about memory ordering semantics see Load-Acquire, Store-
// Release .
//
// For information about memory accesses see Load/Store addressing modes .
//
func (self *Program) LDSET(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSET", 3, asm.Operands { v0, v1, v2 })
    // LDSET  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    // LDSET  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 3, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSET")
}

// LDSETA instruction have 2 forms across one single category:
//
// 1. Atomic bit set on word or doubleword in memory
//
//    LDSETA  <Ws>, <Wt>, [<Xn|SP>]
//    LDSETA  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic bit set on word or doubleword in memory atomically loads a 32-bit word or
// 64-bit doubleword from memory, performs a bitwise OR with the value held in a
// register on it, and stores the result back to memory. The value initially loaded
// from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSETA and
//       LDSETAL load from memory with acquire semantics.
//     * LDSETL and LDSETAL store to memory with release semantics.
//     * LDSET has neither acquire nor release semantics.
//
// For more information about memory ordering semantics see Load-Acquire, Store-
// Release .
//
// For information about memory accesses see Load/Store addressing modes .
//
func (self *Program) LDSETA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETA", 3, asm.Operands { v0, v1, v2 })
    // LDSETA  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 0, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    // LDSETA  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 0, sa_xs, 0, 3, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETA")
}

// LDSETAB instruction have one single form across one single category:
//
// 1. Atomic bit set on byte in memory
//
//    LDSETAB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit set on byte in memory atomically loads an 8-bit byte from memory,
// performs a bitwise OR with the value held in a register on it, and stores the
// result back to memory. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not WZR , LDSETAB and LDSETALB load
//       from memory with acquire semantics.
//     * LDSETLB and LDSETALB store to memory with release semantics.
//     * LDSETB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSETAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETAB")
}

// LDSETAH instruction have one single form across one single category:
//
// 1. Atomic bit set on halfword in memory
//
//    LDSETAH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit set on halfword in memory atomically loads a 16-bit halfword from
// memory, performs a bitwise OR with the value held in a register on it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDSETAH and LDSETALH load
//       from memory with acquire semantics.
//     * LDSETLH and LDSETALH store to memory with release semantics.
//     * LDSETH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSETAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETAH")
}

// LDSETAL instruction have 2 forms across one single category:
//
// 1. Atomic bit set on word or doubleword in memory
//
//    LDSETAL  <Ws>, <Wt>, [<Xn|SP>]
//    LDSETAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic bit set on word or doubleword in memory atomically loads a 32-bit word or
// 64-bit doubleword from memory, performs a bitwise OR with the value held in a
// register on it, and stores the result back to memory. The value initially loaded
// from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSETA and
//       LDSETAL load from memory with acquire semantics.
//     * LDSETL and LDSETAL store to memory with release semantics.
//     * LDSET has neither acquire nor release semantics.
//
// For more information about memory ordering semantics see Load-Acquire, Store-
// Release .
//
// For information about memory accesses see Load/Store addressing modes .
//
func (self *Program) LDSETAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETAL", 3, asm.Operands { v0, v1, v2 })
    // LDSETAL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 1, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    // LDSETAL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 1, sa_xs, 0, 3, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETAL")
}

// LDSETALB instruction have one single form across one single category:
//
// 1. Atomic bit set on byte in memory
//
//    LDSETALB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit set on byte in memory atomically loads an 8-bit byte from memory,
// performs a bitwise OR with the value held in a register on it, and stores the
// result back to memory. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not WZR , LDSETAB and LDSETALB load
//       from memory with acquire semantics.
//     * LDSETLB and LDSETALB store to memory with release semantics.
//     * LDSETB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSETALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETALB")
}

// LDSETALH instruction have one single form across one single category:
//
// 1. Atomic bit set on halfword in memory
//
//    LDSETALH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit set on halfword in memory atomically loads a 16-bit halfword from
// memory, performs a bitwise OR with the value held in a register on it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDSETAH and LDSETALH load
//       from memory with acquire semantics.
//     * LDSETLH and LDSETALH store to memory with release semantics.
//     * LDSETH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSETALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETALH")
}

// LDSETB instruction have one single form across one single category:
//
// 1. Atomic bit set on byte in memory
//
//    LDSETB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit set on byte in memory atomically loads an 8-bit byte from memory,
// performs a bitwise OR with the value held in a register on it, and stores the
// result back to memory. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not WZR , LDSETAB and LDSETALB load
//       from memory with acquire semantics.
//     * LDSETLB and LDSETALB store to memory with release semantics.
//     * LDSETB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSETB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETB")
}

// LDSETH instruction have one single form across one single category:
//
// 1. Atomic bit set on halfword in memory
//
//    LDSETH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit set on halfword in memory atomically loads a 16-bit halfword from
// memory, performs a bitwise OR with the value held in a register on it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDSETAH and LDSETALH load
//       from memory with acquire semantics.
//     * LDSETLH and LDSETALH store to memory with release semantics.
//     * LDSETH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSETH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETH")
}

// LDSETL instruction have 2 forms across one single category:
//
// 1. Atomic bit set on word or doubleword in memory
//
//    LDSETL  <Ws>, <Wt>, [<Xn|SP>]
//    LDSETL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic bit set on word or doubleword in memory atomically loads a 32-bit word or
// 64-bit doubleword from memory, performs a bitwise OR with the value held in a
// register on it, and stores the result back to memory. The value initially loaded
// from memory is returned in the destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSETA and
//       LDSETAL load from memory with acquire semantics.
//     * LDSETL and LDSETAL store to memory with release semantics.
//     * LDSET has neither acquire nor release semantics.
//
// For more information about memory ordering semantics see Load-Acquire, Store-
// Release .
//
// For information about memory accesses see Load/Store addressing modes .
//
func (self *Program) LDSETL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETL", 3, asm.Operands { v0, v1, v2 })
    // LDSETL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    // LDSETL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 3, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETL")
}

// LDSETLB instruction have one single form across one single category:
//
// 1. Atomic bit set on byte in memory
//
//    LDSETLB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit set on byte in memory atomically loads an 8-bit byte from memory,
// performs a bitwise OR with the value held in a register on it, and stores the
// result back to memory. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not WZR , LDSETAB and LDSETALB load
//       from memory with acquire semantics.
//     * LDSETLB and LDSETALB store to memory with release semantics.
//     * LDSETB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSETLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETLB")
}

// LDSETLH instruction have one single form across one single category:
//
// 1. Atomic bit set on halfword in memory
//
//    LDSETLH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic bit set on halfword in memory atomically loads a 16-bit halfword from
// memory, performs a bitwise OR with the value held in a register on it, and
// stores the result back to memory. The value initially loaded from memory is
// returned in the destination register.
//
//     * If the destination register is not WZR , LDSETAH and LDSETALH load
//       from memory with acquire semantics.
//     * LDSETLH and LDSETALH store to memory with release semantics.
//     * LDSETH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSETLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 3, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETLH")
}

// LDSETP instruction have one single form across one single category:
//
// 1. Atomic bit set on quadword in memory
//
//    LDSETP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Atomic bit set on quadword in memory atomically loads a 128-bit quadword from
// memory, performs a bitwise OR with the value held in a pair of registers on it,
// and stores the result back to memory. The value initially loaded from memory is
// returned in the same pair of registers.
//
//     * LDSETPA and LDSETPAL load from memory with acquire semantics.
//     * LDSETPL and LDSETPAL store to memory with release semantics.
//     * LDSETP has neither acquire nor release semantics.
//
func (self *Program) LDSETP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 0, sa_xt2, 0, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETP")
}

// LDSETPA instruction have one single form across one single category:
//
// 1. Atomic bit set on quadword in memory
//
//    LDSETPA  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Atomic bit set on quadword in memory atomically loads a 128-bit quadword from
// memory, performs a bitwise OR with the value held in a pair of registers on it,
// and stores the result back to memory. The value initially loaded from memory is
// returned in the same pair of registers.
//
//     * LDSETPA and LDSETPAL load from memory with acquire semantics.
//     * LDSETPL and LDSETPAL store to memory with release semantics.
//     * LDSETP has neither acquire nor release semantics.
//
func (self *Program) LDSETPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 0, sa_xt2, 0, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETPA")
}

// LDSETPAL instruction have one single form across one single category:
//
// 1. Atomic bit set on quadword in memory
//
//    LDSETPAL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Atomic bit set on quadword in memory atomically loads a 128-bit quadword from
// memory, performs a bitwise OR with the value held in a pair of registers on it,
// and stores the result back to memory. The value initially loaded from memory is
// returned in the same pair of registers.
//
//     * LDSETPA and LDSETPAL load from memory with acquire semantics.
//     * LDSETPL and LDSETPAL store to memory with release semantics.
//     * LDSETP has neither acquire nor release semantics.
//
func (self *Program) LDSETPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 1, sa_xt2, 0, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETPAL")
}

// LDSETPL instruction have one single form across one single category:
//
// 1. Atomic bit set on quadword in memory
//
//    LDSETPL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Atomic bit set on quadword in memory atomically loads a 128-bit quadword from
// memory, performs a bitwise OR with the value held in a pair of registers on it,
// and stores the result back to memory. The value initially loaded from memory is
// returned in the same pair of registers.
//
//     * LDSETPA and LDSETPAL load from memory with acquire semantics.
//     * LDSETPL and LDSETPAL store to memory with release semantics.
//     * LDSETP has neither acquire nor release semantics.
//
func (self *Program) LDSETPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSETPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 1, sa_xt2, 0, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSETPL")
}

// LDSMAX instruction have 2 forms across one single category:
//
// 1. Atomic signed maximum on word or doubleword in memory
//
//    LDSMAX  <Ws>, <Wt>, [<Xn|SP>]
//    LDSMAX  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic signed maximum on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, compares it against the value held in a
// register, and stores the larger value back to memory, treating the values as
// signed numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSMAXA and
//       LDSMAXAL load from memory with acquire semantics.
//     * LDSMAXL and LDSMAXAL store to memory with release semantics.
//     * LDSMAX has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAX(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAX", 3, asm.Operands { v0, v1, v2 })
    // LDSMAX  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    // LDSMAX  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 4, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAX")
}

// LDSMAXA instruction have 2 forms across one single category:
//
// 1. Atomic signed maximum on word or doubleword in memory
//
//    LDSMAXA  <Ws>, <Wt>, [<Xn|SP>]
//    LDSMAXA  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic signed maximum on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, compares it against the value held in a
// register, and stores the larger value back to memory, treating the values as
// signed numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSMAXA and
//       LDSMAXAL load from memory with acquire semantics.
//     * LDSMAXL and LDSMAXAL store to memory with release semantics.
//     * LDSMAX has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXA", 3, asm.Operands { v0, v1, v2 })
    // LDSMAXA  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 0, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    // LDSMAXA  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 0, sa_xs, 0, 4, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXA")
}

// LDSMAXAB instruction have one single form across one single category:
//
// 1. Atomic signed maximum on byte in memory
//
//    LDSMAXAB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed maximum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the larger
// value back to memory, treating the values as signed numbers. The value initially
// loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMAXAB and LDSMAXALB load
//       from memory with acquire semantics.
//     * LDSMAXLB and LDSMAXALB store to memory with release semantics.
//     * LDSMAXB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXAB")
}

// LDSMAXAH instruction have one single form across one single category:
//
// 1. Atomic signed maximum on halfword in memory
//
//    LDSMAXAH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed maximum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// larger value back to memory, treating the values as signed numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMAXAH and LDSMAXALH load
//       from memory with acquire semantics.
//     * LDSMAXLH and LDSMAXALH store to memory with release semantics.
//     * LDSMAXH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXAH")
}

// LDSMAXAL instruction have 2 forms across one single category:
//
// 1. Atomic signed maximum on word or doubleword in memory
//
//    LDSMAXAL  <Ws>, <Wt>, [<Xn|SP>]
//    LDSMAXAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic signed maximum on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, compares it against the value held in a
// register, and stores the larger value back to memory, treating the values as
// signed numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSMAXA and
//       LDSMAXAL load from memory with acquire semantics.
//     * LDSMAXL and LDSMAXAL store to memory with release semantics.
//     * LDSMAX has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXAL", 3, asm.Operands { v0, v1, v2 })
    // LDSMAXAL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 1, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    // LDSMAXAL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 1, sa_xs, 0, 4, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXAL")
}

// LDSMAXALB instruction have one single form across one single category:
//
// 1. Atomic signed maximum on byte in memory
//
//    LDSMAXALB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed maximum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the larger
// value back to memory, treating the values as signed numbers. The value initially
// loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMAXAB and LDSMAXALB load
//       from memory with acquire semantics.
//     * LDSMAXLB and LDSMAXALB store to memory with release semantics.
//     * LDSMAXB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXALB")
}

// LDSMAXALH instruction have one single form across one single category:
//
// 1. Atomic signed maximum on halfword in memory
//
//    LDSMAXALH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed maximum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// larger value back to memory, treating the values as signed numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMAXAH and LDSMAXALH load
//       from memory with acquire semantics.
//     * LDSMAXLH and LDSMAXALH store to memory with release semantics.
//     * LDSMAXH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXALH")
}

// LDSMAXB instruction have one single form across one single category:
//
// 1. Atomic signed maximum on byte in memory
//
//    LDSMAXB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed maximum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the larger
// value back to memory, treating the values as signed numbers. The value initially
// loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMAXAB and LDSMAXALB load
//       from memory with acquire semantics.
//     * LDSMAXLB and LDSMAXALB store to memory with release semantics.
//     * LDSMAXB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXB")
}

// LDSMAXH instruction have one single form across one single category:
//
// 1. Atomic signed maximum on halfword in memory
//
//    LDSMAXH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed maximum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// larger value back to memory, treating the values as signed numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMAXAH and LDSMAXALH load
//       from memory with acquire semantics.
//     * LDSMAXLH and LDSMAXALH store to memory with release semantics.
//     * LDSMAXH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXH")
}

// LDSMAXL instruction have 2 forms across one single category:
//
// 1. Atomic signed maximum on word or doubleword in memory
//
//    LDSMAXL  <Ws>, <Wt>, [<Xn|SP>]
//    LDSMAXL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic signed maximum on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, compares it against the value held in a
// register, and stores the larger value back to memory, treating the values as
// signed numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSMAXA and
//       LDSMAXAL load from memory with acquire semantics.
//     * LDSMAXL and LDSMAXAL store to memory with release semantics.
//     * LDSMAX has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXL", 3, asm.Operands { v0, v1, v2 })
    // LDSMAXL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    // LDSMAXL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 4, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXL")
}

// LDSMAXLB instruction have one single form across one single category:
//
// 1. Atomic signed maximum on byte in memory
//
//    LDSMAXLB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed maximum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the larger
// value back to memory, treating the values as signed numbers. The value initially
// loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMAXAB and LDSMAXALB load
//       from memory with acquire semantics.
//     * LDSMAXLB and LDSMAXALB store to memory with release semantics.
//     * LDSMAXB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXLB")
}

// LDSMAXLH instruction have one single form across one single category:
//
// 1. Atomic signed maximum on halfword in memory
//
//    LDSMAXLH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed maximum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// larger value back to memory, treating the values as signed numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMAXAH and LDSMAXALH load
//       from memory with acquire semantics.
//     * LDSMAXLH and LDSMAXALH store to memory with release semantics.
//     * LDSMAXH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMAXLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMAXLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 4, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMAXLH")
}

// LDSMIN instruction have 2 forms across one single category:
//
// 1. Atomic signed minimum on word or doubleword in memory
//
//    LDSMIN  <Ws>, <Wt>, [<Xn|SP>]
//    LDSMIN  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic signed minimum on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, compares it against the value held in a
// register, and stores the smaller value back to memory, treating the values as
// signed numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSMINA and
//       LDSMINAL load from memory with acquire semantics.
//     * LDSMINL and LDSMINAL store to memory with release semantics.
//     * LDSMIN has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMIN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMIN", 3, asm.Operands { v0, v1, v2 })
    // LDSMIN  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    // LDSMIN  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 5, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMIN")
}

// LDSMINA instruction have 2 forms across one single category:
//
// 1. Atomic signed minimum on word or doubleword in memory
//
//    LDSMINA  <Ws>, <Wt>, [<Xn|SP>]
//    LDSMINA  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic signed minimum on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, compares it against the value held in a
// register, and stores the smaller value back to memory, treating the values as
// signed numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSMINA and
//       LDSMINAL load from memory with acquire semantics.
//     * LDSMINL and LDSMINAL store to memory with release semantics.
//     * LDSMIN has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINA", 3, asm.Operands { v0, v1, v2 })
    // LDSMINA  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 0, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    // LDSMINA  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 0, sa_xs, 0, 5, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINA")
}

// LDSMINAB instruction have one single form across one single category:
//
// 1. Atomic signed minimum on byte in memory
//
//    LDSMINAB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed minimum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the smaller
// value back to memory, treating the values as signed numbers. The value initially
// loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMINAB and LDSMINALB load
//       from memory with acquire semantics.
//     * LDSMINLB and LDSMINALB store to memory with release semantics.
//     * LDSMINB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINAB")
}

// LDSMINAH instruction have one single form across one single category:
//
// 1. Atomic signed minimum on halfword in memory
//
//    LDSMINAH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed minimum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// smaller value back to memory, treating the values as signed numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMINAH and LDSMINALH load
//       from memory with acquire semantics.
//     * LDSMINLH and LDSMINALH store to memory with release semantics.
//     * LDSMINH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINAH")
}

// LDSMINAL instruction have 2 forms across one single category:
//
// 1. Atomic signed minimum on word or doubleword in memory
//
//    LDSMINAL  <Ws>, <Wt>, [<Xn|SP>]
//    LDSMINAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic signed minimum on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, compares it against the value held in a
// register, and stores the smaller value back to memory, treating the values as
// signed numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSMINA and
//       LDSMINAL load from memory with acquire semantics.
//     * LDSMINL and LDSMINAL store to memory with release semantics.
//     * LDSMIN has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINAL", 3, asm.Operands { v0, v1, v2 })
    // LDSMINAL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 1, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    // LDSMINAL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 1, sa_xs, 0, 5, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINAL")
}

// LDSMINALB instruction have one single form across one single category:
//
// 1. Atomic signed minimum on byte in memory
//
//    LDSMINALB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed minimum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the smaller
// value back to memory, treating the values as signed numbers. The value initially
// loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMINAB and LDSMINALB load
//       from memory with acquire semantics.
//     * LDSMINLB and LDSMINALB store to memory with release semantics.
//     * LDSMINB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINALB")
}

// LDSMINALH instruction have one single form across one single category:
//
// 1. Atomic signed minimum on halfword in memory
//
//    LDSMINALH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed minimum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// smaller value back to memory, treating the values as signed numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMINAH and LDSMINALH load
//       from memory with acquire semantics.
//     * LDSMINLH and LDSMINALH store to memory with release semantics.
//     * LDSMINH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINALH")
}

// LDSMINB instruction have one single form across one single category:
//
// 1. Atomic signed minimum on byte in memory
//
//    LDSMINB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed minimum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the smaller
// value back to memory, treating the values as signed numbers. The value initially
// loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMINAB and LDSMINALB load
//       from memory with acquire semantics.
//     * LDSMINLB and LDSMINALB store to memory with release semantics.
//     * LDSMINB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINB")
}

// LDSMINH instruction have one single form across one single category:
//
// 1. Atomic signed minimum on halfword in memory
//
//    LDSMINH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed minimum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// smaller value back to memory, treating the values as signed numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMINAH and LDSMINALH load
//       from memory with acquire semantics.
//     * LDSMINLH and LDSMINALH store to memory with release semantics.
//     * LDSMINH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINH")
}

// LDSMINL instruction have 2 forms across one single category:
//
// 1. Atomic signed minimum on word or doubleword in memory
//
//    LDSMINL  <Ws>, <Wt>, [<Xn|SP>]
//    LDSMINL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic signed minimum on word or doubleword in memory atomically loads a 32-bit
// word or 64-bit doubleword from memory, compares it against the value held in a
// register, and stores the smaller value back to memory, treating the values as
// signed numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDSMINA and
//       LDSMINAL load from memory with acquire semantics.
//     * LDSMINL and LDSMINAL store to memory with release semantics.
//     * LDSMIN has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINL", 3, asm.Operands { v0, v1, v2 })
    // LDSMINL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    // LDSMINL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 5, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINL")
}

// LDSMINLB instruction have one single form across one single category:
//
// 1. Atomic signed minimum on byte in memory
//
//    LDSMINLB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed minimum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the smaller
// value back to memory, treating the values as signed numbers. The value initially
// loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMINAB and LDSMINALB load
//       from memory with acquire semantics.
//     * LDSMINLB and LDSMINALB store to memory with release semantics.
//     * LDSMINB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINLB")
}

// LDSMINLH instruction have one single form across one single category:
//
// 1. Atomic signed minimum on halfword in memory
//
//    LDSMINLH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic signed minimum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// smaller value back to memory, treating the values as signed numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDSMINAH and LDSMINALH load
//       from memory with acquire semantics.
//     * LDSMINLH and LDSMINALH store to memory with release semantics.
//     * LDSMINH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDSMINLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDSMINLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 5, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDSMINLH")
}

// LDTR instruction have 2 forms across one single category:
//
// 1. Load Register (unprivileged)
//
//    LDTR  <Wt>, [<Xn|SP>{, #<simm>}]
//    LDTR  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register (unprivileged) loads a word or doubleword from memory, and writes
// it to a register. The address that is used for the load is calculated from a
// base register and an immediate offset.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed. For information about
// memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDTR(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDTR", 2, asm.Operands { v0, v1 })
    // LDTR  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(2, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDTR  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(3, 0, 1, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDTR")
}

// LDTRB instruction have one single form across one single category:
//
// 1. Load Register Byte (unprivileged)
//
//    LDTRB  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Byte (unprivileged) loads a byte from memory, zero-extends it, and
// writes the result to a register. The address that is used for the load is
// calculated from a base register and an immediate offset.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed. For information about
// memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDTRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDTRB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(0, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDTRB")
}

// LDTRH instruction have one single form across one single category:
//
// 1. Load Register Halfword (unprivileged)
//
//    LDTRH  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Halfword (unprivileged) loads a halfword from memory, zero-extends
// it, and writes the result to a register. The address that is used for the load
// is calculated from a base register and an immediate offset.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed. For information about
// memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDTRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDTRH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(1, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDTRH")
}

// LDTRSB instruction have 2 forms across one single category:
//
// 1. Load Register Signed Byte (unprivileged)
//
//    LDTRSB  <Wt>, [<Xn|SP>{, #<simm>}]
//    LDTRSB  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Signed Byte (unprivileged) loads a byte from memory, sign-extends
// it to 32 bits or 64 bits, and writes the result to a register. The address that
// is used for the load is calculated from a base register and an immediate offset.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed. For information about
// memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDTRSB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDTRSB", 2, asm.Operands { v0, v1 })
    // LDTRSB  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(0, 0, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDTRSB  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(0, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDTRSB")
}

// LDTRSH instruction have 2 forms across one single category:
//
// 1. Load Register Signed Halfword (unprivileged)
//
//    LDTRSH  <Wt>, [<Xn|SP>{, #<simm>}]
//    LDTRSH  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Signed Halfword (unprivileged) loads a halfword from memory, sign-
// extends it to 32 bits or 64 bits, and writes the result to a register. The
// address that is used for the load is calculated from a base register and an
// immediate offset.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed. For information about
// memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDTRSH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDTRSH", 2, asm.Operands { v0, v1 })
    // LDTRSH  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(1, 0, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDTRSH  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(1, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDTRSH")
}

// LDTRSW instruction have one single form across one single category:
//
// 1. Load Register Signed Word (unprivileged)
//
//    LDTRSW  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Signed Word (unprivileged) loads a word from memory, sign-extends
// it to 64 bits, and writes the result to a register. The address that is used for
// the load is calculated from a base register and an immediate offset.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed. For information about
// memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDTRSW(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDTRSW", 2, asm.Operands { v0, v1 })
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(2, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDTRSW")
}

// LDUMAX instruction have 2 forms across one single category:
//
// 1. Atomic unsigned maximum on word or doubleword in memory
//
//    LDUMAX  <Ws>, <Wt>, [<Xn|SP>]
//    LDUMAX  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic unsigned maximum on word or doubleword in memory atomically loads a
// 32-bit word or 64-bit doubleword from memory, compares it against the value held
// in a register, and stores the larger value back to memory, treating the values
// as unsigned numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDUMAXA and
//       LDUMAXAL load from memory with acquire semantics.
//     * LDUMAXL and LDUMAXAL store to memory with release semantics.
//     * LDUMAX has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAX(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAX", 3, asm.Operands { v0, v1, v2 })
    // LDUMAX  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    // LDUMAX  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 6, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAX")
}

// LDUMAXA instruction have 2 forms across one single category:
//
// 1. Atomic unsigned maximum on word or doubleword in memory
//
//    LDUMAXA  <Ws>, <Wt>, [<Xn|SP>]
//    LDUMAXA  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic unsigned maximum on word or doubleword in memory atomically loads a
// 32-bit word or 64-bit doubleword from memory, compares it against the value held
// in a register, and stores the larger value back to memory, treating the values
// as unsigned numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDUMAXA and
//       LDUMAXAL load from memory with acquire semantics.
//     * LDUMAXL and LDUMAXAL store to memory with release semantics.
//     * LDUMAX has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXA", 3, asm.Operands { v0, v1, v2 })
    // LDUMAXA  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 0, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    // LDUMAXA  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 0, sa_xs, 0, 6, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXA")
}

// LDUMAXAB instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on byte in memory
//
//    LDUMAXAB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned maximum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the larger
// value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMAXAB and LDUMAXALB load
//       from memory with acquire semantics.
//     * LDUMAXLB and LDUMAXALB store to memory with release semantics.
//     * LDUMAXB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXAB")
}

// LDUMAXAH instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on halfword in memory
//
//    LDUMAXAH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned maximum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// larger value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMAXAH and LDUMAXALH load
//       from memory with acquire semantics.
//     * LDUMAXLH and LDUMAXALH store to memory with release semantics.
//     * LDUMAXH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXAH")
}

// LDUMAXAL instruction have 2 forms across one single category:
//
// 1. Atomic unsigned maximum on word or doubleword in memory
//
//    LDUMAXAL  <Ws>, <Wt>, [<Xn|SP>]
//    LDUMAXAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic unsigned maximum on word or doubleword in memory atomically loads a
// 32-bit word or 64-bit doubleword from memory, compares it against the value held
// in a register, and stores the larger value back to memory, treating the values
// as unsigned numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDUMAXA and
//       LDUMAXAL load from memory with acquire semantics.
//     * LDUMAXL and LDUMAXAL store to memory with release semantics.
//     * LDUMAX has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXAL", 3, asm.Operands { v0, v1, v2 })
    // LDUMAXAL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 1, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    // LDUMAXAL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 1, sa_xs, 0, 6, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXAL")
}

// LDUMAXALB instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on byte in memory
//
//    LDUMAXALB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned maximum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the larger
// value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMAXAB and LDUMAXALB load
//       from memory with acquire semantics.
//     * LDUMAXLB and LDUMAXALB store to memory with release semantics.
//     * LDUMAXB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXALB")
}

// LDUMAXALH instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on halfword in memory
//
//    LDUMAXALH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned maximum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// larger value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMAXAH and LDUMAXALH load
//       from memory with acquire semantics.
//     * LDUMAXLH and LDUMAXALH store to memory with release semantics.
//     * LDUMAXH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXALH")
}

// LDUMAXB instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on byte in memory
//
//    LDUMAXB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned maximum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the larger
// value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMAXAB and LDUMAXALB load
//       from memory with acquire semantics.
//     * LDUMAXLB and LDUMAXALB store to memory with release semantics.
//     * LDUMAXB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXB")
}

// LDUMAXH instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on halfword in memory
//
//    LDUMAXH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned maximum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// larger value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMAXAH and LDUMAXALH load
//       from memory with acquire semantics.
//     * LDUMAXLH and LDUMAXALH store to memory with release semantics.
//     * LDUMAXH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXH")
}

// LDUMAXL instruction have 2 forms across one single category:
//
// 1. Atomic unsigned maximum on word or doubleword in memory
//
//    LDUMAXL  <Ws>, <Wt>, [<Xn|SP>]
//    LDUMAXL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic unsigned maximum on word or doubleword in memory atomically loads a
// 32-bit word or 64-bit doubleword from memory, compares it against the value held
// in a register, and stores the larger value back to memory, treating the values
// as unsigned numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDUMAXA and
//       LDUMAXAL load from memory with acquire semantics.
//     * LDUMAXL and LDUMAXAL store to memory with release semantics.
//     * LDUMAX has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXL", 3, asm.Operands { v0, v1, v2 })
    // LDUMAXL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    // LDUMAXL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 6, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXL")
}

// LDUMAXLB instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on byte in memory
//
//    LDUMAXLB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned maximum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the larger
// value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMAXAB and LDUMAXALB load
//       from memory with acquire semantics.
//     * LDUMAXLB and LDUMAXALB store to memory with release semantics.
//     * LDUMAXB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXLB")
}

// LDUMAXLH instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on halfword in memory
//
//    LDUMAXLH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned maximum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// larger value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMAXAH and LDUMAXALH load
//       from memory with acquire semantics.
//     * LDUMAXLH and LDUMAXALH store to memory with release semantics.
//     * LDUMAXH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMAXLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMAXLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 6, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMAXLH")
}

// LDUMIN instruction have 2 forms across one single category:
//
// 1. Atomic unsigned minimum on word or doubleword in memory
//
//    LDUMIN  <Ws>, <Wt>, [<Xn|SP>]
//    LDUMIN  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic unsigned minimum on word or doubleword in memory atomically loads a
// 32-bit word or 64-bit doubleword from memory, compares it against the value held
// in a register, and stores the smaller value back to memory, treating the values
// as unsigned numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDUMINA and
//       LDUMINAL load from memory with acquire semantics.
//     * LDUMINL and LDUMINAL store to memory with release semantics.
//     * LDUMIN has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMIN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMIN", 3, asm.Operands { v0, v1, v2 })
    // LDUMIN  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    // LDUMIN  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 7, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMIN")
}

// LDUMINA instruction have 2 forms across one single category:
//
// 1. Atomic unsigned minimum on word or doubleword in memory
//
//    LDUMINA  <Ws>, <Wt>, [<Xn|SP>]
//    LDUMINA  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic unsigned minimum on word or doubleword in memory atomically loads a
// 32-bit word or 64-bit doubleword from memory, compares it against the value held
// in a register, and stores the smaller value back to memory, treating the values
// as unsigned numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDUMINA and
//       LDUMINAL load from memory with acquire semantics.
//     * LDUMINL and LDUMINAL store to memory with release semantics.
//     * LDUMIN has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINA", 3, asm.Operands { v0, v1, v2 })
    // LDUMINA  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 0, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    // LDUMINA  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 0, sa_xs, 0, 7, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINA")
}

// LDUMINAB instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on byte in memory
//
//    LDUMINAB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned minimum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the smaller
// value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMINAB and LDUMINALB load
//       from memory with acquire semantics.
//     * LDUMINLB and LDUMINALB store to memory with release semantics.
//     * LDUMINB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINAB")
}

// LDUMINAH instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on halfword in memory
//
//    LDUMINAH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned minimum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// smaller value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMINAH and LDUMINALH load
//       from memory with acquire semantics.
//     * LDUMINLH and LDUMINALH store to memory with release semantics.
//     * LDUMINH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINAH")
}

// LDUMINAL instruction have 2 forms across one single category:
//
// 1. Atomic unsigned minimum on word or doubleword in memory
//
//    LDUMINAL  <Ws>, <Wt>, [<Xn|SP>]
//    LDUMINAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic unsigned minimum on word or doubleword in memory atomically loads a
// 32-bit word or 64-bit doubleword from memory, compares it against the value held
// in a register, and stores the smaller value back to memory, treating the values
// as unsigned numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDUMINA and
//       LDUMINAL load from memory with acquire semantics.
//     * LDUMINL and LDUMINAL store to memory with release semantics.
//     * LDUMIN has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINAL", 3, asm.Operands { v0, v1, v2 })
    // LDUMINAL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 1, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    // LDUMINAL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 1, sa_xs, 0, 7, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINAL")
}

// LDUMINALB instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on byte in memory
//
//    LDUMINALB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned minimum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the smaller
// value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMINAB and LDUMINALB load
//       from memory with acquire semantics.
//     * LDUMINLB and LDUMINALB store to memory with release semantics.
//     * LDUMINB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINALB")
}

// LDUMINALH instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on halfword in memory
//
//    LDUMINALH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned minimum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// smaller value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMINAH and LDUMINALH load
//       from memory with acquire semantics.
//     * LDUMINLH and LDUMINALH store to memory with release semantics.
//     * LDUMINH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINALH")
}

// LDUMINB instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on byte in memory
//
//    LDUMINB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned minimum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the smaller
// value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMINAB and LDUMINALB load
//       from memory with acquire semantics.
//     * LDUMINLB and LDUMINALB store to memory with release semantics.
//     * LDUMINB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINB")
}

// LDUMINH instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on halfword in memory
//
//    LDUMINH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned minimum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// smaller value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMINAH and LDUMINALH load
//       from memory with acquire semantics.
//     * LDUMINLH and LDUMINALH store to memory with release semantics.
//     * LDUMINH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINH")
}

// LDUMINL instruction have 2 forms across one single category:
//
// 1. Atomic unsigned minimum on word or doubleword in memory
//
//    LDUMINL  <Ws>, <Wt>, [<Xn|SP>]
//    LDUMINL  <Xs>, <Xt>, [<Xn|SP>]
//
// Atomic unsigned minimum on word or doubleword in memory atomically loads a
// 32-bit word or 64-bit doubleword from memory, compares it against the value held
// in a register, and stores the smaller value back to memory, treating the values
// as unsigned numbers. The value initially loaded from memory is returned in the
// destination register.
//
//     * If the destination register is not one of WZR or XZR , LDUMINA and
//       LDUMINAL load from memory with acquire semantics.
//     * LDUMINL and LDUMINAL store to memory with release semantics.
//     * LDUMIN has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINL", 3, asm.Operands { v0, v1, v2 })
    // LDUMINL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    // LDUMINL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 7, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINL")
}

// LDUMINLB instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on byte in memory
//
//    LDUMINLB  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned minimum on byte in memory atomically loads an 8-bit byte from
// memory, compares it against the value held in a register, and stores the smaller
// value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMINAB and LDUMINALB load
//       from memory with acquire semantics.
//     * LDUMINLB and LDUMINALB store to memory with release semantics.
//     * LDUMINB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINLB")
}

// LDUMINLH instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on halfword in memory
//
//    LDUMINLH  <Ws>, <Wt>, [<Xn|SP>]
//
// Atomic unsigned minimum on halfword in memory atomically loads a 16-bit halfword
// from memory, compares it against the value held in a register, and stores the
// smaller value back to memory, treating the values as unsigned numbers. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , LDUMINAH and LDUMINALH load
//       from memory with acquire semantics.
//     * LDUMINLH and LDUMINALH store to memory with release semantics.
//     * LDUMINH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) LDUMINLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDUMINLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 7, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDUMINLH")
}

// LDUR instruction have 7 forms across 2 categories:
//
// 1. Load SIMD&FP Register (unscaled offset)
//
//    LDUR  <Bt>, [<Xn|SP>{, #<simm>}]
//    LDUR  <Dt>, [<Xn|SP>{, #<simm>}]
//    LDUR  <Ht>, [<Xn|SP>{, #<simm>}]
//    LDUR  <Qt>, [<Xn|SP>{, #<simm>}]
//    LDUR  <St>, [<Xn|SP>{, #<simm>}]
//
// Load SIMD&FP Register (unscaled offset). This instruction loads a SIMD&FP
// register from memory. The address that is used for the load is calculated from a
// base register value and an optional immediate offset.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Load Register (unscaled)
//
//    LDUR  <Wt>, [<Xn|SP>{, #<simm>}]
//    LDUR  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register (unscaled) calculates an address from a base register and an
// immediate offset, loads a 32-bit word or 64-bit doubleword from memory, zero-
// extends it, and writes it to a register. For information about memory accesses,
// see Load/Store addressing modes .
//
func (self *Program) LDUR(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDUR", 2, asm.Operands { v0, v1 })
    // LDUR  <Bt>, [<Xn|SP>{, #<simm>}]
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(0, 1, 1, sa_simm, sa_xn_sp, sa_bt))
    }
    // LDUR  <Dt>, [<Xn|SP>{, #<simm>}]
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(3, 1, 1, sa_simm, sa_xn_sp, sa_dt))
    }
    // LDUR  <Ht>, [<Xn|SP>{, #<simm>}]
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(1, 1, 1, sa_simm, sa_xn_sp, sa_ht))
    }
    // LDUR  <Qt>, [<Xn|SP>{, #<simm>}]
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(0, 1, 3, sa_simm, sa_xn_sp, sa_qt))
    }
    // LDUR  <St>, [<Xn|SP>{, #<simm>}]
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(2, 1, 1, sa_simm, sa_xn_sp, sa_st))
    }
    // LDUR  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(2, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDUR  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(3, 0, 1, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDUR")
}

// LDURB instruction have one single form across one single category:
//
// 1. Load Register Byte (unscaled)
//
//    LDURB  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Byte (unscaled) calculates an address from a base register and an
// immediate offset, loads a byte from memory, zero-extends it, and writes it to a
// register. For information about memory accesses, see Load/Store addressing modes
// .
//
func (self *Program) LDURB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDURB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(0, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDURB")
}

// LDURH instruction have one single form across one single category:
//
// 1. Load Register Halfword (unscaled)
//
//    LDURH  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Halfword (unscaled) calculates an address from a base register and
// an immediate offset, loads a halfword from memory, zero-extends it, and writes
// it to a register. For information about memory accesses, see Load/Store
// addressing modes .
//
func (self *Program) LDURH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDURH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(1, 0, 1, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDURH")
}

// LDURSB instruction have 2 forms across one single category:
//
// 1. Load Register Signed Byte (unscaled)
//
//    LDURSB  <Wt>, [<Xn|SP>{, #<simm>}]
//    LDURSB  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Signed Byte (unscaled) calculates an address from a base register
// and an immediate offset, loads a signed byte from memory, sign-extends it, and
// writes it to a register. For information about memory accesses, see Load/Store
// addressing modes .
//
func (self *Program) LDURSB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDURSB", 2, asm.Operands { v0, v1 })
    // LDURSB  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(0, 0, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDURSB  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(0, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDURSB")
}

// LDURSH instruction have 2 forms across one single category:
//
// 1. Load Register Signed Halfword (unscaled)
//
//    LDURSH  <Wt>, [<Xn|SP>{, #<simm>}]
//    LDURSH  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Signed Halfword (unscaled) calculates an address from a base
// register and an immediate offset, loads a signed halfword from memory, sign-
// extends it, and writes it to a register. For information about memory accesses,
// see Load/Store addressing modes .
//
func (self *Program) LDURSH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDURSH", 2, asm.Operands { v0, v1 })
    // LDURSH  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(1, 0, 3, sa_simm, sa_xn_sp, sa_wt))
    }
    // LDURSH  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(1, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDURSH")
}

// LDURSW instruction have one single form across one single category:
//
// 1. Load Register Signed Word (unscaled)
//
//    LDURSW  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Load Register Signed Word (unscaled) calculates an address from a base register
// and an immediate offset, loads a signed word from memory, sign-extends it, and
// writes it to a register. For information about memory accesses, see Load/Store
// addressing modes .
//
func (self *Program) LDURSW(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDURSW", 2, asm.Operands { v0, v1 })
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(2, 0, 2, sa_simm, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDURSW")
}

// LDXP instruction have 2 forms across one single category:
//
// 1. Load Exclusive Pair of Registers
//
//    LDXP  <Wt1>, <Wt2>, [<Xn|SP>{,#0}]
//    LDXP  <Xt1>, <Xt2>, [<Xn|SP>{,#0}]
//
// Load Exclusive Pair of Registers derives an address from a base register value,
// loads two 32-bit words or two 64-bit doublewords from memory, and writes them to
// two registers. For information on single-copy atomicity and alignment
// requirements, see Requirements for single-copy atomicity and Alignment of data
// accesses . The PE marks the physical address being accessed as an exclusive
// access. This exclusive access mark is checked by Store Exclusive instructions.
// See Synchronization and semaphores . For information about memory accesses, see
// Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly LDXP .
//
func (self *Program) LDXP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LDXP", 3, asm.Operands { v0, v1, v2 })
    // LDXP  <Wt1>, <Wt2>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclp(0, 1, 31, 0, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // LDXP  <Xt1>, <Xt2>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclp(1, 1, 31, 0, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDXP")
}

// LDXR instruction have 2 forms across one single category:
//
// 1. Load Exclusive Register
//
//    LDXR  <Wt>, [<Xn|SP>{,#0}]
//    LDXR  <Xt>, [<Xn|SP>{,#0}]
//
// Load Exclusive Register derives an address from a base register value, loads a
// 32-bit word or a 64-bit doubleword from memory, and writes it to a register. The
// memory access is atomic. The PE marks the physical address being accessed as an
// exclusive access. This exclusive access mark is checked by Store Exclusive
// instructions. See Synchronization and semaphores . For information about memory
// accesses, see Load/Store addressing modes .
//
func (self *Program) LDXR(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDXR", 2, asm.Operands { v0, v1 })
    // LDXR  <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstexclr(2, 1, 31, 0, 31, sa_xn_sp, sa_wt))
    }
    // LDXR  <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstexclr(3, 1, 31, 0, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LDXR")
}

// LDXRB instruction have one single form across one single category:
//
// 1. Load Exclusive Register Byte
//
//    LDXRB  <Wt>, [<Xn|SP>{,#0}]
//
// Load Exclusive Register Byte derives an address from a base register value,
// loads a byte from memory, zero-extends it and writes it to a register. The
// memory access is atomic. The PE marks the physical address being accessed as an
// exclusive access. This exclusive access mark is checked by Store Exclusive
// instructions. See Synchronization and semaphores . For information about memory
// accesses, see Load/Store addressing modes .
//
func (self *Program) LDXRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDXRB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstexclr(0, 1, 31, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDXRB")
}

// LDXRH instruction have one single form across one single category:
//
// 1. Load Exclusive Register Halfword
//
//    LDXRH  <Wt>, [<Xn|SP>{,#0}]
//
// Load Exclusive Register Halfword derives an address from a base register value,
// loads a halfword from memory, zero-extends it and writes it to a register. The
// memory access is atomic. The PE marks the physical address being accessed as an
// exclusive access. This exclusive access mark is checked by Store Exclusive
// instructions. See Synchronization and semaphores . For information about memory
// accesses, see Load/Store addressing modes .
//
func (self *Program) LDXRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("LDXRH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstexclr(1, 1, 31, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for LDXRH")
}

// LSL instruction have 4 forms across 2 categories:
//
// 1. Logical Shift Left (register)
//
//    LSL  <Wd>, <Wn>, <Wm>
//    LSL  <Xd>, <Xn>, <Xm>
//
// Logical Shift Left (register) shifts a register value left by a variable number
// of bits, shifting in zeros, and writes the result to the destination register.
// The remainder obtained by dividing the second source register by the data size
// defines the number of bits by which the first source register is left-shifted.
//
// 2. Logical Shift Left (immediate)
//
//    LSL  <Wd>, <Wn>, #<shift>
//    LSL  <Xd>, <Xn>, #<shift>
//
// Logical Shift Left (immediate) shifts a register value left by an immediate
// number of bits, shifting in zeros, and writes the result to the destination
// register.
//
func (self *Program) LSL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LSL", 3, asm.Operands { v0, v1, v2 })
    // LSL  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 8, sa_wn, sa_wd))
    }
    // LSL  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 8, sa_xn, sa_xd))
    }
    // LSL  <Wd>, <Wn>, #<shift>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_shift_1 := asLSLShift(v2, 32)
        return p.setins(bitfield(0, 2, 0, ubfx(sa_shift_1, 6, 6), mask(sa_shift_1, 6), sa_wn, sa_wd))
    }
    // LSL  <Xd>, <Xn>, #<shift>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_shift_3 := asLSLShift(v2, 64)
        return p.setins(bitfield(1, 2, 1, ubfx(sa_shift_3, 6, 6), mask(sa_shift_3, 6), sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LSL")
}

// LSLV instruction have 2 forms across one single category:
//
// 1. Logical Shift Left Variable
//
//    LSLV  <Wd>, <Wn>, <Wm>
//    LSLV  <Xd>, <Xn>, <Xm>
//
// Logical Shift Left Variable shifts a register value left by a variable number of
// bits, shifting in zeros, and writes the result to the destination register. The
// remainder obtained by dividing the second source register by the data size
// defines the number of bits by which the first source register is left-shifted.
//
func (self *Program) LSLV(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LSLV", 3, asm.Operands { v0, v1, v2 })
    // LSLV  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 8, sa_wn, sa_wd))
    }
    // LSLV  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 8, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LSLV")
}

// LSR instruction have 4 forms across 2 categories:
//
// 1. Logical Shift Right (register)
//
//    LSR  <Wd>, <Wn>, <Wm>
//    LSR  <Xd>, <Xn>, <Xm>
//
// Logical Shift Right (register) shifts a register value right by a variable
// number of bits, shifting in zeros, and writes the result to the destination
// register. The remainder obtained by dividing the second source register by the
// data size defines the number of bits by which the first source register is
// right-shifted.
//
// 2. Logical Shift Right (immediate)
//
//    LSR  <Wd>, <Wn>, #<shift>
//    LSR  <Xd>, <Xn>, #<shift>
//
// Logical Shift Right (immediate) shifts a register value right by an immediate
// number of bits, shifting in zeros, and writes the result to the destination
// register.
//
func (self *Program) LSR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LSR", 3, asm.Operands { v0, v1, v2 })
    // LSR  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 9, sa_wn, sa_wd))
    }
    // LSR  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 9, sa_xn, sa_xd))
    }
    // LSR  <Wd>, <Wn>, #<shift>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_shift := asUimm6(v2)
        return p.setins(bitfield(0, 2, 0, sa_shift, 31, sa_wn, sa_wd))
    }
    // LSR  <Xd>, <Xn>, #<shift>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_shift_2 := asUimm6(v2)
        return p.setins(bitfield(1, 2, 1, sa_shift_2, 63, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LSR")
}

// LSRV instruction have 2 forms across one single category:
//
// 1. Logical Shift Right Variable
//
//    LSRV  <Wd>, <Wn>, <Wm>
//    LSRV  <Xd>, <Xn>, <Xm>
//
// Logical Shift Right Variable shifts a register value right by a variable number
// of bits, shifting in zeros, and writes the result to the destination register.
// The remainder obtained by dividing the second source register by the data size
// defines the number of bits by which the first source register is right-shifted.
//
func (self *Program) LSRV(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("LSRV", 3, asm.Operands { v0, v1, v2 })
    // LSRV  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 9, sa_wn, sa_wd))
    }
    // LSRV  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 9, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for LSRV")
}

// MADD instruction have 2 forms across one single category:
//
// 1. Multiply-Add
//
//    MADD  <Wd>, <Wn>, <Wm>, <Wa>
//    MADD  <Xd>, <Xn>, <Xm>, <Xa>
//
// Multiply-Add multiplies two register values, adds a third register value, and
// writes the result to the destination register.
//
func (self *Program) MADD(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("MADD", 4, asm.Operands { v0, v1, v2, v3 })
    // MADD  <Wd>, <Wn>, <Wm>, <Wa>
    if isWr(v0) && isWr(v1) && isWr(v2) && isWr(v3) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_wa := uint32(v3.(asm.Register).ID())
        return p.setins(dp_3src(0, 0, 0, sa_wm, 0, sa_wa, sa_wn, sa_wd))
    }
    // MADD  <Xd>, <Xn>, <Xm>, <Xa>
    if isXr(v0) && isXr(v1) && isXr(v2) && isXr(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        sa_xa := uint32(v3.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 0, sa_xm, 0, sa_xa, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MADD")
}

// MLA instruction have 2 forms across 2 categories:
//
// 1. Multiply-Add to accumulator (vector, by element)
//
//    MLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//
// Multiply-Add to accumulator (vector, by element). This instruction multiplies
// the vector elements in the first source SIMD&FP register by the specified value
// in the second source SIMD&FP register, and accumulates the results with the
// vector elements of the destination SIMD&FP register. All the values in this
// instruction are unsigned integer values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Multiply-Add to accumulator (vector)
//
//    MLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Multiply-Add to accumulator (vector). This instruction multiplies corresponding
// elements in the vectors of the two source SIMD&FP registers, and accumulates the
// results with the vector elements of the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) MLA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("MLA", 3, asm.Operands { v0, v1, v2 })
    // MLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != ubfx(sa_t, 1, 2) || ubfx(sa_t, 1, 2) != sa_ts || sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for MLA")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for MLA")
        }
        return p.setins(asimdelem(
            mask(sa_t, 1),
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            0,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // MLA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 18, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MLA")
}

// MLS instruction have 2 forms across 2 categories:
//
// 1. Multiply-Subtract from accumulator (vector, by element)
//
//    MLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//
// Multiply-Subtract from accumulator (vector, by element). This instruction
// multiplies the vector elements in the first source SIMD&FP register by the
// specified value in the second source SIMD&FP register, and subtracts the results
// from the vector elements of the destination SIMD&FP register. All the values in
// this instruction are unsigned integer values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Multiply-Subtract from accumulator (vector)
//
//    MLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Multiply-Subtract from accumulator (vector). This instruction multiplies
// corresponding elements in the vectors of the two source SIMD&FP registers, and
// subtracts the results from the vector elements of the destination SIMD&FP
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) MLS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("MLS", 3, asm.Operands { v0, v1, v2 })
    // MLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != ubfx(sa_t, 1, 2) || ubfx(sa_t, 1, 2) != sa_ts || sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for MLS")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for MLS")
        }
        return p.setins(asimdelem(
            mask(sa_t, 1),
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            4,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // MLS  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 18, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MLS")
}

// MNEG instruction have 2 forms across one single category:
//
// 1. Multiply-Negate
//
//    MNEG  <Wd>, <Wn>, <Wm>
//    MNEG  <Xd>, <Xn>, <Xm>
//
// Multiply-Negate multiplies two register values, negates the product, and writes
// the result to the destination register.
//
func (self *Program) MNEG(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("MNEG", 3, asm.Operands { v0, v1, v2 })
    // MNEG  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(0, 0, 0, sa_wm, 1, 31, sa_wn, sa_wd))
    }
    // MNEG  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 0, sa_xm, 1, 31, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MNEG")
}

// MOV instruction have 16 forms across 10 categories:
//
// 1. Move between register and stack pointer
//
//    MOV  <Wd|WSP>, <Wn|WSP>
//    MOV  <Xd|SP>, <Xn|SP>
//
// 2. Move vector element to scalar
//
//    MOV  <V><d>, <Vn>.<T>[<index>]
//
// Move vector element to scalar. This instruction duplicates the specified vector
// element in the SIMD&FP source register into a scalar, and writes the result to
// the SIMD&FP destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 3. Move vector element to another vector element
//
//    MOV  <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]
//
// Move vector element to another vector element. This instruction copies the
// vector element of the source SIMD&FP register to the specified vector element of
// the destination SIMD&FP register.
//
// This instruction can insert data into individual elements within a SIMD&FP
// register without clearing the remaining bits to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 4. Move general-purpose register to a vector element
//
//    MOV  <Vd>.<Ts>[<index>], <R><n>
//
// Move general-purpose register to a vector element. This instruction copies the
// contents of the source general-purpose register to the specified vector element
// in the destination SIMD&FP register.
//
// This instruction can insert data into individual elements within a SIMD&FP
// register without clearing the remaining bits to zero.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 5. Move (inverted wide immediate)
//
//    MOV  <Wd>, #<imm>
//    MOV  <Xd>, #<imm>
//
// Move (inverted wide immediate) moves an inverted 16-bit immediate value to a
// register.
//
// 6. Move (wide immediate)
//
//    MOV  <Wd>, #<imm>
//    MOV  <Xd>, #<imm>
//
// Move (wide immediate) moves a 16-bit immediate value to a register.
//
// 7. Move vector
//
//    MOV  <Vd>.<T>, <Vn>.<T>
//
// Move vector. This instruction copies the vector in the source SIMD&FP register
// into the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 8. Move (bitmask immediate)
//
//    MOV  <Wd|WSP>, #<imm>
//    MOV  <Xd|SP>, #<imm>
//
// Move (bitmask immediate) writes a bitmask immediate value to a register.
//
// 9. Move (register)
//
//    MOV  <Wd>, <Wm>
//    MOV  <Xd>, <Xm>
//
// Move (register) copies the value in a source register to the destination
// register.
//
// 10. Move vector element to general-purpose register
//
//    MOV  <Wd>, <Vn>.S[<index>]
//    MOV  <Xd>, <Vn>.D[<index>]
//
// Move vector element to general-purpose register. This instruction reads the
// unsigned integer from the source SIMD&FP register, zero-extends it to form a
// 32-bit or 64-bit value, and writes the result to the destination general-purpose
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) MOV(v0, v1 interface{}) *Instruction {
    p := self.alloc("MOV", 2, asm.Operands { v0, v1 })
    // MOV  <Wd|WSP>, <Wn|WSP>
    if isWrOrWSP(v0) && isWrOrWSP(v1) && (v0 == WSP || v1 == WSP) {
        p.Domain = asm.DomainGeneric
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        return p.setins(addsub_imm(0, 0, 0, 0, 0, sa_wn_wsp, sa_wd_wsp))
    }
    // MOV  <Xd|SP>, <Xn|SP>
    if isXrOrSP(v0) && isXrOrSP(v1) && (v0 == SP || v1 == SP) {
        p.Domain = asm.DomainGeneric
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        return p.setins(addsub_imm(1, 0, 0, 0, 0, sa_xn_sp, sa_xd_sp))
    }
    // MOV  <V><d>, <Vn>.<T>[<index>]
    if isAdvSIMD(v0) && isVri(v1) {
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        var sa_t_1__bit_mask uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00001
            case HRegister: sa_v = 0b00010
            case SRegister: sa_v = 0b00100
            case DRegister: sa_v = 0b01000
            default: panic("aarch64: invalid scalar operand size for MOV")
        }
        switch v0.(type) {
            case BRegister: sa_v__bit_mask = 0b00001
            case HRegister: sa_v__bit_mask = 0b00011
            case SRegister: sa_v__bit_mask = 0b00111
            case DRegister: sa_v__bit_mask = 0b01111
            default: panic("aarch64: invalid scalar operand size for MOV")
        }
        sa_vn := uint32(v1.(VidxRegister).ID())
        switch vmoder(v1) {
            case ModeB: sa_t_1 = 0b00001
            case ModeH: sa_t_1 = 0b00010
            case ModeS: sa_t_1 = 0b00100
            case ModeD: sa_t_1 = 0b01000
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v1) {
            case ModeB: sa_t_1__bit_mask = 0b00001
            case ModeH: sa_t_1__bit_mask = 0b00011
            case ModeS: sa_t_1__bit_mask = 0b00111
            case ModeD: sa_t_1__bit_mask = 0b01111
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v1))
        if sa_index != sa_t_1 & sa_t_1__bit_mask || sa_t_1 & sa_t_1__bit_mask != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for MOV")
        }
        return p.setins(asisdone(0, sa_index, 0, sa_vn, sa_d))
    }
    // MOV  <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]
    if isVri(v0) && isVri(v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_ts__bit_mask uint32
        sa_vd := uint32(v0.(VidxRegister).ID())
        switch vmoder(v0) {
            case ModeB: sa_ts = 0b00001
            case ModeH: sa_ts = 0b00010
            case ModeS: sa_ts = 0b00100
            case ModeD: sa_ts = 0b01000
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v0) {
            case ModeB: sa_ts__bit_mask = 0b00001
            case ModeH: sa_ts__bit_mask = 0b00011
            case ModeS: sa_ts__bit_mask = 0b00111
            case ModeD: sa_ts__bit_mask = 0b01111
            default: panic("aarch64: unreachable")
        }
        sa_index1 := uint32(vidxr(v0))
        sa_vn := uint32(v1.(VidxRegister).ID())
        sa_index2 := uint32(vidxr(v1))
        if sa_index1 != ubfx(sa_index2, 4, 5) || ubfx(sa_index2, 4, 5) != sa_ts & sa_ts__bit_mask {
            panic("aarch64: invalid combination of operands for MOV")
        }
        return p.setins(asimdins(1, 1, sa_index1, mask(sa_index2, 4), sa_vn, sa_vd))
    }
    // MOV  <Vd>.<Ts>[<index>], <R><n>
    if isVri(v0) && isWrOrXr(v1) {
        p.Domain = DomainAdvSimd
        var sa_r [3]uint32
        var sa_r__bit_mask [3]uint32
        var sa_ts uint32
        var sa_ts__bit_mask uint32
        sa_vd := uint32(v0.(VidxRegister).ID())
        switch vmoder(v0) {
            case ModeB: sa_ts = 0b00001
            case ModeH: sa_ts = 0b00010
            case ModeS: sa_ts = 0b00100
            case ModeD: sa_ts = 0b01000
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v0) {
            case ModeB: sa_ts__bit_mask = 0b00001
            case ModeH: sa_ts__bit_mask = 0b00011
            case ModeS: sa_ts__bit_mask = 0b00111
            case ModeD: sa_ts__bit_mask = 0b01111
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v0))
        sa_n := uint32(v1.(asm.Register).ID())
        switch true {
            case isWr(v1): sa_r = [3]uint32{0b00100, 0b00010, 0b00001}
            case isXr(v1): sa_r = [3]uint32{0b01000}
            default: panic("aarch64: unreachable")
        }
        switch true {
            case isWr(v1): sa_r__bit_mask = [3]uint32{0b00111, 0b00011, 0b00001}
            case isXr(v1): sa_r__bit_mask = [3]uint32{0b01111}
            default: panic("aarch64: unreachable")
        }
        if sa_index != sa_ts & sa_ts__bit_mask || !matchany(sa_ts & sa_ts__bit_mask, &sa_r[0], &sa_r__bit_mask[0], 3) {
            panic("aarch64: invalid combination of operands for MOV")
        }
        return p.setins(asimdins(1, 0, sa_index, 3, sa_n, sa_vd))
    }
    // MOV  <Wd>, #<imm>
    if isWr(v0) && isMOVxImm(v1, 32, true) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_imm_1 := asMOVxImm(v1, 32, true)
        return p.setins(movewide(0, 0, ubfx(sa_imm_1, 16, 2), mask(sa_imm_1, 16), sa_wd))
    }
    // MOV  <Xd>, #<imm>
    if isXr(v0) && isMOVxImm(v1, 64, true) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_imm_2 := asMOVxImm(v1, 64, true)
        return p.setins(movewide(1, 0, ubfx(sa_imm_2, 16, 2), mask(sa_imm_2, 16), sa_xd))
    }
    // MOV  <Wd>, #<imm>
    if isWr(v0) && isMOVxImm(v1, 32, false) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_imm_1 := asMOVxImm(v1, 32, false)
        return p.setins(movewide(0, 2, ubfx(sa_imm_1, 16, 2), mask(sa_imm_1, 16), sa_wd))
    }
    // MOV  <Xd>, #<imm>
    if isXr(v0) && isMOVxImm(v1, 64, false) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_imm_2 := asMOVxImm(v1, 64, false)
        return p.setins(movewide(1, 2, ubfx(sa_imm_2, 16, 2), mask(sa_imm_2, 16), sa_xd))
    }
    // MOV  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec8B, Vec16B) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B) && vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdsame(sa_t, 0, 2, ubfx(sa_vn, 5, 5), 3, mask(sa_vn, 5), sa_vd))
    }
    // MOV  <Wd|WSP>, #<imm>
    if isWrOrWSP(v0) && isMask32(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_imm_2 := asMaskOp(v1)
        return p.setins(log_imm(0, 1, 0, ubfx(sa_imm_2, 6, 6), mask(sa_imm_2, 6), 31, sa_wd_wsp))
    }
    // MOV  <Xd|SP>, #<imm>
    if isXrOrSP(v0) && isMask64(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_imm_3 := asMaskOp(v1)
        return p.setins(log_imm(1, 1, ubfx(sa_imm_3, 12, 1), ubfx(sa_imm_3, 6, 6), mask(sa_imm_3, 6), 31, sa_xd_sp))
    }
    // MOV  <Wd>, <Wm>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wm_1 := uint32(v1.(asm.Register).ID())
        return p.setins(log_shift(0, 1, 0, 0, sa_wm_1, 0, 31, sa_wd))
    }
    // MOV  <Xd>, <Xm>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xm_1 := uint32(v1.(asm.Register).ID())
        return p.setins(log_shift(1, 1, 0, 0, sa_xm_1, 0, 31, sa_xd))
    }
    // MOV  <Wd>, <Vn>.S[<index>]
    if isWr(v0) && isVri(v1) && vmoder(v1) == ModeS {
        p.Domain = DomainAdvSimd
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(VidxRegister).ID())
        sa_index_2 := uint32(vidxr(v1))
        return p.setins(asimdins(0, 0, sa_index_2, 7, sa_vn, sa_wd))
    }
    // MOV  <Xd>, <Vn>.D[<index>]
    if isXr(v0) && isVri(v1) && vmoder(v1) == ModeD {
        p.Domain = DomainAdvSimd
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(VidxRegister).ID())
        sa_index_1 := uint32(vidxr(v1))
        return p.setins(asimdins(1, 0, sa_index_1, 7, sa_vn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MOV")
}

// MOVI instruction have 6 forms across one single category:
//
// 1. Move Immediate (vector)
//
//    MOVI  <Vd>.2D, #<imm>
//    MOVI  <Dd>, #<imm>
//    MOVI  <Vd>.<T>, #<imm8>{, LSL #<amount>}
//    MOVI  <Vd>.<T>, #<imm8>{, LSL #<amount>}
//    MOVI  <Vd>.<T>, #<imm8>, MSL #<amount>
//    MOVI  <Vd>.<T>, #<imm8>{, LSL #0}
//
// Move Immediate (vector). This instruction places an immediate constant into
// every vector element of the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) MOVI(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("MOVI", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("MOVI", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction MOVI takes 2 or 3 operands")
    }
    // MOVI  <Vd>.2D, #<imm>
    if isVr(v0) && vfmt(v0) == Vec2D && isUimm8(v1) {
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm8(v1)
        return p.setins(asimdimm(
            1,
            1,
            ubfx(sa_imm, 7, 1),
            ubfx(sa_imm, 6, 1),
            ubfx(sa_imm, 5, 1),
            14,
            0,
            ubfx(sa_imm, 4, 1),
            ubfx(sa_imm, 3, 1),
            ubfx(sa_imm, 2, 1),
            ubfx(sa_imm, 1, 1),
            mask(sa_imm, 1),
            sa_vd,
        ))
    }
    // MOVI  <Dd>, #<imm>
    if isDr(v0) && isUimm8(v1) {
        p.Domain = DomainAdvSimd
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm8(v1)
        return p.setins(asimdimm(
            0,
            1,
            ubfx(sa_imm, 7, 1),
            ubfx(sa_imm, 6, 1),
            ubfx(sa_imm, 5, 1),
            14,
            0,
            ubfx(sa_imm, 4, 1),
            ubfx(sa_imm, 3, 1),
            ubfx(sa_imm, 2, 1),
            ubfx(sa_imm, 1, 1),
            mask(sa_imm, 1),
            sa_dd,
        ))
    }
    // MOVI  <Vd>.<T>, #<imm8>{, LSL #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isUimm8(v1) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = DomainAdvSimd
        sa_amount := uint32(0b0)
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 8: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b1000)
        switch sa_amount {
            case 0: cmode |= 0b0 << 1
            case 8: cmode |= 0b1 << 1
            default: panic("aarch64: invalid combination of operands for MOVI")
        }
        return p.setins(asimdimm(
            sa_t,
            0,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // MOVI  <Vd>.<T>, #<imm8>{, LSL #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isUimm8(v1) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = DomainAdvSimd
        sa_amount_1 := uint32(0b00)
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b0
            case Vec4S: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 0: sa_amount_1 = 0b00
            case 8: sa_amount_1 = 0b01
            case 16: sa_amount_1 = 0b10
            case 24: sa_amount_1 = 0b11
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b0000)
        switch sa_amount_1 {
            case 0: cmode |= 0b00 << 1
            case 8: cmode |= 0b01 << 1
            case 16: cmode |= 0b10 << 1
            case 24: cmode |= 0b11 << 1
            default: panic("aarch64: invalid combination of operands for MOVI")
        }
        return p.setins(asimdimm(
            sa_t_1,
            0,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // MOVI  <Vd>.<T>, #<imm8>, MSL #<amount>
    if len(vv) == 1 && isVr(v0) && isVfmt(v0, Vec2S, Vec4S) && isUimm8(v1) && modt(vv[0]) == ModMSL {
        p.Domain = DomainAdvSimd
        var sa_amount_2 uint32
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b0
            case Vec4S: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 8: sa_amount_2 = 0b0
            case 16: sa_amount_2 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b1100)
        switch sa_amount_2 {
            case 8: cmode |= 0b0 << 0
            case 16: cmode |= 0b1 << 0
            default: panic("aarch64: invalid combination of operands for MOVI")
        }
        return p.setins(asimdimm(
            sa_t_1,
            0,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // MOVI  <Vd>.<T>, #<imm8>{, LSL #0}
    if (len(vv) == 0 || len(vv) == 1) &&
       isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isUimm8(v1) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL && modn(vv[0]) == 0) {
        p.Domain = DomainAdvSimd
        var sa_t_2 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t_2 = 0b0
            case Vec16B: sa_t_2 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        return p.setins(asimdimm(
            sa_t_2,
            0,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            14,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MOVI")
}

// MOVK instruction have 2 forms across one single category:
//
// 1. Move wide with keep
//
//    MOVK  <Wd>, #<imm>{, LSL #<shift>}
//    MOVK  <Xd>, #<imm>{, LSL #<shift>}
//
// Move wide with keep moves an optionally-shifted 16-bit immediate value into a
// register, keeping other bits unchanged.
//
func (self *Program) MOVK(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("MOVK", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("MOVK", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction MOVK takes 2 or 3 operands")
    }
    // MOVK  <Wd>, #<imm>{, LSL #<shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isInRange(v1, 0, 65535) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm16(v1)
        if len(vv) >= 1 {
            sa_shift = asMOVxShift(vv[0], 32)
        }
        return p.setins(movewide(0, 3, sa_shift, sa_imm, sa_wd))
    }
    // MOVK  <Xd>, #<imm>{, LSL #<shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isInRange(v1, 0, 65535) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_shift_1 uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm16(v1)
        if len(vv) >= 1 {
            sa_shift_1 = asMOVxShift(vv[0], 64)
        }
        return p.setins(movewide(1, 3, sa_shift_1, sa_imm, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MOVK")
}

// MOVN instruction have 2 forms across one single category:
//
// 1. Move wide with NOT
//
//    MOVN  <Wd>, #<imm>{, LSL #<shift>}
//    MOVN  <Xd>, #<imm>{, LSL #<shift>}
//
// Move wide with NOT moves the inverse of an optionally-shifted 16-bit immediate
// value to a register.
//
func (self *Program) MOVN(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("MOVN", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("MOVN", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction MOVN takes 2 or 3 operands")
    }
    // MOVN  <Wd>, #<imm>{, LSL #<shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isInRange(v1, 0, 65535) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm16(v1)
        if len(vv) >= 1 {
            sa_shift = asMOVxShift(vv[0], 32)
        }
        return p.setins(movewide(0, 0, sa_shift, sa_imm, sa_wd))
    }
    // MOVN  <Xd>, #<imm>{, LSL #<shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isInRange(v1, 0, 65535) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_shift_1 uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm16(v1)
        if len(vv) >= 1 {
            sa_shift_1 = asMOVxShift(vv[0], 64)
        }
        return p.setins(movewide(1, 0, sa_shift_1, sa_imm, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MOVN")
}

// MOVZ instruction have 2 forms across one single category:
//
// 1. Move wide with zero
//
//    MOVZ  <Wd>, #<imm>{, LSL #<shift>}
//    MOVZ  <Xd>, #<imm>{, LSL #<shift>}
//
// Move wide with zero moves an optionally-shifted 16-bit immediate value to a
// register.
//
func (self *Program) MOVZ(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("MOVZ", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("MOVZ", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction MOVZ takes 2 or 3 operands")
    }
    // MOVZ  <Wd>, #<imm>{, LSL #<shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isInRange(v1, 0, 65535) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm16(v1)
        if len(vv) >= 1 {
            sa_shift = asMOVxShift(vv[0], 32)
        }
        return p.setins(movewide(0, 2, sa_shift, sa_imm, sa_wd))
    }
    // MOVZ  <Xd>, #<imm>{, LSL #<shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isInRange(v1, 0, 65535) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_shift_1 uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_imm := asUimm16(v1)
        if len(vv) >= 1 {
            sa_shift_1 = asMOVxShift(vv[0], 64)
        }
        return p.setins(movewide(1, 2, sa_shift_1, sa_imm, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MOVZ")
}

// MRRS instruction have one single form across one single category:
//
// 1. Move System Register to two adjacent general-purpose registers
//
//    MRRS  <Xt>, <Xt+1>, (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>)
//
// Move System Register to two adjacent general-purpose registers allows the PE to
// read an AArch64 128-bit System register into two adjacent 64-bit general-purpose
// registers.
//
func (self *Program) MRRS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("MRRS", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isXr(v1) && isNextReg(v1, v0, 1) && isSysReg(v2) {
        self.Arch.Require(FEAT_SYSREG128)
        p.Domain = DomainSystem
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_systemreg := v2.(SystemRegister).r()
        return p.setins(systemmovepr(
            1,
            ubfx(sa_systemreg, 6, 1),
            ubfx(sa_systemreg, 3, 3),
            ubfx(sa_systemreg, 7, 4),
            ubfx(sa_systemreg, 11, 4),
            mask(sa_systemreg, 3),
            sa_xt,
        ))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for MRRS")
}

// MRS instruction have one single form across one single category:
//
// 1. Move System Register to general-purpose register
//
//    MRS  <Xt>, (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>)
//
// Move System Register to general-purpose register allows the PE to read an
// AArch64 System register into a general-purpose register.
//
func (self *Program) MRS(v0, v1 interface{}) *Instruction {
    p := self.alloc("MRS", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isSysReg(v1) {
        p.Domain = DomainSystem
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_systemreg := v1.(SystemRegister).r()
        return p.setins(systemmove(
            1,
            ubfx(sa_systemreg, 6, 1),
            ubfx(sa_systemreg, 3, 3),
            ubfx(sa_systemreg, 7, 4),
            ubfx(sa_systemreg, 11, 4),
            mask(sa_systemreg, 3),
            sa_xt,
        ))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for MRS")
}

// MSR instruction have 2 forms across 2 categories:
//
// 1. Move immediate value to Special Register
//
//    MSR  <pstatefield>, #<imm>
//
// Move immediate value to Special Register moves an immediate value to selected
// bits of the PSTATE. For more information, see Process state, PSTATE .
//
// The bits that can be written by this instruction are:
//
//     * PSTATE.D, PSTATE.A, PSTATE.I, PSTATE.F, and PSTATE.SP.
//     * If FEAT_SSBS is implemented, PSTATE.SSBS.
//     * If FEAT_PAN is implemented, PSTATE.PAN.
//     * If FEAT_UAO is implemented, PSTATE.UAO.
//     * If FEAT_DIT is implemented, PSTATE.DIT.
//     * If FEAT_MTE is implemented, PSTATE.TCO.
//     * If FEAT_NMI is implemented, PSTATE.ALLINT.
//     * If FEAT_SME is implemented, PSTATE.SM and PSTATE.ZA.
//     * If FEAT_EBEP is implemented, PSTATE.PM.
//
// 2. Move general-purpose register to System Register
//
//    MSR  (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>), <Xt>
//
// Move general-purpose register to System Register allows the PE to write an
// AArch64 System register from a general-purpose register.
//
func (self *Program) MSR(v0, v1 interface{}) *Instruction {
    p := self.alloc("MSR", 2, asm.Operands { v0, v1 })
    // MSR  <pstatefield>, #<imm>
    if isPStateField(v0) && isPStateImm(v0, v1) {
        p.Domain = DomainSystem
        sa_pstatefield := asPStateField(v0).encode()
        sa_imm := asPStateImm(sa_pstatefield, v1)
        return p.setins(pstate(ubfx(sa_pstatefield, 7, 3), sa_imm, ubfx(sa_pstatefield, 4, 3), 31))
    }
    // MSR  (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>), <Xt>
    if isSysReg(v0) && isXr(v1) {
        p.Domain = DomainSystem
        sa_systemreg := v0.(SystemRegister).w()
        sa_xt := uint32(v1.(asm.Register).ID())
        return p.setins(systemmove(
            0,
            ubfx(sa_systemreg, 6, 1),
            ubfx(sa_systemreg, 3, 3),
            ubfx(sa_systemreg, 7, 4),
            ubfx(sa_systemreg, 11, 4),
            mask(sa_systemreg, 3),
            sa_xt,
        ))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MSR")
}

// MSRR instruction have one single form across one single category:
//
// 1. Move two adjacent general-purpose registers to System Register
//
//    MSRR  (<systemreg>|S<op0>_<op1>_<Cn>_<Cm>_<op2>), <Xt>, <Xt+1>
//
// Move two adjacent general-purpose registers to System Register allows the PE to
// write an AArch64 128-bit System register from two adjacent 64-bit general-
// purpose registers.
//
func (self *Program) MSRR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("MSRR", 3, asm.Operands { v0, v1, v2 })
    if isSysReg(v0) && isXr(v1) && isXr(v2) && isNextReg(v2, v1, 1) {
        self.Arch.Require(FEAT_SYSREG128)
        p.Domain = DomainSystem
        sa_systemreg := v0.(SystemRegister).w()
        sa_xt := uint32(v1.(asm.Register).ID())
        return p.setins(systemmovepr(
            0,
            ubfx(sa_systemreg, 6, 1),
            ubfx(sa_systemreg, 3, 3),
            ubfx(sa_systemreg, 7, 4),
            ubfx(sa_systemreg, 11, 4),
            mask(sa_systemreg, 3),
            sa_xt,
        ))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for MSRR")
}

// MSUB instruction have 2 forms across one single category:
//
// 1. Multiply-Subtract
//
//    MSUB  <Wd>, <Wn>, <Wm>, <Wa>
//    MSUB  <Xd>, <Xn>, <Xm>, <Xa>
//
// Multiply-Subtract multiplies two register values, subtracts the product from a
// third register value, and writes the result to the destination register.
//
func (self *Program) MSUB(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("MSUB", 4, asm.Operands { v0, v1, v2, v3 })
    // MSUB  <Wd>, <Wn>, <Wm>, <Wa>
    if isWr(v0) && isWr(v1) && isWr(v2) && isWr(v3) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_wa := uint32(v3.(asm.Register).ID())
        return p.setins(dp_3src(0, 0, 0, sa_wm, 1, sa_wa, sa_wn, sa_wd))
    }
    // MSUB  <Xd>, <Xn>, <Xm>, <Xa>
    if isXr(v0) && isXr(v1) && isXr(v2) && isXr(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        sa_xa := uint32(v3.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 0, sa_xm, 1, sa_xa, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MSUB")
}

// MUL instruction have 4 forms across 3 categories:
//
// 1. Multiply
//
//    MUL  <Wd>, <Wn>, <Wm>
//    MUL  <Xd>, <Xn>, <Xm>
//
// 2. Multiply (vector, by element)
//
//    MUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//
// Multiply (vector, by element). This instruction multiplies the vector elements
// in the first source SIMD&FP register by the specified value in the second source
// SIMD&FP register, places the results in a vector, and writes the vector to the
// destination SIMD&FP register. All the values in this instruction are unsigned
// integer values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 3. Multiply (vector)
//
//    MUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Multiply (vector). This instruction multiplies corresponding elements in the
// vectors of the two source SIMD&FP registers, places the results in a vector, and
// writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) MUL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("MUL", 3, asm.Operands { v0, v1, v2 })
    // MUL  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(0, 0, 0, sa_wm, 0, 31, sa_wn, sa_wd))
    }
    // MUL  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 0, sa_xm, 0, 31, sa_xn, sa_xd))
    }
    // MUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != ubfx(sa_t, 1, 2) || ubfx(sa_t, 1, 2) != sa_ts || sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for MUL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for MUL")
        }
        return p.setins(asimdelem(
            mask(sa_t, 1),
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            8,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // MUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 19, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MUL")
}

// MVN instruction have 3 forms across 2 categories:
//
// 1. Bitwise NOT (vector)
//
//    MVN  <Vd>.<T>, <Vn>.<T>
//
// Bitwise NOT (vector). This instruction reads each vector element from the source
// SIMD&FP register, places the inverse of each value into a vector, and writes the
// vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Bitwise NOT
//
//    MVN  <Wd>, <Wm>{, <shift> #<amount>}
//    MVN  <Xd>, <Xm>{, <shift> #<amount>}
//
// Bitwise NOT writes the bitwise inverse of a register value to the destination
// register.
//
func (self *Program) MVN(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("MVN", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("MVN", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction MVN takes 2 or 3 operands")
    }
    // MVN  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec8B, Vec16B) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B) && vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(sa_t, 1, 0, 5, sa_vn, sa_vd))
    }
    // MVN  <Wd>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wm_1 := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 1, sa_shift, 1, sa_wm_1, sa_amount, 31, sa_wd))
    }
    // MVN  <Xd>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xm_1 := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 1, sa_shift, 1, sa_xm_1, sa_amount_1, 31, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MVN")
}

// MVNI instruction have 3 forms across one single category:
//
// 1. Move inverted Immediate (vector)
//
//    MVNI  <Vd>.<T>, #<imm8>{, LSL #<amount>}
//    MVNI  <Vd>.<T>, #<imm8>{, LSL #<amount>}
//    MVNI  <Vd>.<T>, #<imm8>, MSL #<amount>
//
// Move inverted Immediate (vector). This instruction places the inverse of an
// immediate constant into every vector element of the destination SIMD&FP
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) MVNI(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("MVNI", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("MVNI", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction MVNI takes 2 or 3 operands")
    }
    // MVNI  <Vd>.<T>, #<imm8>{, LSL #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isUimm8(v1) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = DomainAdvSimd
        sa_amount := uint32(0b0)
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 8: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b1000)
        switch sa_amount {
            case 0: cmode |= 0b0 << 1
            case 8: cmode |= 0b1 << 1
            default: panic("aarch64: invalid combination of operands for MVNI")
        }
        return p.setins(asimdimm(
            sa_t,
            1,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // MVNI  <Vd>.<T>, #<imm8>{, LSL #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isUimm8(v1) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = DomainAdvSimd
        sa_amount_1 := uint32(0b00)
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b0
            case Vec4S: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 0: sa_amount_1 = 0b00
            case 8: sa_amount_1 = 0b01
            case 16: sa_amount_1 = 0b10
            case 24: sa_amount_1 = 0b11
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b0000)
        switch sa_amount_1 {
            case 0: cmode |= 0b00 << 1
            case 8: cmode |= 0b01 << 1
            case 16: cmode |= 0b10 << 1
            case 24: cmode |= 0b11 << 1
            default: panic("aarch64: invalid combination of operands for MVNI")
        }
        return p.setins(asimdimm(
            sa_t_1,
            1,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // MVNI  <Vd>.<T>, #<imm8>, MSL #<amount>
    if len(vv) == 1 && isVr(v0) && isVfmt(v0, Vec2S, Vec4S) && isUimm8(v1) && modt(vv[0]) == ModMSL {
        p.Domain = DomainAdvSimd
        var sa_amount_2 uint32
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b0
            case Vec4S: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 8: sa_amount_2 = 0b0
            case 16: sa_amount_2 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b1100)
        switch sa_amount_2 {
            case 8: cmode |= 0b0 << 0
            case 16: cmode |= 0b1 << 0
            default: panic("aarch64: invalid combination of operands for MVNI")
        }
        return p.setins(asimdimm(
            sa_t_1,
            1,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for MVNI")
}

// NEG instruction have 4 forms across 2 categories:
//
// 1. Negate (shifted register)
//
//    NEG  <Wd>, <Wm>{, <shift> #<amount>}
//    NEG  <Xd>, <Xm>{, <shift> #<amount>}
//
// Negate (shifted register) negates an optionally-shifted register value, and
// writes the result to the destination register.
//
// 2. Negate (vector)
//
//    NEG  <Vd>.<T>, <Vn>.<T>
//    NEG  <V><d>, <V><n>
//
// Negate (vector). This instruction reads each vector element from the source
// SIMD&FP register, negates each value, puts the result into a vector, and writes
// the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) NEG(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("NEG", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("NEG", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction NEG takes 2 or 3 operands")
    }
    // NEG  <Wd>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wm_1 := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(0, 1, 0, sa_shift, sa_wm_1, sa_amount, 31, sa_wd))
    }
    // NEG  <Xd>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xm_1 := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(1, 1, 0, sa_shift, sa_xm_1, sa_amount_1, 31, sa_xd))
    }
    // NEG  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 11, sa_vn, sa_vd))
    }
    // NEG  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for NEG")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(1, sa_v, 11, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for NEG")
}

// NEGS instruction have 2 forms across one single category:
//
// 1. Negate, setting flags
//
//    NEGS  <Wd>, <Wm>{, <shift> #<amount>}
//    NEGS  <Xd>, <Xm>{, <shift> #<amount>}
//
// Negate, setting flags, negates an optionally-shifted register value, and writes
// the result to the destination register. It updates the condition flags based on
// the result.
//
func (self *Program) NEGS(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("NEGS", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("NEGS", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction NEGS takes 2 or 3 operands")
    }
    // NEGS  <Wd>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wm_1 := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(0, 1, 1, sa_shift, sa_wm_1, sa_amount, 31, sa_wd))
    }
    // NEGS  <Xd>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xm_1 := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(1, 1, 1, sa_shift, sa_xm_1, sa_amount_1, 31, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for NEGS")
}

// NGC instruction have 2 forms across one single category:
//
// 1. Negate with Carry
//
//    NGC  <Wd>, <Wm>
//    NGC  <Xd>, <Xm>
//
// Negate with Carry negates the sum of a register value and the value of NOT
// (Carry flag), and writes the result to the destination register.
//
func (self *Program) NGC(v0, v1 interface{}) *Instruction {
    p := self.alloc("NGC", 2, asm.Operands { v0, v1 })
    // NGC  <Wd>, <Wm>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wm_1 := uint32(v1.(asm.Register).ID())
        return p.setins(addsub_carry(0, 1, 0, sa_wm_1, 31, sa_wd))
    }
    // NGC  <Xd>, <Xm>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xm_1 := uint32(v1.(asm.Register).ID())
        return p.setins(addsub_carry(1, 1, 0, sa_xm_1, 31, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for NGC")
}

// NGCS instruction have 2 forms across one single category:
//
// 1. Negate with Carry, setting flags
//
//    NGCS  <Wd>, <Wm>
//    NGCS  <Xd>, <Xm>
//
// Negate with Carry, setting flags, negates the sum of a register value and the
// value of NOT (Carry flag), and writes the result to the destination register. It
// updates the condition flags based on the result.
//
func (self *Program) NGCS(v0, v1 interface{}) *Instruction {
    p := self.alloc("NGCS", 2, asm.Operands { v0, v1 })
    // NGCS  <Wd>, <Wm>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wm_1 := uint32(v1.(asm.Register).ID())
        return p.setins(addsub_carry(0, 1, 1, sa_wm_1, 31, sa_wd))
    }
    // NGCS  <Xd>, <Xm>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xm_1 := uint32(v1.(asm.Register).ID())
        return p.setins(addsub_carry(1, 1, 1, sa_xm_1, 31, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for NGCS")
}

// NOP instruction have one single form across one single category:
//
// 1. No Operation
//
//    NOP
//
// No Operation does nothing, other than advance the value of the program counter
// by 4. This instruction can be used for instruction alignment purposes.
//
// NOTE: 
//     The timing effects of including a NOP instruction in a program are not
//     guaranteed. It can increase execution time, leave it unchanged, or even
//     reduce it. Therefore, NOP instructions are not suitable for timing
//     loops.
//
func (self *Program) NOP() *Instruction {
    p := self.alloc("NOP", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(hints(0, 0))
}

// NOT instruction have one single form across one single category:
//
// 1. Bitwise NOT (vector)
//
//    NOT  <Vd>.<T>, <Vn>.<T>
//
// Bitwise NOT (vector). This instruction reads each vector element from the source
// SIMD&FP register, places the inverse of each value into a vector, and writes the
// vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) NOT(v0, v1 interface{}) *Instruction {
    p := self.alloc("NOT", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec8B, Vec16B) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B) && vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(sa_t, 1, 0, 5, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for NOT")
}

// ORN instruction have 3 forms across 2 categories:
//
// 1. Bitwise inclusive OR NOT (vector)
//
//    ORN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Bitwise inclusive OR NOT (vector). This instruction performs a bitwise OR NOT
// between the two source SIMD&FP registers, and writes the result to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Bitwise OR NOT (shifted register)
//
//    ORN  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    ORN  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Bitwise OR NOT (shifted register) performs a bitwise (inclusive) OR of a
// register value and the complement of an optionally-shifted register value, and
// writes the result to the destination register.
//
func (self *Program) ORN(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("ORN", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("ORN", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction ORN takes 3 or 4 operands")
    }
    // ORN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(sa_t, 0, 3, sa_vm, 3, sa_vn, sa_vd))
    }
    // ORN  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 1, sa_shift, 1, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // ORN  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 1, sa_shift, 1, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ORN")
}

// ORR instruction have 7 forms across 4 categories:
//
// 1. Bitwise inclusive OR (vector, immediate)
//
//    ORR  <Vd>.<T>, #<imm8>{, LSL #<amount>}
//    ORR  <Vd>.<T>, #<imm8>{, LSL #<amount>}
//
// Bitwise inclusive OR (vector, immediate). This instruction reads each vector
// element from the destination SIMD&FP register, performs a bitwise OR between
// each result and an immediate constant, places the result into a vector, and
// writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Bitwise inclusive OR (vector, register)
//
//    ORR  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Bitwise inclusive OR (vector, register). This instruction performs a bitwise OR
// between the two source SIMD&FP registers, and writes the result to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 3. Bitwise OR (immediate)
//
//    ORR  <Wd|WSP>, <Wn>, #<imm>
//    ORR  <Xd|SP>, <Xn>, #<imm>
//
// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and
// an immediate register value, and writes the result to the destination register.
//
// 4. Bitwise OR (shifted register)
//
//    ORR  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    ORR  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Bitwise OR (shifted register) performs a bitwise (inclusive) OR of a register
// value and an optionally-shifted register value, and writes the result to the
// destination register.
//
func (self *Program) ORR(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("ORR", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("ORR", 3, asm.Operands { v0, v1, vv[0] })
        case 2  : p = self.alloc("ORR", 4, asm.Operands { v0, v1, vv[0], vv[1] })
        default : panic("aarch64: instruction ORR takes 2 or 3 or 4 operands")
    }
    // ORR  <Vd>.<T>, #<imm8>{, LSL #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H) &&
       isUimm8(v1) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = DomainAdvSimd
        sa_amount := uint32(0b0)
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b0
            case Vec8H: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 8: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b1001)
        switch sa_amount {
            case 0: cmode |= 0b0 << 1
            case 8: cmode |= 0b1 << 1
            default: panic("aarch64: invalid combination of operands for ORR")
        }
        return p.setins(asimdimm(
            sa_t,
            0,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // ORR  <Vd>.<T>, #<imm8>{, LSL #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isUimm8(v1) &&
       (len(vv) == 0 || modt(vv[0]) == ModLSL) {
        p.Domain = DomainAdvSimd
        sa_amount_1 := uint32(0b00)
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t_1 = 0b0
            case Vec4S: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm8 := asUimm8(v1)
        switch uint32(vv[0].(Modifier).Amount()) {
            case 0: sa_amount_1 = 0b00
            case 8: sa_amount_1 = 0b01
            case 16: sa_amount_1 = 0b10
            case 24: sa_amount_1 = 0b11
            default: panic("aarch64: invalid modifier amount")
        }
        cmode := uint32(0b0001)
        switch sa_amount_1 {
            case 0: cmode |= 0b00 << 1
            case 8: cmode |= 0b01 << 1
            case 16: cmode |= 0b10 << 1
            case 24: cmode |= 0b11 << 1
            default: panic("aarch64: invalid combination of operands for ORR")
        }
        return p.setins(asimdimm(
            sa_t_1,
            0,
            ubfx(sa_imm8, 7, 1),
            ubfx(sa_imm8, 6, 1),
            ubfx(sa_imm8, 5, 1),
            cmode,
            0,
            ubfx(sa_imm8, 4, 1),
            ubfx(sa_imm8, 3, 1),
            ubfx(sa_imm8, 2, 1),
            ubfx(sa_imm8, 1, 1),
            mask(sa_imm8, 1),
            sa_vd,
        ))
    }
    // ORR  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(vv[0]) &&
       isVfmt(vv[0], Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(vv[0]) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(vv[0].(asm.Register).ID())
        return p.setins(asimdsame(sa_t, 0, 2, sa_vm, 3, sa_vn, sa_vd))
    }
    // ORR  <Wd|WSP>, <Wn>, #<imm>
    if len(vv) == 1 && isWrOrWSP(v0) && isWr(v1) && isMask32(vv[0]) {
        p.Domain = asm.DomainGeneric
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_imm := asMaskOp(vv[0])
        return p.setins(log_imm(0, 1, 0, ubfx(sa_imm, 6, 6), mask(sa_imm, 6), sa_wn, sa_wd_wsp))
    }
    // ORR  <Xd|SP>, <Xn>, #<imm>
    if len(vv) == 1 && isXrOrSP(v0) && isXr(v1) && isMask64(vv[0]) {
        p.Domain = asm.DomainGeneric
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_imm_1 := asMaskOp(vv[0])
        return p.setins(log_imm(1, 1, ubfx(sa_imm_1, 12, 1), ubfx(sa_imm_1, 6, 6), mask(sa_imm_1, 6), sa_xn, sa_xd_sp))
    }
    // ORR  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 1 || len(vv) == 2) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(vv[0]) &&
       (len(vv) < 2 || isMods(vv[1], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(vv[0].(asm.Register).ID())
        if len(vv) >= 2 {
            switch vv[1].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[1].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 1, sa_shift, 0, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // ORR  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 1 || len(vv) == 2) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(vv[0]) &&
       (len(vv) < 2 || isMods(vv[1], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(vv[0].(asm.Register).ID())
        if len(vv) >= 2 {
            switch vv[1].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[1].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 1, sa_shift, 0, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ORR")
}

// PACDA instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Data address, using key A
//
//    PACDA  <Xd>, <Xn|SP>
//
// Pointer Authentication Code for Data address, using key A. This instruction
// computes and inserts a pointer authentication code for a data address, using a
// modifier and key A.
//
// The address is in the general-purpose register that is specified by <Xd> .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACDA .
//     * The value zero, for PACDZA .
//
func (self *Program) PACDA(v0, v1 interface{}) *Instruction {
    p := self.alloc("PACDA", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 2, sa_xn_sp, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PACDA")
}

// PACDB instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Data address, using key B
//
//    PACDB  <Xd>, <Xn|SP>
//
// Pointer Authentication Code for Data address, using key B. This instruction
// computes and inserts a pointer authentication code for a data address, using a
// modifier and key B.
//
// The address is in the general-purpose register that is specified by <Xd> .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACDB .
//     * The value zero, for PACDZB .
//
func (self *Program) PACDB(v0, v1 interface{}) *Instruction {
    p := self.alloc("PACDB", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 3, sa_xn_sp, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PACDB")
}

// PACDZA instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Data address, using key A
//
//    PACDZA  <Xd>
//
// Pointer Authentication Code for Data address, using key A. This instruction
// computes and inserts a pointer authentication code for a data address, using a
// modifier and key A.
//
// The address is in the general-purpose register that is specified by <Xd> .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACDA .
//     * The value zero, for PACDZA .
//
func (self *Program) PACDZA(v0 interface{}) *Instruction {
    p := self.alloc("PACDZA", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 10, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PACDZA")
}

// PACDZB instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Data address, using key B
//
//    PACDZB  <Xd>
//
// Pointer Authentication Code for Data address, using key B. This instruction
// computes and inserts a pointer authentication code for a data address, using a
// modifier and key B.
//
// The address is in the general-purpose register that is specified by <Xd> .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACDB .
//     * The value zero, for PACDZB .
//
func (self *Program) PACDZB(v0 interface{}) *Instruction {
    p := self.alloc("PACDZB", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 11, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PACDZB")
}

// PACGA instruction have one single form across one single category:
//
// 1. Pointer Authentication Code, using Generic key
//
//    PACGA  <Xd>, <Xn>, <Xm|SP>
//
// Pointer Authentication Code, using Generic key. This instruction computes the
// pointer authentication code for a 64-bit value in the first source register,
// using a modifier in the second source register, and the Generic key. The
// computed pointer authentication code is written to the most significant 32 bits
// of the destination register, and the least significant 32 bits of the
// destination register are set to zero.
//
func (self *Program) PACGA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("PACGA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isXr(v1) && isXrOrSP(v2) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm_sp := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm_sp, 12, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PACGA")
}

// PACIA instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key A
//
//    PACIA  <Xd>, <Xn|SP>
//
// Pointer Authentication Code for Instruction address, using key A. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIA
//       and PACIZA .
//     * In X17, for PACIA1716 .
//     * In X30, for PACIASP and PACIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIA .
//     * The value zero, for PACIZA and PACIAZ .
//     * In X16, for PACIA1716 .
//     * In SP, for PACIASP .
//
func (self *Program) PACIA(v0, v1 interface{}) *Instruction {
    p := self.alloc("PACIA", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 0, sa_xn_sp, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PACIA")
}

// PACIA1716 instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key A
//
//    PACIA1716
//
// Pointer Authentication Code for Instruction address, using key A. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIA
//       and PACIZA .
//     * In X17, for PACIA1716 .
//     * In X30, for PACIASP and PACIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIA .
//     * The value zero, for PACIZA and PACIAZ .
//     * In X16, for PACIA1716 .
//     * In SP, for PACIASP .
//
func (self *Program) PACIA1716() *Instruction {
    p := self.alloc("PACIA1716", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(1, 0))
}

// PACIASP instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key A
//
//    PACIASP
//
// Pointer Authentication Code for Instruction address, using key A. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIA
//       and PACIZA .
//     * In X17, for PACIA1716 .
//     * In X30, for PACIASP and PACIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIA .
//     * The value zero, for PACIZA and PACIAZ .
//     * In X16, for PACIA1716 .
//     * In SP, for PACIASP .
//
func (self *Program) PACIASP() *Instruction {
    p := self.alloc("PACIASP", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(3, 1))
}

// PACIAZ instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key A
//
//    PACIAZ
//
// Pointer Authentication Code for Instruction address, using key A. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIA
//       and PACIZA .
//     * In X17, for PACIA1716 .
//     * In X30, for PACIASP and PACIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIA .
//     * The value zero, for PACIZA and PACIAZ .
//     * In X16, for PACIA1716 .
//     * In SP, for PACIASP .
//
func (self *Program) PACIAZ() *Instruction {
    p := self.alloc("PACIAZ", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(3, 0))
}

// PACIB instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key B
//
//    PACIB  <Xd>, <Xn|SP>
//
// Pointer Authentication Code for Instruction address, using key B. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIB
//       and PACIZB .
//     * In X17, for PACIB1716 .
//     * In X30, for PACIBSP and PACIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIB .
//     * The value zero, for PACIZB and PACIBZ .
//     * In X16, for PACIB1716 .
//     * In SP, for PACIBSP .
//
func (self *Program) PACIB(v0, v1 interface{}) *Instruction {
    p := self.alloc("PACIB", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isXrOrSP(v1) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 1, sa_xn_sp, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PACIB")
}

// PACIB1716 instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key B
//
//    PACIB1716
//
// Pointer Authentication Code for Instruction address, using key B. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIB
//       and PACIZB .
//     * In X17, for PACIB1716 .
//     * In X30, for PACIBSP and PACIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIB .
//     * The value zero, for PACIZB and PACIBZ .
//     * In X16, for PACIB1716 .
//     * In SP, for PACIBSP .
//
func (self *Program) PACIB1716() *Instruction {
    p := self.alloc("PACIB1716", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(1, 2))
}

// PACIBSP instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key B
//
//    PACIBSP
//
// Pointer Authentication Code for Instruction address, using key B. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIB
//       and PACIZB .
//     * In X17, for PACIB1716 .
//     * In X30, for PACIBSP and PACIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIB .
//     * The value zero, for PACIZB and PACIBZ .
//     * In X16, for PACIB1716 .
//     * In SP, for PACIBSP .
//
func (self *Program) PACIBSP() *Instruction {
    p := self.alloc("PACIBSP", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(3, 3))
}

// PACIBZ instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key B
//
//    PACIBZ
//
// Pointer Authentication Code for Instruction address, using key B. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIB
//       and PACIZB .
//     * In X17, for PACIB1716 .
//     * In X30, for PACIBSP and PACIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIB .
//     * The value zero, for PACIZB and PACIBZ .
//     * In X16, for PACIB1716 .
//     * In SP, for PACIBSP .
//
func (self *Program) PACIBZ() *Instruction {
    p := self.alloc("PACIBZ", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(3, 2))
}

// PACIZA instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key A
//
//    PACIZA  <Xd>
//
// Pointer Authentication Code for Instruction address, using key A. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key A.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIA
//       and PACIZA .
//     * In X17, for PACIA1716 .
//     * In X30, for PACIASP and PACIAZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIA .
//     * The value zero, for PACIZA and PACIAZ .
//     * In X16, for PACIA1716 .
//     * In SP, for PACIASP .
//
func (self *Program) PACIZA(v0 interface{}) *Instruction {
    p := self.alloc("PACIZA", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 8, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PACIZA")
}

// PACIZB instruction have one single form across one single category:
//
// 1. Pointer Authentication Code for Instruction address, using key B
//
//    PACIZB  <Xd>
//
// Pointer Authentication Code for Instruction address, using key B. This
// instruction computes and inserts a pointer authentication code for an
// instruction address, using a modifier and key B.
//
// The address is:
//
//     * In the general-purpose register that is specified by <Xd> for PACIB
//       and PACIZB .
//     * In X17, for PACIB1716 .
//     * In X30, for PACIBSP and PACIBZ .
//
// The modifier is:
//
//     * In the general-purpose register or stack pointer that is specified by
//       <Xn|SP> for PACIB .
//     * The value zero, for PACIZB and PACIBZ .
//     * In X16, for PACIB1716 .
//     * In SP, for PACIBSP .
//
func (self *Program) PACIZB(v0 interface{}) *Instruction {
    p := self.alloc("PACIZB", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 9, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PACIZB")
}

// PMUL instruction have one single form across one single category:
//
// 1. Polynomial Multiply
//
//    PMUL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Polynomial Multiply. This instruction multiplies corresponding elements in the
// vectors of the two source SIMD&FP registers, places the results in a vector, and
// writes the vector to the destination SIMD&FP register.
//
// For information about multiplying polynomials see Polynomial arithmetic over {0,
// 1} .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) PMUL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("PMUL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 19, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PMUL")
}

// PMULL instruction have one single form across one single category:
//
// 1. Polynomial Multiply Long
//
//    PMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Polynomial Multiply Long. This instruction multiplies corresponding elements in
// the lower or upper half of the vectors of the two source SIMD&FP registers,
// places the results in a vector, and writes the vector to the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// For information about multiplying polynomials, see Polynomial arithmetic over
// {0, 1} .
//
// The PMULL instruction extracts each source vector from the lower half of each
// source register. The PMULL2 instruction extracts each source vector from the
// upper half of each source register.
//
// The PMULL and PMULL2 variants that operate on 64-bit source elements are defined
// only when FEAT_PMULL is implemented.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) PMULL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("PMULL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec1Q) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec1D, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec1D, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec1Q: sa_ta = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec1D: sa_tb = 0b110
            case Vec2D: sa_tb = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for PMULL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for PMULL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 14, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PMULL")
}

// PMULL2 instruction have one single form across one single category:
//
// 1. Polynomial Multiply Long
//
//    PMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Polynomial Multiply Long. This instruction multiplies corresponding elements in
// the lower or upper half of the vectors of the two source SIMD&FP registers,
// places the results in a vector, and writes the vector to the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// For information about multiplying polynomials, see Polynomial arithmetic over
// {0, 1} .
//
// The PMULL instruction extracts each source vector from the lower half of each
// source register. The PMULL2 instruction extracts each source vector from the
// upper half of each source register.
//
// The PMULL and PMULL2 variants that operate on 64-bit source elements are defined
// only when FEAT_PMULL is implemented.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) PMULL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("PMULL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec1Q) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec1D, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec1D, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec1Q: sa_ta = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec1D: sa_tb = 0b110
            case Vec2D: sa_tb = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for PMULL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for PMULL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 14, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PMULL2")
}

// PRFM instruction have 4 forms across 3 categories:
//
// 1. Prefetch Memory (immediate)
//
//    PRFM  (<prfop>|#<imm5>), [<Xn|SP>{, #<pimm>}]
//
// Prefetch Memory (immediate) signals the memory system that data memory accesses
// from a specified address are likely to occur in the near future. The memory
// system can respond by taking actions that are expected to speed up the memory
// accesses when they do occur, such as preloading the cache line containing the
// specified address into one or more caches.
//
// The effect of a PRFM instruction is implementation defined . For more
// information, see Prefetch memory .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// 2. Prefetch Memory (literal)
//
//    PRFM  (<prfop>|#<imm5>), <label>
//    PRFM  (<prfop>|#<imm5>), .±<offs>
//
// Prefetch Memory (literal) signals the memory system that data memory accesses
// from a specified address are likely to occur in the near future. The memory
// system can respond by taking actions that are expected to speed up the memory
// accesses when they do occur, such as preloading the cache line containing the
// specified address into one or more caches.
//
// The effect of a PRFM instruction is implementation defined . For more
// information, see Prefetch memory .
//
// For information about memory accesses, see Load/Store addressing modes .
//
// 3. Prefetch Memory (register)
//
//    PRFM  (<prfop>|#<imm5>), [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//
// Prefetch Memory (register) signals the memory system that data memory accesses
// from a specified address are likely to occur in the near future. The memory
// system can respond by taking actions that are expected to speed up the memory
// accesses when they do occur, such as preloading the cache line containing the
// specified address into one or more caches.
//
// The effect of a PRFM instruction is implementation defined . For more
// information, see Prefetch memory .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) PRFM(v0, v1 interface{}) *Instruction {
    p := self.alloc("PRFM", 2, asm.Operands { v0, v1 })
    // PRFM  (<prfop>|#<imm5>), [<Xn|SP>{, #<pimm>}]
    if isBasicPrf(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 32760) &&
       isMultipleOf(moffs(v1), 8) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_prfop := asBasicPrefetchOp(v0)
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1) / 8)
        return p.setins(ldst_pos(3, 0, 2, sa_pimm, sa_xn_sp, sa_prfop))
    }
    // PRFM  (<prfop>|#<imm5>), <label>
    if isBasicPrf(v0) && isLabel(v1) {
        p.Domain = asm.DomainGeneric
        sa_prfop := asBasicPrefetchOp(v0)
        sa_label := v1.(*asm.Label)
        return p.setenc(func(pc uintptr) uint32 {
            return loadlit(3, 0, pcrel19(sa_label, pc), sa_prfop)
        })
    }
    // PRFM  (<prfop>|#<imm5>), .±<offs>
    if isBasicPrf(v0) && isPCrel(v1) {
        p.Domain = asm.DomainGeneric
        sa_prfop := asBasicPrefetchOp(v0)
        ra_pcrel := v1.(asm.RelativeOffset)
        return p.setins(loadlit(3, 0, rel19(ra_pcrel), sa_prfop))
    }
    // PRFM  (<prfop>|#<imm5>), [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isBasicPrf(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_extend := uint32(0b011)
        sa_prfop := asBasicPrefetchOp(v0)
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 3: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for PRFM")
        }
        return p.setins(ldst_regoff(3, 0, 2, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_prfop))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for PRFM")
}

// PRFUM instruction have one single form across one single category:
//
// 1. Prefetch Memory (unscaled offset)
//
//    PRFUM (<prfop>|#<imm5>), [<Xn|SP>{, #<simm>}]
//
// Prefetch Memory (unscaled offset) signals the memory system that data memory
// accesses from a specified address are likely to occur in the near future. The
// memory system can respond by taking actions that are expected to speed up the
// memory accesses when they do occur, such as preloading the cache line containing
// the specified address into one or more caches.
//
// The effect of a PRFUM instruction is implementation defined . For more
// information, see Prefetch memory .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) PRFUM(v0, v1 interface{}) *Instruction {
    p := self.alloc("PRFUM", 2, asm.Operands { v0, v1 })
    if isBasicPrf(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_prfop := asBasicPrefetchOp(v0)
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(3, 0, 2, sa_simm, sa_xn_sp, sa_prfop))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PRFUM")
}

// PSB instruction have one single form across one single category:
//
// 1. Profiling Synchronization Barrier
//
//    PSB CSYNC
//
// Profiling Synchronization Barrier. This instruction is a barrier that ensures
// that all existing profiling data for the current PE has been formatted, and
// profiling buffer addresses have been translated such that all writes to the
// profiling buffer have been initiated. A following DSB instruction completes when
// the writes to the profiling buffer have completed.
//
// If the Statistical Profiling Extension is not implemented, this instruction
// executes as a NOP .
//
func (self *Program) PSB(v0 interface{}) *Instruction {
    p := self.alloc("PSB", 1, asm.Operands { v0 })
    if v0 == CSYNC {
        self.Arch.Require(FEAT_SPE)
        p.Domain = DomainSystem
        return p.setins(hints(2, 1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for PSB")
}

// PSSBB instruction have one single form across one single category:
//
// 1. Physical Speculative Store Bypass Barrier
//
//    PSSBB
//
// Physical Speculative Store Bypass Barrier is a memory barrier that prevents
// speculative loads from bypassing earlier stores to the same physical address
// under certain conditions. For more information and details of the semantics, see
// Physical Speculative Store Bypass Barrier (PSSBB) .
//
func (self *Program) PSSBB() *Instruction {
    p := self.alloc("PSSBB", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(barriers(4, 4, 31))
}

// RADDHN instruction have one single form across one single category:
//
// 1. Rounding Add returning High Narrow
//
//    RADDHN  <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>
//
// Rounding Add returning High Narrow. This instruction adds each vector element in
// the first source SIMD&FP register to the corresponding vector element in the
// second source SIMD&FP register, places the most significant half of the result
// into a vector, and writes the vector to the lower or upper half of the
// destination SIMD&FP register.
//
// The results are rounded. For truncated results, see ADDHN .
//
// The RADDHN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the RADDHN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) RADDHN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RADDHN", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8H, Vec4S, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for RADDHN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for RADDHN")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 4, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RADDHN")
}

// RADDHN2 instruction have one single form across one single category:
//
// 1. Rounding Add returning High Narrow
//
//    RADDHN2  <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>
//
// Rounding Add returning High Narrow. This instruction adds each vector element in
// the first source SIMD&FP register to the corresponding vector element in the
// second source SIMD&FP register, places the most significant half of the result
// into a vector, and writes the vector to the lower or upper half of the
// destination SIMD&FP register.
//
// The results are rounded. For truncated results, see ADDHN .
//
// The RADDHN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the RADDHN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) RADDHN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RADDHN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8H, Vec4S, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for RADDHN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for RADDHN2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 4, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RADDHN2")
}

// RAX1 instruction have one single form across one single category:
//
// 1. Rotate and Exclusive-OR
//
//    RAX1  <Vd>.2D, <Vn>.2D, <Vm>.2D
//
// Rotate and Exclusive-OR rotates each 64-bit element of the 128-bit vector in a
// source SIMD&FP register left by 1, performs a bitwise exclusive-OR of the
// resulting 128-bit vector and the vector in another source SIMD&FP register, and
// writes the result to the destination SIMD&FP register.
//
// This instruction is implemented only when FEAT_SHA3 is implemented.
//
func (self *Program) RAX1(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RAX1", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec2D && isVr(v1) && vfmt(v1) == Vec2D && isVr(v2) && vfmt(v2) == Vec2D {
        self.Arch.Require(FEAT_SHA3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha512_3(sa_vm, 0, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RAX1")
}

// RBIT instruction have 3 forms across 2 categories:
//
// 1. Reverse Bit order (vector)
//
//    RBIT  <Vd>.<T>, <Vn>.<T>
//
// Reverse Bit order (vector). This instruction reads each vector element from the
// source SIMD&FP register, reverses the bits of the element, places the results
// into a vector, and writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Reverse Bits
//
//    RBIT  <Wd>, <Wn>
//    RBIT  <Xd>, <Xn>
//
// Reverse Bits reverses the bit order in a register.
//
func (self *Program) RBIT(v0, v1 interface{}) *Instruction {
    p := self.alloc("RBIT", 2, asm.Operands { v0, v1 })
    // RBIT  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec8B, Vec16B) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B) && vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b0
            case Vec16B: sa_t = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(sa_t, 1, 1, 5, sa_vn, sa_vd))
    }
    // RBIT  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(0, 0, 0, 0, sa_wn, sa_wd))
    }
    // RBIT  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 0, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for RBIT")
}

// RCWCAS instruction have one single form across one single category:
//
// 1. Read Check Write Compare and Swap doubleword in memory
//
//    RCWCAS  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Compare and Swap doubleword in memory reads a 64-bit doubleword
// from memory, and compares it against the value held in a register. If the
// comparison is equal, the value in a second register is conditionally written to
// memory. Storing back to memory is conditional on RCW Checks. If the write is
// performed, the read and the write occur atomically such that no other
// modification of the memory location can take place between the read and the
// write. This instruction updates the condition flags based on the result of the
// update of memory.
//
//     * RCWCASA and RCWCASAL load from memory with acquire semantics.
//     * RCWCASL and RCWCASAL store to memory with release semantics.
//     * RCWCAS has neither acquire nor release semantics.
//
func (self *Program) RCWCAS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCAS", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(rcwcomswap(0, 0, 0, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCAS")
}

// RCWCASA instruction have one single form across one single category:
//
// 1. Read Check Write Compare and Swap doubleword in memory
//
//    RCWCASA  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Compare and Swap doubleword in memory reads a 64-bit doubleword
// from memory, and compares it against the value held in a register. If the
// comparison is equal, the value in a second register is conditionally written to
// memory. Storing back to memory is conditional on RCW Checks. If the write is
// performed, the read and the write occur atomically such that no other
// modification of the memory location can take place between the read and the
// write. This instruction updates the condition flags based on the result of the
// update of memory.
//
//     * RCWCASA and RCWCASAL load from memory with acquire semantics.
//     * RCWCASL and RCWCASAL store to memory with release semantics.
//     * RCWCAS has neither acquire nor release semantics.
//
func (self *Program) RCWCASA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCASA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(rcwcomswap(0, 1, 0, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCASA")
}

// RCWCASAL instruction have one single form across one single category:
//
// 1. Read Check Write Compare and Swap doubleword in memory
//
//    RCWCASAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Compare and Swap doubleword in memory reads a 64-bit doubleword
// from memory, and compares it against the value held in a register. If the
// comparison is equal, the value in a second register is conditionally written to
// memory. Storing back to memory is conditional on RCW Checks. If the write is
// performed, the read and the write occur atomically such that no other
// modification of the memory location can take place between the read and the
// write. This instruction updates the condition flags based on the result of the
// update of memory.
//
//     * RCWCASA and RCWCASAL load from memory with acquire semantics.
//     * RCWCASL and RCWCASAL store to memory with release semantics.
//     * RCWCAS has neither acquire nor release semantics.
//
func (self *Program) RCWCASAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCASAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(rcwcomswap(0, 1, 1, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCASAL")
}

// RCWCASL instruction have one single form across one single category:
//
// 1. Read Check Write Compare and Swap doubleword in memory
//
//    RCWCASL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Compare and Swap doubleword in memory reads a 64-bit doubleword
// from memory, and compares it against the value held in a register. If the
// comparison is equal, the value in a second register is conditionally written to
// memory. Storing back to memory is conditional on RCW Checks. If the write is
// performed, the read and the write occur atomically such that no other
// modification of the memory location can take place between the read and the
// write. This instruction updates the condition flags based on the result of the
// update of memory.
//
//     * RCWCASA and RCWCASAL load from memory with acquire semantics.
//     * RCWCASL and RCWCASAL store to memory with release semantics.
//     * RCWCAS has neither acquire nor release semantics.
//
func (self *Program) RCWCASL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCASL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(rcwcomswap(0, 0, 1, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCASL")
}

// RCWCASP instruction have one single form across one single category:
//
// 1. Read Check Write Compare and Swap quadword in memory
//
//    RCWCASP  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
//
// Read Check Write Compare and Swap quadword in memory reads a 128-bit quadword
// from memory, and compares it against the value held in a pair of registers. If
// the comparison is equal, the value in a second pair of registers is
// conditionally written to memory. Storing back to memory is conditional on RCW
// Checks. If the write is performed, the read and the write occur atomically such
// that no other modification of the memory location can take place between the
// read and the write. This instruction updates the condition flags based on the
// result of the update of memory.
//
//     * RCWCASPA and RCWCASPAL load from memory with acquire semantics.
//     * RCWCASPL and RCWCASPAL store to memory with release semantics.
//     * RCWCASP has neither acquire nor release semantics.
//
func (self *Program) RCWCASP(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("RCWCASP", 5, asm.Operands { v0, v1, v2, v3, v4 })
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       moffs(v4) == 0 &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(rcwcomswappr(0, 0, 0, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCASP")
}

// RCWCASPA instruction have one single form across one single category:
//
// 1. Read Check Write Compare and Swap quadword in memory
//
//    RCWCASPA  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
//
// Read Check Write Compare and Swap quadword in memory reads a 128-bit quadword
// from memory, and compares it against the value held in a pair of registers. If
// the comparison is equal, the value in a second pair of registers is
// conditionally written to memory. Storing back to memory is conditional on RCW
// Checks. If the write is performed, the read and the write occur atomically such
// that no other modification of the memory location can take place between the
// read and the write. This instruction updates the condition flags based on the
// result of the update of memory.
//
//     * RCWCASPA and RCWCASPAL load from memory with acquire semantics.
//     * RCWCASPL and RCWCASPAL store to memory with release semantics.
//     * RCWCASP has neither acquire nor release semantics.
//
func (self *Program) RCWCASPA(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("RCWCASPA", 5, asm.Operands { v0, v1, v2, v3, v4 })
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       moffs(v4) == 0 &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(rcwcomswappr(0, 1, 0, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCASPA")
}

// RCWCASPAL instruction have one single form across one single category:
//
// 1. Read Check Write Compare and Swap quadword in memory
//
//    RCWCASPAL  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
//
// Read Check Write Compare and Swap quadword in memory reads a 128-bit quadword
// from memory, and compares it against the value held in a pair of registers. If
// the comparison is equal, the value in a second pair of registers is
// conditionally written to memory. Storing back to memory is conditional on RCW
// Checks. If the write is performed, the read and the write occur atomically such
// that no other modification of the memory location can take place between the
// read and the write. This instruction updates the condition flags based on the
// result of the update of memory.
//
//     * RCWCASPA and RCWCASPAL load from memory with acquire semantics.
//     * RCWCASPL and RCWCASPAL store to memory with release semantics.
//     * RCWCASP has neither acquire nor release semantics.
//
func (self *Program) RCWCASPAL(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("RCWCASPAL", 5, asm.Operands { v0, v1, v2, v3, v4 })
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       moffs(v4) == 0 &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(rcwcomswappr(0, 1, 1, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCASPAL")
}

// RCWCASPL instruction have one single form across one single category:
//
// 1. Read Check Write Compare and Swap quadword in memory
//
//    RCWCASPL  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
//
// Read Check Write Compare and Swap quadword in memory reads a 128-bit quadword
// from memory, and compares it against the value held in a pair of registers. If
// the comparison is equal, the value in a second pair of registers is
// conditionally written to memory. Storing back to memory is conditional on RCW
// Checks. If the write is performed, the read and the write occur atomically such
// that no other modification of the memory location can take place between the
// read and the write. This instruction updates the condition flags based on the
// result of the update of memory.
//
//     * RCWCASPA and RCWCASPAL load from memory with acquire semantics.
//     * RCWCASPL and RCWCASPAL store to memory with release semantics.
//     * RCWCASP has neither acquire nor release semantics.
//
func (self *Program) RCWCASPL(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("RCWCASPL", 5, asm.Operands { v0, v1, v2, v3, v4 })
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       moffs(v4) == 0 &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(rcwcomswappr(0, 0, 1, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCASPL")
}

// RCWCLR instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Clear on doubleword in memory
//
//    RCWCLR  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write atomic bit Clear on doubleword in memory atomically loads a
// 64-bit doubleword from memory, performs a bitwise AND with the complement of the
// value held in a register on it, and conditionally stores the result back to
// memory. Storing of the result back to memory is conditional on RCW Checks. The
// value initially loaded from memory is returned in the destination register. This
// instruction updates the condition flags based on the result of the update of
// memory.
//
//     * RCWCLRA and RCWCLRAL load from memory with acquire semantics.
//     * RCWCLRL and RCWCLRAL store to memory with release semantics.
//     * RCWCLR has neither acquire nor release semantics.
//
func (self *Program) RCWCLR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCLR", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_xs, 1, 1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCLR")
}

// RCWCLRA instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Clear on doubleword in memory
//
//    RCWCLRA  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write atomic bit Clear on doubleword in memory atomically loads a
// 64-bit doubleword from memory, performs a bitwise AND with the complement of the
// value held in a register on it, and conditionally stores the result back to
// memory. Storing of the result back to memory is conditional on RCW Checks. The
// value initially loaded from memory is returned in the destination register. This
// instruction updates the condition flags based on the result of the update of
// memory.
//
//     * RCWCLRA and RCWCLRAL load from memory with acquire semantics.
//     * RCWCLRL and RCWCLRAL store to memory with release semantics.
//     * RCWCLR has neither acquire nor release semantics.
//
func (self *Program) RCWCLRA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCLRA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_xs, 1, 1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCLRA")
}

// RCWCLRAL instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Clear on doubleword in memory
//
//    RCWCLRAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write atomic bit Clear on doubleword in memory atomically loads a
// 64-bit doubleword from memory, performs a bitwise AND with the complement of the
// value held in a register on it, and conditionally stores the result back to
// memory. Storing of the result back to memory is conditional on RCW Checks. The
// value initially loaded from memory is returned in the destination register. This
// instruction updates the condition flags based on the result of the update of
// memory.
//
//     * RCWCLRA and RCWCLRAL load from memory with acquire semantics.
//     * RCWCLRL and RCWCLRAL store to memory with release semantics.
//     * RCWCLR has neither acquire nor release semantics.
//
func (self *Program) RCWCLRAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCLRAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_xs, 1, 1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCLRAL")
}

// RCWCLRL instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Clear on doubleword in memory
//
//    RCWCLRL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write atomic bit Clear on doubleword in memory atomically loads a
// 64-bit doubleword from memory, performs a bitwise AND with the complement of the
// value held in a register on it, and conditionally stores the result back to
// memory. Storing of the result back to memory is conditional on RCW Checks. The
// value initially loaded from memory is returned in the destination register. This
// instruction updates the condition flags based on the result of the update of
// memory.
//
//     * RCWCLRA and RCWCLRAL load from memory with acquire semantics.
//     * RCWCLRL and RCWCLRAL store to memory with release semantics.
//     * RCWCLR has neither acquire nor release semantics.
//
func (self *Program) RCWCLRL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCLRL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_xs, 1, 1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCLRL")
}

// RCWCLRP instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Clear on quadword in memory
//
//    RCWCLRP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write atomic bit Clear on quadword in memory atomically loads a
// 128-bit quadword from memory, performs a bitwise AND with the complement of the
// value held in a pair of registers on it, and conditionally stores the result
// back to memory. Storing of the result back to memory is conditional on RCW
// Checks. The value initially loaded from memory is returned in the same pair of
// registers. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWCLRPA and RCWCLRPAL load from memory with acquire semantics.
//     * RCWCLRPL and RCWCLRPAL store to memory with release semantics.
//     * RCWCLRP has neither acquire nor release semantics.
//
func (self *Program) RCWCLRP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCLRP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 0, sa_xt2, 1, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCLRP")
}

// RCWCLRPA instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Clear on quadword in memory
//
//    RCWCLRPA  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write atomic bit Clear on quadword in memory atomically loads a
// 128-bit quadword from memory, performs a bitwise AND with the complement of the
// value held in a pair of registers on it, and conditionally stores the result
// back to memory. Storing of the result back to memory is conditional on RCW
// Checks. The value initially loaded from memory is returned in the same pair of
// registers. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWCLRPA and RCWCLRPAL load from memory with acquire semantics.
//     * RCWCLRPL and RCWCLRPAL store to memory with release semantics.
//     * RCWCLRP has neither acquire nor release semantics.
//
func (self *Program) RCWCLRPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCLRPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 0, sa_xt2, 1, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCLRPA")
}

// RCWCLRPAL instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Clear on quadword in memory
//
//    RCWCLRPAL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write atomic bit Clear on quadword in memory atomically loads a
// 128-bit quadword from memory, performs a bitwise AND with the complement of the
// value held in a pair of registers on it, and conditionally stores the result
// back to memory. Storing of the result back to memory is conditional on RCW
// Checks. The value initially loaded from memory is returned in the same pair of
// registers. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWCLRPA and RCWCLRPAL load from memory with acquire semantics.
//     * RCWCLRPL and RCWCLRPAL store to memory with release semantics.
//     * RCWCLRP has neither acquire nor release semantics.
//
func (self *Program) RCWCLRPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCLRPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 1, sa_xt2, 1, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCLRPAL")
}

// RCWCLRPL instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Clear on quadword in memory
//
//    RCWCLRPL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write atomic bit Clear on quadword in memory atomically loads a
// 128-bit quadword from memory, performs a bitwise AND with the complement of the
// value held in a pair of registers on it, and conditionally stores the result
// back to memory. Storing of the result back to memory is conditional on RCW
// Checks. The value initially loaded from memory is returned in the same pair of
// registers. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWCLRPA and RCWCLRPAL load from memory with acquire semantics.
//     * RCWCLRPL and RCWCLRPAL store to memory with release semantics.
//     * RCWCLRP has neither acquire nor release semantics.
//
func (self *Program) RCWCLRPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWCLRPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 1, sa_xt2, 1, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWCLRPL")
}

// RCWSCAS instruction have one single form across one single category:
//
// 1. Read Check Write Software Compare and Swap doubleword in memory
//
//    RCWSCAS  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software Compare and Swap doubleword in memory reads a 64-bit
// doubleword from memory, and compares it against the value held in a register. If
// the comparison is equal, the value in a second register is conditionally written
// to memory. Storing back to memory is conditional on RCW Checks and RCWS Checks.
// If the write is performed, the read and the write occur atomically such that no
// other modification of the memory location can take place between the read and
// the write. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSCASA and RCWSCASAL load from memory with acquire semantics.
//     * RCWSCASL and RCWSCASAL store to memory with release semantics.
//     * RCWSCAS has neither acquire nor release semantics.
//
func (self *Program) RCWSCAS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCAS", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(rcwcomswap(1, 0, 0, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCAS")
}

// RCWSCASA instruction have one single form across one single category:
//
// 1. Read Check Write Software Compare and Swap doubleword in memory
//
//    RCWSCASA  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software Compare and Swap doubleword in memory reads a 64-bit
// doubleword from memory, and compares it against the value held in a register. If
// the comparison is equal, the value in a second register is conditionally written
// to memory. Storing back to memory is conditional on RCW Checks and RCWS Checks.
// If the write is performed, the read and the write occur atomically such that no
// other modification of the memory location can take place between the read and
// the write. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSCASA and RCWSCASAL load from memory with acquire semantics.
//     * RCWSCASL and RCWSCASAL store to memory with release semantics.
//     * RCWSCAS has neither acquire nor release semantics.
//
func (self *Program) RCWSCASA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCASA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(rcwcomswap(1, 1, 0, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCASA")
}

// RCWSCASAL instruction have one single form across one single category:
//
// 1. Read Check Write Software Compare and Swap doubleword in memory
//
//    RCWSCASAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software Compare and Swap doubleword in memory reads a 64-bit
// doubleword from memory, and compares it against the value held in a register. If
// the comparison is equal, the value in a second register is conditionally written
// to memory. Storing back to memory is conditional on RCW Checks and RCWS Checks.
// If the write is performed, the read and the write occur atomically such that no
// other modification of the memory location can take place between the read and
// the write. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSCASA and RCWSCASAL load from memory with acquire semantics.
//     * RCWSCASL and RCWSCASAL store to memory with release semantics.
//     * RCWSCAS has neither acquire nor release semantics.
//
func (self *Program) RCWSCASAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCASAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(rcwcomswap(1, 1, 1, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCASAL")
}

// RCWSCASL instruction have one single form across one single category:
//
// 1. Read Check Write Software Compare and Swap doubleword in memory
//
//    RCWSCASL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software Compare and Swap doubleword in memory reads a 64-bit
// doubleword from memory, and compares it against the value held in a register. If
// the comparison is equal, the value in a second register is conditionally written
// to memory. Storing back to memory is conditional on RCW Checks and RCWS Checks.
// If the write is performed, the read and the write occur atomically such that no
// other modification of the memory location can take place between the read and
// the write. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSCASA and RCWSCASAL load from memory with acquire semantics.
//     * RCWSCASL and RCWSCASAL store to memory with release semantics.
//     * RCWSCAS has neither acquire nor release semantics.
//
func (self *Program) RCWSCASL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCASL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(rcwcomswap(1, 0, 1, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCASL")
}

// RCWSCASP instruction have one single form across one single category:
//
// 1. Read Check Write Software Compare and Swap quadword in memory
//
//    RCWSCASP  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
//
// Read Check Write Software Compare and Swap quadword in memory reads a 128-bit
// quadword from memory, and compares it against the value held in a pair of
// registers. If the comparison is equal, the value in a second pair of registers
// is conditionally written to memory. Storing back to memory is conditional on RCW
// Checks and RCWS Checks. If the write is performed, the read and the write occur
// atomically such that no other modification of the memory location can take place
// between the read and the write. This instruction updates the condition flags
// based on the result of the update of memory.
//
//     * RCWSCASPA and RCWSCASPAL load from memory with acquire semantics.
//     * RCWSCASPL and RCWSCASPAL store to memory with release semantics.
//     * RCWSCASP has neither acquire nor release semantics.
//
func (self *Program) RCWSCASP(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("RCWSCASP", 5, asm.Operands { v0, v1, v2, v3, v4 })
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       moffs(v4) == 0 &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(rcwcomswappr(1, 0, 0, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCASP")
}

// RCWSCASPA instruction have one single form across one single category:
//
// 1. Read Check Write Software Compare and Swap quadword in memory
//
//    RCWSCASPA  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
//
// Read Check Write Software Compare and Swap quadword in memory reads a 128-bit
// quadword from memory, and compares it against the value held in a pair of
// registers. If the comparison is equal, the value in a second pair of registers
// is conditionally written to memory. Storing back to memory is conditional on RCW
// Checks and RCWS Checks. If the write is performed, the read and the write occur
// atomically such that no other modification of the memory location can take place
// between the read and the write. This instruction updates the condition flags
// based on the result of the update of memory.
//
//     * RCWSCASPA and RCWSCASPAL load from memory with acquire semantics.
//     * RCWSCASPL and RCWSCASPAL store to memory with release semantics.
//     * RCWSCASP has neither acquire nor release semantics.
//
func (self *Program) RCWSCASPA(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("RCWSCASPA", 5, asm.Operands { v0, v1, v2, v3, v4 })
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       moffs(v4) == 0 &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(rcwcomswappr(1, 1, 0, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCASPA")
}

// RCWSCASPAL instruction have one single form across one single category:
//
// 1. Read Check Write Software Compare and Swap quadword in memory
//
//    RCWSCASPAL  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
//
// Read Check Write Software Compare and Swap quadword in memory reads a 128-bit
// quadword from memory, and compares it against the value held in a pair of
// registers. If the comparison is equal, the value in a second pair of registers
// is conditionally written to memory. Storing back to memory is conditional on RCW
// Checks and RCWS Checks. If the write is performed, the read and the write occur
// atomically such that no other modification of the memory location can take place
// between the read and the write. This instruction updates the condition flags
// based on the result of the update of memory.
//
//     * RCWSCASPA and RCWSCASPAL load from memory with acquire semantics.
//     * RCWSCASPL and RCWSCASPAL store to memory with release semantics.
//     * RCWSCASP has neither acquire nor release semantics.
//
func (self *Program) RCWSCASPAL(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("RCWSCASPAL", 5, asm.Operands { v0, v1, v2, v3, v4 })
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       moffs(v4) == 0 &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(rcwcomswappr(1, 1, 1, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCASPAL")
}

// RCWSCASPL instruction have one single form across one single category:
//
// 1. Read Check Write Software Compare and Swap quadword in memory
//
//    RCWSCASPL  <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
//
// Read Check Write Software Compare and Swap quadword in memory reads a 128-bit
// quadword from memory, and compares it against the value held in a pair of
// registers. If the comparison is equal, the value in a second pair of registers
// is conditionally written to memory. Storing back to memory is conditional on RCW
// Checks and RCWS Checks. If the write is performed, the read and the write occur
// atomically such that no other modification of the memory location can take place
// between the read and the write. This instruction updates the condition flags
// based on the result of the update of memory.
//
//     * RCWSCASPA and RCWSCASPAL load from memory with acquire semantics.
//     * RCWSCASPL and RCWSCASPAL store to memory with release semantics.
//     * RCWSCASP has neither acquire nor release semantics.
//
func (self *Program) RCWSCASPL(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("RCWSCASPL", 5, asm.Operands { v0, v1, v2, v3, v4 })
    if isXr(v0) &&
       isXr(v1) &&
       isNextReg(v1, v0, 1) &&
       isXr(v2) &&
       isXr(v3) &&
       isNextReg(v3, v2, 1) &&
       isMem(v4) &&
       isXrOrSP(mbase(v4)) &&
       midx(v4) == nil &&
       moffs(v4) == 0 &&
       mext(v4) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v4).ID())
        return p.setins(rcwcomswappr(1, 0, 1, sa_xs, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCASPL")
}

// RCWSCLR instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Clear on doubleword in memory
//
//    RCWSCLR  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Clear on doubleword in memory atomically
// loads a 64-bit doubleword from memory, performs a bitwise AND with the
// complement of the value held in a register on it, and conditionally stores the
// result back to memory. Storing of the result back to memory is conditional on
// RCW Checks and RCWS Checks. The value initially loaded from memory is returned
// in the destination register. This instruction updates the condition flags based
// on the result of the update of memory.
//
//     * RCWSCLRA and RCWSCLRAL load from memory with acquire semantics.
//     * RCWSCLRL and RCWSCLRAL store to memory with release semantics.
//     * RCWSCLR has neither acquire nor release semantics.
//
func (self *Program) RCWSCLR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCLR", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_xs, 1, 1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCLR")
}

// RCWSCLRA instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Clear on doubleword in memory
//
//    RCWSCLRA  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Clear on doubleword in memory atomically
// loads a 64-bit doubleword from memory, performs a bitwise AND with the
// complement of the value held in a register on it, and conditionally stores the
// result back to memory. Storing of the result back to memory is conditional on
// RCW Checks and RCWS Checks. The value initially loaded from memory is returned
// in the destination register. This instruction updates the condition flags based
// on the result of the update of memory.
//
//     * RCWSCLRA and RCWSCLRAL load from memory with acquire semantics.
//     * RCWSCLRL and RCWSCLRAL store to memory with release semantics.
//     * RCWSCLR has neither acquire nor release semantics.
//
func (self *Program) RCWSCLRA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCLRA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_xs, 1, 1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCLRA")
}

// RCWSCLRAL instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Clear on doubleword in memory
//
//    RCWSCLRAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Clear on doubleword in memory atomically
// loads a 64-bit doubleword from memory, performs a bitwise AND with the
// complement of the value held in a register on it, and conditionally stores the
// result back to memory. Storing of the result back to memory is conditional on
// RCW Checks and RCWS Checks. The value initially loaded from memory is returned
// in the destination register. This instruction updates the condition flags based
// on the result of the update of memory.
//
//     * RCWSCLRA and RCWSCLRAL load from memory with acquire semantics.
//     * RCWSCLRL and RCWSCLRAL store to memory with release semantics.
//     * RCWSCLR has neither acquire nor release semantics.
//
func (self *Program) RCWSCLRAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCLRAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_xs, 1, 1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCLRAL")
}

// RCWSCLRL instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Clear on doubleword in memory
//
//    RCWSCLRL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Clear on doubleword in memory atomically
// loads a 64-bit doubleword from memory, performs a bitwise AND with the
// complement of the value held in a register on it, and conditionally stores the
// result back to memory. Storing of the result back to memory is conditional on
// RCW Checks and RCWS Checks. The value initially loaded from memory is returned
// in the destination register. This instruction updates the condition flags based
// on the result of the update of memory.
//
//     * RCWSCLRA and RCWSCLRAL load from memory with acquire semantics.
//     * RCWSCLRL and RCWSCLRAL store to memory with release semantics.
//     * RCWSCLR has neither acquire nor release semantics.
//
func (self *Program) RCWSCLRL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCLRL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_xs, 1, 1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCLRL")
}

// RCWSCLRP instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Clear on quadword in memory
//
//    RCWSCLRP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Clear on quadword in memory atomically
// loads a 128-bit quadword from memory, performs a bitwise AND with the complement
// of the value held in a pair of registers on it, and conditionally stores the
// result back to memory. Storing of the result back to memory is conditional on
// RCW Checks and RCWS Checks. The value initially loaded from memory is returned
// in the same pair of registers. This instruction updates the condition flags
// based on the result of the update of memory.
//
//     * RCWSCLRPA and RCWSCLRPAL load from memory with acquire semantics.
//     * RCWSCLRPL and RCWSCLRPAL store to memory with release semantics.
//     * RCWSCLRP has neither acquire nor release semantics.
//
func (self *Program) RCWSCLRP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCLRP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 0, 0, sa_xt2, 1, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCLRP")
}

// RCWSCLRPA instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Clear on quadword in memory
//
//    RCWSCLRPA  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Clear on quadword in memory atomically
// loads a 128-bit quadword from memory, performs a bitwise AND with the complement
// of the value held in a pair of registers on it, and conditionally stores the
// result back to memory. Storing of the result back to memory is conditional on
// RCW Checks and RCWS Checks. The value initially loaded from memory is returned
// in the same pair of registers. This instruction updates the condition flags
// based on the result of the update of memory.
//
//     * RCWSCLRPA and RCWSCLRPAL load from memory with acquire semantics.
//     * RCWSCLRPL and RCWSCLRPAL store to memory with release semantics.
//     * RCWSCLRP has neither acquire nor release semantics.
//
func (self *Program) RCWSCLRPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCLRPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 1, 0, sa_xt2, 1, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCLRPA")
}

// RCWSCLRPAL instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Clear on quadword in memory
//
//    RCWSCLRPAL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Clear on quadword in memory atomically
// loads a 128-bit quadword from memory, performs a bitwise AND with the complement
// of the value held in a pair of registers on it, and conditionally stores the
// result back to memory. Storing of the result back to memory is conditional on
// RCW Checks and RCWS Checks. The value initially loaded from memory is returned
// in the same pair of registers. This instruction updates the condition flags
// based on the result of the update of memory.
//
//     * RCWSCLRPA and RCWSCLRPAL load from memory with acquire semantics.
//     * RCWSCLRPL and RCWSCLRPAL store to memory with release semantics.
//     * RCWSCLRP has neither acquire nor release semantics.
//
func (self *Program) RCWSCLRPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCLRPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 1, 1, sa_xt2, 1, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCLRPAL")
}

// RCWSCLRPL instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Clear on quadword in memory
//
//    RCWSCLRPL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Clear on quadword in memory atomically
// loads a 128-bit quadword from memory, performs a bitwise AND with the complement
// of the value held in a pair of registers on it, and conditionally stores the
// result back to memory. Storing of the result back to memory is conditional on
// RCW Checks and RCWS Checks. The value initially loaded from memory is returned
// in the same pair of registers. This instruction updates the condition flags
// based on the result of the update of memory.
//
//     * RCWSCLRPA and RCWSCLRPAL load from memory with acquire semantics.
//     * RCWSCLRPL and RCWSCLRPAL store to memory with release semantics.
//     * RCWSCLRP has neither acquire nor release semantics.
//
func (self *Program) RCWSCLRPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSCLRPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 0, 1, sa_xt2, 1, 1, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSCLRPL")
}

// RCWSET instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Set on doubleword in memory
//
//    RCWSET  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write atomic bit Set on doubleword in memory atomically loads a
// 64-bit doubleword from memory, performs a bitwise OR with the complement of the
// value held in a register on it, and conditionally stores the result back to
// memory. Storing of the result back to memory is conditional on RCW Checks. The
// value initially loaded from memory is returned in the destination register. This
// instruction updates the condition flags based on the result of the update of
// memory.
//
//     * RCWSETA and RCWSETAL load from memory with acquire semantics.
//     * RCWSETL and RCWSETAL store to memory with release semantics.
//     * RCWSET has neither acquire nor release semantics.
//
func (self *Program) RCWSET(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSET", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_xs, 1, 3, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSET")
}

// RCWSETA instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Set on doubleword in memory
//
//    RCWSETA  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write atomic bit Set on doubleword in memory atomically loads a
// 64-bit doubleword from memory, performs a bitwise OR with the complement of the
// value held in a register on it, and conditionally stores the result back to
// memory. Storing of the result back to memory is conditional on RCW Checks. The
// value initially loaded from memory is returned in the destination register. This
// instruction updates the condition flags based on the result of the update of
// memory.
//
//     * RCWSETA and RCWSETAL load from memory with acquire semantics.
//     * RCWSETL and RCWSETAL store to memory with release semantics.
//     * RCWSET has neither acquire nor release semantics.
//
func (self *Program) RCWSETA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSETA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_xs, 1, 3, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSETA")
}

// RCWSETAL instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Set on doubleword in memory
//
//    RCWSETAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write atomic bit Set on doubleword in memory atomically loads a
// 64-bit doubleword from memory, performs a bitwise OR with the complement of the
// value held in a register on it, and conditionally stores the result back to
// memory. Storing of the result back to memory is conditional on RCW Checks. The
// value initially loaded from memory is returned in the destination register. This
// instruction updates the condition flags based on the result of the update of
// memory.
//
//     * RCWSETA and RCWSETAL load from memory with acquire semantics.
//     * RCWSETL and RCWSETAL store to memory with release semantics.
//     * RCWSET has neither acquire nor release semantics.
//
func (self *Program) RCWSETAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSETAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_xs, 1, 3, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSETAL")
}

// RCWSETL instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Set on doubleword in memory
//
//    RCWSETL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write atomic bit Set on doubleword in memory atomically loads a
// 64-bit doubleword from memory, performs a bitwise OR with the complement of the
// value held in a register on it, and conditionally stores the result back to
// memory. Storing of the result back to memory is conditional on RCW Checks. The
// value initially loaded from memory is returned in the destination register. This
// instruction updates the condition flags based on the result of the update of
// memory.
//
//     * RCWSETA and RCWSETAL load from memory with acquire semantics.
//     * RCWSETL and RCWSETAL store to memory with release semantics.
//     * RCWSET has neither acquire nor release semantics.
//
func (self *Program) RCWSETL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSETL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_xs, 1, 3, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSETL")
}

// RCWSETP instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Set on quadword in memory
//
//    RCWSETP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write atomic bit Set on quadword in memory atomically loads a 128-bit
// quadword from memory, performs a bitwise OR with the value held in a pair of
// registers on it, and conditionally stores the result back to memory. Storing of
// the result back to memory is conditional on RCW Checks. The value initially
// loaded from memory is returned in the same pair of registers. This instruction
// updates the condition flags based on the result of the update of memory.
//
//     * RCWSETPA and RCWSETPAL load from memory with acquire semantics.
//     * RCWSETPL and RCWSETPAL store to memory with release semantics.
//     * RCWSETP has neither acquire nor release semantics.
//
func (self *Program) RCWSETP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSETP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 0, sa_xt2, 1, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSETP")
}

// RCWSETPA instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Set on quadword in memory
//
//    RCWSETPA  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write atomic bit Set on quadword in memory atomically loads a 128-bit
// quadword from memory, performs a bitwise OR with the value held in a pair of
// registers on it, and conditionally stores the result back to memory. Storing of
// the result back to memory is conditional on RCW Checks. The value initially
// loaded from memory is returned in the same pair of registers. This instruction
// updates the condition flags based on the result of the update of memory.
//
//     * RCWSETPA and RCWSETPAL load from memory with acquire semantics.
//     * RCWSETPL and RCWSETPAL store to memory with release semantics.
//     * RCWSETP has neither acquire nor release semantics.
//
func (self *Program) RCWSETPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSETPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 0, sa_xt2, 1, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSETPA")
}

// RCWSETPAL instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Set on quadword in memory
//
//    RCWSETPAL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write atomic bit Set on quadword in memory atomically loads a 128-bit
// quadword from memory, performs a bitwise OR with the value held in a pair of
// registers on it, and conditionally stores the result back to memory. Storing of
// the result back to memory is conditional on RCW Checks. The value initially
// loaded from memory is returned in the same pair of registers. This instruction
// updates the condition flags based on the result of the update of memory.
//
//     * RCWSETPA and RCWSETPAL load from memory with acquire semantics.
//     * RCWSETPL and RCWSETPAL store to memory with release semantics.
//     * RCWSETP has neither acquire nor release semantics.
//
func (self *Program) RCWSETPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSETPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 1, sa_xt2, 1, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSETPAL")
}

// RCWSETPL instruction have one single form across one single category:
//
// 1. Read Check Write atomic bit Set on quadword in memory
//
//    RCWSETPL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write atomic bit Set on quadword in memory atomically loads a 128-bit
// quadword from memory, performs a bitwise OR with the value held in a pair of
// registers on it, and conditionally stores the result back to memory. Storing of
// the result back to memory is conditional on RCW Checks. The value initially
// loaded from memory is returned in the same pair of registers. This instruction
// updates the condition flags based on the result of the update of memory.
//
//     * RCWSETPA and RCWSETPAL load from memory with acquire semantics.
//     * RCWSETPL and RCWSETPAL store to memory with release semantics.
//     * RCWSETP has neither acquire nor release semantics.
//
func (self *Program) RCWSETPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSETPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 1, sa_xt2, 1, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSETPL")
}

// RCWSSET instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Set on doubleword in memory
//
//    RCWSSET  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Set on doubleword in memory atomically
// loads a 64-bit doubleword from memory, performs a bitwise OR with the complement
// of the value held in a register on it, and conditionally stores the result back
// to memory. Storing of the result back to memory is conditional on RCW Checks and
// RCWS Checks. The value initially loaded from memory is returned in the
// destination register. This instruction updates the condition flags based on the
// result of the update of memory.
//
//     * RCWSSETA and RCWSSETAL load from memory with acquire semantics.
//     * RCWSSETL and RCWSSETAL store to memory with release semantics.
//     * RCWSSET has neither acquire nor release semantics.
//
func (self *Program) RCWSSET(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSET", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_xs, 1, 3, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSET")
}

// RCWSSETA instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Set on doubleword in memory
//
//    RCWSSETA  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Set on doubleword in memory atomically
// loads a 64-bit doubleword from memory, performs a bitwise OR with the complement
// of the value held in a register on it, and conditionally stores the result back
// to memory. Storing of the result back to memory is conditional on RCW Checks and
// RCWS Checks. The value initially loaded from memory is returned in the
// destination register. This instruction updates the condition flags based on the
// result of the update of memory.
//
//     * RCWSSETA and RCWSSETAL load from memory with acquire semantics.
//     * RCWSSETL and RCWSSETAL store to memory with release semantics.
//     * RCWSSET has neither acquire nor release semantics.
//
func (self *Program) RCWSSETA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSETA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_xs, 1, 3, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSETA")
}

// RCWSSETAL instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Set on doubleword in memory
//
//    RCWSSETAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Set on doubleword in memory atomically
// loads a 64-bit doubleword from memory, performs a bitwise OR with the complement
// of the value held in a register on it, and conditionally stores the result back
// to memory. Storing of the result back to memory is conditional on RCW Checks and
// RCWS Checks. The value initially loaded from memory is returned in the
// destination register. This instruction updates the condition flags based on the
// result of the update of memory.
//
//     * RCWSSETA and RCWSSETAL load from memory with acquire semantics.
//     * RCWSSETL and RCWSSETAL store to memory with release semantics.
//     * RCWSSET has neither acquire nor release semantics.
//
func (self *Program) RCWSSETAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSETAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_xs, 1, 3, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSETAL")
}

// RCWSSETL instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Set on doubleword in memory
//
//    RCWSSETL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Set on doubleword in memory atomically
// loads a 64-bit doubleword from memory, performs a bitwise OR with the complement
// of the value held in a register on it, and conditionally stores the result back
// to memory. Storing of the result back to memory is conditional on RCW Checks and
// RCWS Checks. The value initially loaded from memory is returned in the
// destination register. This instruction updates the condition flags based on the
// result of the update of memory.
//
//     * RCWSSETA and RCWSSETAL load from memory with acquire semantics.
//     * RCWSSETL and RCWSSETAL store to memory with release semantics.
//     * RCWSSET has neither acquire nor release semantics.
//
func (self *Program) RCWSSETL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSETL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_xs, 1, 3, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSETL")
}

// RCWSSETP instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Set on quadword in memory
//
//    RCWSSETP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Set on quadword in memory atomically loads
// a 128-bit quadword from memory, performs a bitwise OR with the value held in a
// pair of registers on it, and conditionally stores the result back to memory.
// Storing of the result back to memory is conditional on RCW Checks and RCWS
// Checks. The value initially loaded from memory is returned in the same pair of
// registers. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSSETPA and RCWSSETPAL load from memory with acquire semantics.
//     * RCWSSETPL and RCWSSETPAL store to memory with release semantics.
//     * RCWSSETP has neither acquire nor release semantics.
//
func (self *Program) RCWSSETP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSETP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 0, 0, sa_xt2, 1, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSETP")
}

// RCWSSETPA instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Set on quadword in memory
//
//    RCWSSETPA  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Set on quadword in memory atomically loads
// a 128-bit quadword from memory, performs a bitwise OR with the value held in a
// pair of registers on it, and conditionally stores the result back to memory.
// Storing of the result back to memory is conditional on RCW Checks and RCWS
// Checks. The value initially loaded from memory is returned in the same pair of
// registers. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSSETPA and RCWSSETPAL load from memory with acquire semantics.
//     * RCWSSETPL and RCWSSETPAL store to memory with release semantics.
//     * RCWSSETP has neither acquire nor release semantics.
//
func (self *Program) RCWSSETPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSETPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 1, 0, sa_xt2, 1, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSETPA")
}

// RCWSSETPAL instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Set on quadword in memory
//
//    RCWSSETPAL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Set on quadword in memory atomically loads
// a 128-bit quadword from memory, performs a bitwise OR with the value held in a
// pair of registers on it, and conditionally stores the result back to memory.
// Storing of the result back to memory is conditional on RCW Checks and RCWS
// Checks. The value initially loaded from memory is returned in the same pair of
// registers. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSSETPA and RCWSSETPAL load from memory with acquire semantics.
//     * RCWSSETPL and RCWSSETPAL store to memory with release semantics.
//     * RCWSSETP has neither acquire nor release semantics.
//
func (self *Program) RCWSSETPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSETPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 1, 1, sa_xt2, 1, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSETPAL")
}

// RCWSSETPL instruction have one single form across one single category:
//
// 1. Read Check Write Software atomic bit Set on quadword in memory
//
//    RCWSSETPL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software atomic bit Set on quadword in memory atomically loads
// a 128-bit quadword from memory, performs a bitwise OR with the value held in a
// pair of registers on it, and conditionally stores the result back to memory.
// Storing of the result back to memory is conditional on RCW Checks and RCWS
// Checks. The value initially loaded from memory is returned in the same pair of
// registers. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSSETPA and RCWSSETPAL load from memory with acquire semantics.
//     * RCWSSETPL and RCWSSETPAL store to memory with release semantics.
//     * RCWSSETP has neither acquire nor release semantics.
//
func (self *Program) RCWSSETPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSETPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 0, 1, sa_xt2, 1, 3, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSETPL")
}

// RCWSSWP instruction have one single form across one single category:
//
// 1. Read Check Write Software Swap doubleword in memory
//
//    RCWSSWP  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software Swap doubleword in memory atomically loads a 64-bit
// doubleword from a memory location, and conditionally stores the value held in a
// register back to the same memory location. Storing back to memory is conditional
// on RCW Checks and RCWS Checks. The value initially loaded from memory is
// returned in the destination register. This instruction updates the condition
// flags based on the result of the update of memory.
//
//     * RCWSSWPA and RCWSSWPAL load from memory with acquire semantics.
//     * RCWSSWPL and RCWSSWPAL store to memory with release semantics.
//     * RCWSSWP has neither acquire nor release semantics.
//
func (self *Program) RCWSSWP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSWP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_xs, 1, 2, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSWP")
}

// RCWSSWPA instruction have one single form across one single category:
//
// 1. Read Check Write Software Swap doubleword in memory
//
//    RCWSSWPA  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software Swap doubleword in memory atomically loads a 64-bit
// doubleword from a memory location, and conditionally stores the value held in a
// register back to the same memory location. Storing back to memory is conditional
// on RCW Checks and RCWS Checks. The value initially loaded from memory is
// returned in the destination register. This instruction updates the condition
// flags based on the result of the update of memory.
//
//     * RCWSSWPA and RCWSSWPAL load from memory with acquire semantics.
//     * RCWSSWPL and RCWSSWPAL store to memory with release semantics.
//     * RCWSSWP has neither acquire nor release semantics.
//
func (self *Program) RCWSSWPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSWPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_xs, 1, 2, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSWPA")
}

// RCWSSWPAL instruction have one single form across one single category:
//
// 1. Read Check Write Software Swap doubleword in memory
//
//    RCWSSWPAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software Swap doubleword in memory atomically loads a 64-bit
// doubleword from a memory location, and conditionally stores the value held in a
// register back to the same memory location. Storing back to memory is conditional
// on RCW Checks and RCWS Checks. The value initially loaded from memory is
// returned in the destination register. This instruction updates the condition
// flags based on the result of the update of memory.
//
//     * RCWSSWPA and RCWSSWPAL load from memory with acquire semantics.
//     * RCWSSWPL and RCWSSWPAL store to memory with release semantics.
//     * RCWSSWP has neither acquire nor release semantics.
//
func (self *Program) RCWSSWPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSWPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_xs, 1, 2, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSWPAL")
}

// RCWSSWPL instruction have one single form across one single category:
//
// 1. Read Check Write Software Swap doubleword in memory
//
//    RCWSSWPL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Software Swap doubleword in memory atomically loads a 64-bit
// doubleword from a memory location, and conditionally stores the value held in a
// register back to the same memory location. Storing back to memory is conditional
// on RCW Checks and RCWS Checks. The value initially loaded from memory is
// returned in the destination register. This instruction updates the condition
// flags based on the result of the update of memory.
//
//     * RCWSSWPA and RCWSSWPAL load from memory with acquire semantics.
//     * RCWSSWPL and RCWSSWPAL store to memory with release semantics.
//     * RCWSSWP has neither acquire nor release semantics.
//
func (self *Program) RCWSSWPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSWPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_xs, 1, 2, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSWPL")
}

// RCWSSWPP instruction have one single form across one single category:
//
// 1. Read Check Write Software Swap quadword in memory
//
//    RCWSSWPP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software Swap quadword in memory atomically loads a 128-bit
// quadword from a memory location, and conditionally stores the value held in a
// pair of registers back to the same memory location. Storing back to memory is
// conditional on RCW Checks and RCWS Checks. The value initially loaded from
// memory is returned in the same pair of registers. This instruction updates the
// condition flags based on the result of the update of memory.
//
//     * RCWSSWPPA and RCWSSWPPAL load from memory with acquire semantics.
//     * RCWSSWPPL and RCWSSWPPAL store to memory with release semantics.
//     * RCWSSWPP has neither acquire nor release semantics.
//
func (self *Program) RCWSSWPP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSWPP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 0, 0, sa_xt2, 1, 2, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSWPP")
}

// RCWSSWPPA instruction have one single form across one single category:
//
// 1. Read Check Write Software Swap quadword in memory
//
//    RCWSSWPPA  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software Swap quadword in memory atomically loads a 128-bit
// quadword from a memory location, and conditionally stores the value held in a
// pair of registers back to the same memory location. Storing back to memory is
// conditional on RCW Checks and RCWS Checks. The value initially loaded from
// memory is returned in the same pair of registers. This instruction updates the
// condition flags based on the result of the update of memory.
//
//     * RCWSSWPPA and RCWSSWPPAL load from memory with acquire semantics.
//     * RCWSSWPPL and RCWSSWPPAL store to memory with release semantics.
//     * RCWSSWPP has neither acquire nor release semantics.
//
func (self *Program) RCWSSWPPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSWPPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 1, 0, sa_xt2, 1, 2, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSWPPA")
}

// RCWSSWPPAL instruction have one single form across one single category:
//
// 1. Read Check Write Software Swap quadword in memory
//
//    RCWSSWPPAL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software Swap quadword in memory atomically loads a 128-bit
// quadword from a memory location, and conditionally stores the value held in a
// pair of registers back to the same memory location. Storing back to memory is
// conditional on RCW Checks and RCWS Checks. The value initially loaded from
// memory is returned in the same pair of registers. This instruction updates the
// condition flags based on the result of the update of memory.
//
//     * RCWSSWPPA and RCWSSWPPAL load from memory with acquire semantics.
//     * RCWSSWPPL and RCWSSWPPAL store to memory with release semantics.
//     * RCWSSWPP has neither acquire nor release semantics.
//
func (self *Program) RCWSSWPPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSWPPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 1, 1, sa_xt2, 1, 2, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSWPPAL")
}

// RCWSSWPPL instruction have one single form across one single category:
//
// 1. Read Check Write Software Swap quadword in memory
//
//    RCWSSWPPL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Software Swap quadword in memory atomically loads a 128-bit
// quadword from a memory location, and conditionally stores the value held in a
// pair of registers back to the same memory location. Storing back to memory is
// conditional on RCW Checks and RCWS Checks. The value initially loaded from
// memory is returned in the same pair of registers. This instruction updates the
// condition flags based on the result of the update of memory.
//
//     * RCWSSWPPA and RCWSSWPPAL load from memory with acquire semantics.
//     * RCWSSWPPL and RCWSSWPPAL store to memory with release semantics.
//     * RCWSSWPP has neither acquire nor release semantics.
//
func (self *Program) RCWSSWPPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSSWPPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(1, 0, 1, sa_xt2, 1, 2, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSSWPPL")
}

// RCWSWP instruction have one single form across one single category:
//
// 1. Read Check Write Swap doubleword in memory
//
//    RCWSWP  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Swap doubleword in memory atomically loads a 64-bit doubleword
// from a memory location, and conditionally stores the value held in a register
// back to the same memory location. Storing back to memory is conditional on RCW
// Checks. The value initially loaded from memory is returned in the destination
// register. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSWPA and RCWSWPAL load from memory with acquire semantics.
//     * RCWSWPL and RCWSWPAL store to memory with release semantics.
//     * RCWSWP has neither acquire nor release semantics.
//
func (self *Program) RCWSWP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSWP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_xs, 1, 2, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSWP")
}

// RCWSWPA instruction have one single form across one single category:
//
// 1. Read Check Write Swap doubleword in memory
//
//    RCWSWPA  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Swap doubleword in memory atomically loads a 64-bit doubleword
// from a memory location, and conditionally stores the value held in a register
// back to the same memory location. Storing back to memory is conditional on RCW
// Checks. The value initially loaded from memory is returned in the destination
// register. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSWPA and RCWSWPAL load from memory with acquire semantics.
//     * RCWSWPL and RCWSWPAL store to memory with release semantics.
//     * RCWSWP has neither acquire nor release semantics.
//
func (self *Program) RCWSWPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSWPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_xs, 1, 2, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSWPA")
}

// RCWSWPAL instruction have one single form across one single category:
//
// 1. Read Check Write Swap doubleword in memory
//
//    RCWSWPAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Swap doubleword in memory atomically loads a 64-bit doubleword
// from a memory location, and conditionally stores the value held in a register
// back to the same memory location. Storing back to memory is conditional on RCW
// Checks. The value initially loaded from memory is returned in the destination
// register. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSWPA and RCWSWPAL load from memory with acquire semantics.
//     * RCWSWPL and RCWSWPAL store to memory with release semantics.
//     * RCWSWP has neither acquire nor release semantics.
//
func (self *Program) RCWSWPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSWPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_xs, 1, 2, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSWPAL")
}

// RCWSWPL instruction have one single form across one single category:
//
// 1. Read Check Write Swap doubleword in memory
//
//    RCWSWPL  <Xs>, <Xt>, [<Xn|SP>]
//
// Read Check Write Swap doubleword in memory atomically loads a 64-bit doubleword
// from a memory location, and conditionally stores the value held in a register
// back to the same memory location. Storing back to memory is conditional on RCW
// Checks. The value initially loaded from memory is returned in the destination
// register. This instruction updates the condition flags based on the result of
// the update of memory.
//
//     * RCWSWPA and RCWSWPAL load from memory with acquire semantics.
//     * RCWSWPL and RCWSWPAL store to memory with release semantics.
//     * RCWSWP has neither acquire nor release semantics.
//
func (self *Program) RCWSWPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSWPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_xs, 1, 2, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSWPL")
}

// RCWSWPP instruction have one single form across one single category:
//
// 1. Read Check Write Swap quadword in memory
//
//    RCWSWPP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Swap quadword in memory atomically loads a 128-bit quadword
// from a memory location, and conditionally stores the value held in a pair of
// registers back to the same memory location. Storing back to memory is
// conditional on RCW Checks. The value initially loaded from memory is returned in
// the same pair of registers. This instruction updates the condition flags based
// on the result of the update of memory.
//
//     * RCWSWPPA and RCWSWPPAL load from memory with acquire semantics.
//     * RCWSWPPL and RCWSWPPAL store to memory with release semantics.
//     * RCWSWPP has neither acquire nor release semantics.
//
func (self *Program) RCWSWPP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSWPP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 0, sa_xt2, 1, 2, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSWPP")
}

// RCWSWPPA instruction have one single form across one single category:
//
// 1. Read Check Write Swap quadword in memory
//
//    RCWSWPPA  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Swap quadword in memory atomically loads a 128-bit quadword
// from a memory location, and conditionally stores the value held in a pair of
// registers back to the same memory location. Storing back to memory is
// conditional on RCW Checks. The value initially loaded from memory is returned in
// the same pair of registers. This instruction updates the condition flags based
// on the result of the update of memory.
//
//     * RCWSWPPA and RCWSWPPAL load from memory with acquire semantics.
//     * RCWSWPPL and RCWSWPPAL store to memory with release semantics.
//     * RCWSWPP has neither acquire nor release semantics.
//
func (self *Program) RCWSWPPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSWPPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 0, sa_xt2, 1, 2, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSWPPA")
}

// RCWSWPPAL instruction have one single form across one single category:
//
// 1. Read Check Write Swap quadword in memory
//
//    RCWSWPPAL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Swap quadword in memory atomically loads a 128-bit quadword
// from a memory location, and conditionally stores the value held in a pair of
// registers back to the same memory location. Storing back to memory is
// conditional on RCW Checks. The value initially loaded from memory is returned in
// the same pair of registers. This instruction updates the condition flags based
// on the result of the update of memory.
//
//     * RCWSWPPA and RCWSWPPAL load from memory with acquire semantics.
//     * RCWSWPPL and RCWSWPPAL store to memory with release semantics.
//     * RCWSWPP has neither acquire nor release semantics.
//
func (self *Program) RCWSWPPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSWPPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 1, sa_xt2, 1, 2, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSWPPAL")
}

// RCWSWPPL instruction have one single form across one single category:
//
// 1. Read Check Write Swap quadword in memory
//
//    RCWSWPPL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Read Check Write Swap quadword in memory atomically loads a 128-bit quadword
// from a memory location, and conditionally stores the value held in a pair of
// registers back to the same memory location. Storing back to memory is
// conditional on RCW Checks. The value initially loaded from memory is returned in
// the same pair of registers. This instruction updates the condition flags based
// on the result of the update of memory.
//
//     * RCWSWPPA and RCWSWPPAL load from memory with acquire semantics.
//     * RCWSWPPL and RCWSWPPAL store to memory with release semantics.
//     * RCWSWPP has neither acquire nor release semantics.
//
func (self *Program) RCWSWPPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RCWSWPPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_D128)
        self.Arch.Require(FEAT_THE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 1, sa_xt2, 1, 2, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RCWSWPPL")
}

// RET instruction have one single form across one single category:
//
// 1. Return from subroutine
//
//    RET  {<Xn>}
//
// Return from subroutine branches unconditionally to an address in a register,
// with a hint that this is a subroutine return.
//
func (self *Program) RET(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("RET", 0, asm.Operands {})
        case 1  : p = self.alloc("RET", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction RET takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isXr(vv[0])) {
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(X30.ID())
        if len(vv) >= 1 {
            sa_xn = uint32(vv[0].(asm.Register).ID())
        }
        return p.setins(branch_reg(2, 31, 0, sa_xn, 0))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RET")
}

// RETAA instruction have one single form across one single category:
//
// 1. Return from subroutine, with pointer authentication
//
//    RETAA
//
// Return from subroutine, with pointer authentication. This instruction
// authenticates the address that is held in LR, using SP as the modifier and the
// specified key, branches to the authenticated address, with a hint that this
// instruction is a subroutine return.
//
// Key A is used for RETAA . Key B is used for RETAB .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to LR.
//
func (self *Program) RETAA() *Instruction {
    p := self.alloc("RETAA", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = asm.DomainGeneric
    return p.setins(branch_reg(2, 31, 2, 31, 31))
}

// RETAB instruction have one single form across one single category:
//
// 1. Return from subroutine, with pointer authentication
//
//    RETAB
//
// Return from subroutine, with pointer authentication. This instruction
// authenticates the address that is held in LR, using SP as the modifier and the
// specified key, branches to the authenticated address, with a hint that this
// instruction is a subroutine return.
//
// Key A is used for RETAA . Key B is used for RETAB .
//
// If the authentication passes, the PE continues execution at the target of the
// branch. For information on behavior if the authentication fails, see Faulting on
// pointer authentication .
//
// The authenticated address is not written back to LR.
//
func (self *Program) RETAB() *Instruction {
    p := self.alloc("RETAB", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = asm.DomainGeneric
    return p.setins(branch_reg(2, 31, 3, 31, 31))
}

// REV instruction have 2 forms across one single category:
//
// 1. Reverse Bytes
//
//    REV  <Wd>, <Wn>
//    REV  <Xd>, <Xn>
//
// Reverse Bytes reverses the byte order in a register.
//
func (self *Program) REV(v0, v1 interface{}) *Instruction {
    p := self.alloc("REV", 2, asm.Operands { v0, v1 })
    // REV  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(0, 0, 0, 2, sa_wn, sa_wd))
    }
    // REV  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 3, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for REV")
}

// REV16 instruction have 3 forms across 2 categories:
//
// 1. Reverse elements in 16-bit halfwords (vector)
//
//    REV16  <Vd>.<T>, <Vn>.<T>
//
// Reverse elements in 16-bit halfwords (vector). This instruction reverses the
// order of 8-bit elements in each halfword of the vector in the source SIMD&FP
// register, places the results into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Reverse bytes in 16-bit halfwords
//
//    REV16  <Wd>, <Wn>
//    REV16  <Xd>, <Xn>
//
// Reverse bytes in 16-bit halfwords reverses the byte order in each 16-bit
// halfword of a register.
//
func (self *Program) REV16(v0, v1 interface{}) *Instruction {
    p := self.alloc("REV16", 2, asm.Operands { v0, v1 })
    // REV16  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec8B, Vec16B) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B) && vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 1, sa_vn, sa_vd))
    }
    // REV16  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(0, 0, 0, 1, sa_wn, sa_wd))
    }
    // REV16  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for REV16")
}

// REV32 instruction have 2 forms across 2 categories:
//
// 1. Reverse elements in 32-bit words (vector)
//
//    REV32  <Vd>.<T>, <Vn>.<T>
//
// Reverse elements in 32-bit words (vector). This instruction reverses the order
// of 8-bit or 16-bit elements in each word of the vector in the source SIMD&FP
// register, places the results into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Reverse bytes in 32-bit words
//
//    REV32  <Xd>, <Xn>
//
// Reverse bytes in 32-bit words reverses the byte order in each 32-bit word of a
// register.
//
func (self *Program) REV32(v0, v1 interface{}) *Instruction {
    p := self.alloc("REV32", 2, asm.Operands { v0, v1 })
    // REV32  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 0, sa_vn, sa_vd))
    }
    // REV32  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 2, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for REV32")
}

// REV64 instruction have 2 forms across 2 categories:
//
// 1. Reverse Bytes
//
//    REV64  <Xd>, <Xn>
//
// Reverse Bytes reverses the byte order in a 64-bit general-purpose register.
//
// When assembling for Armv8.2, an assembler must support this pseudo-instruction.
// It is optional whether an assembler supports this pseudo-instruction when
// assembling for an architecture earlier than Armv8.2.
//
// 2. Reverse elements in 64-bit doublewords (vector)
//
//    REV64  <Vd>.<T>, <Vn>.<T>
//
// Reverse elements in 64-bit doublewords (vector). This instruction reverses the
// order of 8-bit, 16-bit, or 32-bit elements in each doubleword of the vector in
// the source SIMD&FP register, places the results into a vector, and writes the
// vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) REV64(v0, v1 interface{}) *Instruction {
    p := self.alloc("REV64", 2, asm.Operands { v0, v1 })
    // REV64  <Xd>, <Xn>
    if isXr(v0) && isXr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 0, 3, sa_xn, sa_xd))
    }
    // REV64  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 0, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for REV64")
}

// RMIF instruction have one single form across one single category:
//
// 1. Rotate, Mask Insert Flags
//
//    RMIF  <Xn>, #<shift>, #<mask>
//
// Performs a rotation right of a value held in a general purpose register by an
// immediate value, and then inserts a selection of the bottom four bits of the
// result of the rotation into the PSTATE flags, under the control of a second
// immediate mask.
//
func (self *Program) RMIF(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RMIF", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isInRange(v1, 0, 63) && isInRange(v2, 0, 15) {
        self.Arch.Require(FEAT_FlagM)
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_shift := asUimm6(v1)
        sa_mask := asUimm4(v2)
        return p.setins(rmif(1, 0, 1, sa_shift, sa_xn, 0, sa_mask))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RMIF")
}

// ROR instruction have 4 forms across 2 categories:
//
// 1. Rotate right (immediate)
//
//    ROR  <Wd>, <Ws>, #<shift>
//    ROR  <Xd>, <Xs>, #<shift>
//
// Rotate right (immediate) provides the value of the contents of a register
// rotated by a variable number of bits. The bits that are rotated off the right
// end are inserted into the vacated bit positions on the left.
//
// 2. Rotate Right (register)
//
//    ROR  <Wd>, <Wn>, <Wm>
//    ROR  <Xd>, <Xn>, <Xm>
//
// Rotate Right (register) provides the value of the contents of a register rotated
// by a variable number of bits. The bits that are rotated off the right end are
// inserted into the vacated bit positions on the left. The remainder obtained by
// dividing the second source register by the data size defines the number of bits
// by which the first source register is right-shifted.
//
func (self *Program) ROR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ROR", 3, asm.Operands { v0, v1, v2 })
    // ROR  <Wd>, <Ws>, #<shift>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_ws := uint32(v1.(asm.Register).ID())
        sa_shift := asUimm6(v2)
        return p.setins(extract(0, 0, 0, 0, ubfx(sa_ws, 5, 5), sa_shift, mask(sa_ws, 5), sa_wd))
    }
    // ROR  <Xd>, <Xs>, #<shift>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xs := uint32(v1.(asm.Register).ID())
        sa_shift_1 := asUimm6(v2)
        return p.setins(extract(1, 0, 1, 0, ubfx(sa_xs, 5, 5), sa_shift_1, mask(sa_xs, 5), sa_xd))
    }
    // ROR  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 11, sa_wn, sa_wd))
    }
    // ROR  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 11, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ROR")
}

// RORV instruction have 2 forms across one single category:
//
// 1. Rotate Right Variable
//
//    RORV  <Wd>, <Wn>, <Wm>
//    RORV  <Xd>, <Xn>, <Xm>
//
// Rotate Right Variable provides the value of the contents of a register rotated
// by a variable number of bits. The bits that are rotated off the right end are
// inserted into the vacated bit positions on the left. The remainder obtained by
// dividing the second source register by the data size defines the number of bits
// by which the first source register is right-shifted.
//
func (self *Program) RORV(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RORV", 3, asm.Operands { v0, v1, v2 })
    // RORV  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 11, sa_wn, sa_wd))
    }
    // RORV  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 11, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for RORV")
}

// RPRFM instruction have one single form across one single category:
//
// 1. Range Prefetch Memory
//
//    RPRFM  (<rprfop>|#<imm6>), <Xm>, [<Xn|SP>]
//
// Range Prefetch Memory signals the memory system that data memory accesses from a
// specified range of addresses are likely to occur in the near future. The
// instruction may also signal the memory system about the likelihood of data reuse
// of the specified range of addresses. The memory system can respond by taking
// actions that are expected to speed up the memory accesses when they do occur,
// such as prefetching locations within the specified address ranges into one or
// more caches. The memory system may also exploit the data reuse hints to decide
// whether to retain the data in other caches upon eviction from the innermost
// caches or to discard it.
//
// The effect of an RPRFM instruction is implementation defined , but because these
// signals are only hints, the instruction cannot cause a synchronous Data Abort
// exception and is guaranteed not to access Device memory. It is valid for the PE
// to treat this instruction as a NOP.
//
// An RPRFM instruction specifies the type of accesses and range of addresses using
// the following parameters:
//
//     * 'Type', in the <rprfop> operand opcode bits, specifies whether the
//       prefetched data will be accessed by load or store instructions.
//     * 'Policy', in the <rprfop> operand opcode bits, specifies whether the
//       data is likely to be reused or if it is a streaming, non-temporal
//       prefetch. If a streaming prefetch is specified, then the
//       'ReuseDistance' parameter is ignored.
//     * 'BaseAddress', in the 64-bit base register, holds the initial block
//       address for the accesses.
//     * 'ReuseDistance', in the metadata register bits[63:60], indicates the
//       maximum number of bytes to be accessed by this PE before executing the
//       next RPRFM instruction that specifies the same range. This includes
//       the total number of bytes inside and outside of the range that will be
//       accessed by the same PE. This parameter can be used to influence cache
//       eviction and replacement policies, in order to retain the data in the
//       most optimal levels of the memory hierarchy after each access. If
//       software cannot easily determine the amount of other memory that will
//       be accessed, these bits can be set to zero to indicate that
//       'ReuseDistance' is not known. Otherwise, these four bits encode
//       decreasing powers of two in the range 512MiB ( 0b0001 ) to 32KiB (
//       0b1111 ).
//     * 'Stride', in the metadata register bits[59:38], is a signed, two's
//       complement integer encoding of the number of bytes to advance the
//       block address after 'Length' bytes have been accessed, in the range
//       -2MiB to +2MiB-1B. A negative value indicates that the block address
//       is advanced in a descending direction.
//     * 'Count', in the metadata register bits[37:22], is an unsigned integer
//       encoding of the number of blocks of data to be accessed minus 1,
//       representing the range 1 to 65536 blocks. If 'Count' is 0, then the
//       'Stride' parameter is ignored and only a single block of contiguous
//       bytes from 'BaseAddress' to ('BaseAddress' + 'Length' - 1) is
//       described.
//     * 'Length', in the metadata register bits[21:0], is a signed, two's
//       complement integer encoding of the number of contiguous bytes to be
//       accessed starting from the current block address, without changing the
//       block address, in the range -2MiB to +2MiB-1B. A negative value
//       indicates that the bytes are accessed in a descending direction.
//
// NOTE: 
//     Software is expected to honor the parameters it provides to the RPRFM
//     instruction, and the same PE should access all locations in the range,
//     in the direction specified by the sign of the 'Length' and 'Stride'
//     parameters. A range prefetch is considered active on a PE until all
//     locations in the range have been accessed by the PE. A range prefetch
//     might also be inactivated by the PE prior to completion, for example due
//     to a software context switch or lack of hardware resources.
//
//     Software should not specify overlapping addresses in multiple active
//     ranges. If a range is expected to be accessed by both load and store
//     instructions (read-modify-write), then a single range with a 'Type'
//     parameter of PST (prefetch for store) should be specified.
//
func (self *Program) RPRFM(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RPRFM", 3, asm.Operands { v0, v1, v2 })
    if isRangePrf(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_RPRFM)
        p.Domain = asm.DomainGeneric
        sa_rprfop := asRangePrefetchOp(v0)
        sa_xm := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldst_regoff(
            3,
            0,
            2,
            sa_xm,
            mask(sa_rprfop, 3),
            ubfx(sa_rprfop, 3, 1),
            sa_xn_sp,
            ubfx(sa_rprfop, 4, 5),
        ))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RPRFM")
}

// RSHRN instruction have one single form across one single category:
//
// 1. Rounding Shift Right Narrow (immediate)
//
//    RSHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Rounding Shift Right Narrow (immediate). This instruction reads each unsigned
// integer value from the vector in the source SIMD&FP register, right shifts each
// result by an immediate value, writes the final result to a vector, and writes
// the vector to the lower or upper half of the destination SIMD&FP register. The
// destination vector elements are half as long as the source vector elements. The
// results are rounded. For truncated results, see SHRN .
//
// The RSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the RSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) RSHRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RSHRN", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for RSHRN")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for RSHRN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for RSHRN")
        }
        return p.setins(asimdshf(0, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 17, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RSHRN")
}

// RSHRN2 instruction have one single form across one single category:
//
// 1. Rounding Shift Right Narrow (immediate)
//
//    RSHRN2  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Rounding Shift Right Narrow (immediate). This instruction reads each unsigned
// integer value from the vector in the source SIMD&FP register, right shifts each
// result by an immediate value, writes the final result to a vector, and writes
// the vector to the lower or upper half of the destination SIMD&FP register. The
// destination vector elements are half as long as the source vector elements. The
// results are rounded. For truncated results, see SHRN .
//
// The RSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the RSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) RSHRN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RSHRN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for RSHRN2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for RSHRN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for RSHRN2")
        }
        return p.setins(asimdshf(1, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 17, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RSHRN2")
}

// RSUBHN instruction have one single form across one single category:
//
// 1. Rounding Subtract returning High Narrow
//
//    RSUBHN  <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>
//
// Rounding Subtract returning High Narrow. This instruction subtracts each vector
// element of the second source SIMD&FP register from the corresponding vector
// element of the first source SIMD&FP register, places the most significant half
// of the result into a vector, and writes the vector to the lower or upper half of
// the destination SIMD&FP register.
//
// The results are rounded. For truncated results, see SUBHN .
//
// The RSUBHN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the RSUBHN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) RSUBHN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RSUBHN", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8H, Vec4S, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for RSUBHN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for RSUBHN")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RSUBHN")
}

// RSUBHN2 instruction have one single form across one single category:
//
// 1. Rounding Subtract returning High Narrow
//
//    RSUBHN2  <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>
//
// Rounding Subtract returning High Narrow. This instruction subtracts each vector
// element of the second source SIMD&FP register from the corresponding vector
// element of the first source SIMD&FP register, places the most significant half
// of the result into a vector, and writes the vector to the lower or upper half of
// the destination SIMD&FP register.
//
// The results are rounded. For truncated results, see SUBHN .
//
// The RSUBHN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the RSUBHN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) RSUBHN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("RSUBHN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8H, Vec4S, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for RSUBHN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for RSUBHN2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for RSUBHN2")
}

// SABA instruction have one single form across one single category:
//
// 1. Signed Absolute difference and Accumulate
//
//    SABA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Signed Absolute difference and Accumulate. This instruction subtracts the
// elements of the vector of the second source SIMD&FP register from the
// corresponding elements of the first source SIMD&FP register, and accumulates the
// absolute values of the results into the elements of the vector of the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SABA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SABA", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 15, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SABA")
}

// SABAL instruction have one single form across one single category:
//
// 1. Signed Absolute difference and Accumulate Long
//
//    SABAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Absolute difference and Accumulate Long. This instruction subtracts the
// vector elements in the lower or upper half of the second source SIMD&FP register
// from the corresponding vector elements of the first source SIMD&FP register, and
// accumulates the absolute values of the results into the vector elements of the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the source vector elements.
//
// The SABAL instruction extracts each source vector from the lower half of each
// source register. The SABAL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SABAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SABAL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SABAL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SABAL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 5, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SABAL")
}

// SABAL2 instruction have one single form across one single category:
//
// 1. Signed Absolute difference and Accumulate Long
//
//    SABAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Absolute difference and Accumulate Long. This instruction subtracts the
// vector elements in the lower or upper half of the second source SIMD&FP register
// from the corresponding vector elements of the first source SIMD&FP register, and
// accumulates the absolute values of the results into the vector elements of the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the source vector elements.
//
// The SABAL instruction extracts each source vector from the lower half of each
// source register. The SABAL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SABAL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SABAL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SABAL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SABAL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 5, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SABAL2")
}

// SABD instruction have one single form across one single category:
//
// 1. Signed Absolute Difference
//
//    SABD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Signed Absolute Difference. This instruction subtracts the elements of the
// vector of the second source SIMD&FP register from the corresponding elements of
// the first source SIMD&FP register, places the absolute values of the results
// into a vector, and writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SABD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SABD", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 14, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SABD")
}

// SABDL instruction have one single form across one single category:
//
// 1. Signed Absolute Difference Long
//
//    SABDL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Absolute Difference Long. This instruction subtracts the vector elements
// in the lower or upper half of the second source SIMD&FP register from the
// corresponding vector elements of the first source SIMD&FP register, places the
// absolute value of the results into a vector, and writes the vector to the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the source vector elements.
//
// The SABDL instruction extracts each source vector from the lower half of each
// source register. The SABDL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SABDL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SABDL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SABDL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SABDL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 7, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SABDL")
}

// SABDL2 instruction have one single form across one single category:
//
// 1. Signed Absolute Difference Long
//
//    SABDL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Absolute Difference Long. This instruction subtracts the vector elements
// in the lower or upper half of the second source SIMD&FP register from the
// corresponding vector elements of the first source SIMD&FP register, places the
// absolute value of the results into a vector, and writes the vector to the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the source vector elements.
//
// The SABDL instruction extracts each source vector from the lower half of each
// source register. The SABDL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SABDL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SABDL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SABDL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SABDL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 7, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SABDL2")
}

// SADALP instruction have one single form across one single category:
//
// 1. Signed Add and Accumulate Long Pairwise
//
//    SADALP  <Vd>.<Ta>, <Vn>.<Tb>
//
// Signed Add and Accumulate Long Pairwise. This instruction adds pairs of adjacent
// signed integer values from the vector in the source SIMD&FP register and
// accumulates the results into the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the source vector
// elements.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SADALP(v0, v1 interface{}) *Instruction {
    p := self.alloc("SADALP", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec1D, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_ta = 0b000
            case Vec8H: sa_ta = 0b001
            case Vec2S: sa_ta = 0b010
            case Vec4S: sa_ta = 0b011
            case Vec1D: sa_ta = 0b100
            case Vec2D: sa_ta = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_ta, 1, 2) != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SADALP")
        }
        if mask(sa_ta, 1) != mask(sa_tb, 1) {
            panic("aarch64: invalid combination of operands for SADALP")
        }
        return p.setins(asimdmisc(mask(sa_ta, 1), 0, ubfx(sa_ta, 1, 2), 6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SADALP")
}

// SADDL instruction have one single form across one single category:
//
// 1. Signed Add Long (vector)
//
//    SADDL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Add Long (vector). This instruction adds each vector element in the lower
// or upper half of the first source SIMD&FP register to the corresponding vector
// element of the second source SIMD&FP register, places the results into a vector,
// and writes the vector to the destination SIMD&FP register. The destination
// vector elements are twice as long as the source vector elements. All the values
// in this instruction are signed integer values.
//
// The SADDL instruction extracts each source vector from the lower half of each
// source register. The SADDL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SADDL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SADDL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SADDL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SADDL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 0, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SADDL")
}

// SADDL2 instruction have one single form across one single category:
//
// 1. Signed Add Long (vector)
//
//    SADDL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Add Long (vector). This instruction adds each vector element in the lower
// or upper half of the first source SIMD&FP register to the corresponding vector
// element of the second source SIMD&FP register, places the results into a vector,
// and writes the vector to the destination SIMD&FP register. The destination
// vector elements are twice as long as the source vector elements. All the values
// in this instruction are signed integer values.
//
// The SADDL instruction extracts each source vector from the lower half of each
// source register. The SADDL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SADDL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SADDL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SADDL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SADDL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 0, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SADDL2")
}

// SADDLP instruction have one single form across one single category:
//
// 1. Signed Add Long Pairwise
//
//    SADDLP  <Vd>.<Ta>, <Vn>.<Tb>
//
// Signed Add Long Pairwise. This instruction adds pairs of adjacent signed integer
// values from the vector in the source SIMD&FP register, places the result into a
// vector, and writes the vector to the destination SIMD&FP register. The
// destination vector elements are twice as long as the source vector elements.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SADDLP(v0, v1 interface{}) *Instruction {
    p := self.alloc("SADDLP", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec1D, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_ta = 0b000
            case Vec8H: sa_ta = 0b001
            case Vec2S: sa_ta = 0b010
            case Vec4S: sa_ta = 0b011
            case Vec1D: sa_ta = 0b100
            case Vec2D: sa_ta = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_ta, 1, 2) != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SADDLP")
        }
        if mask(sa_ta, 1) != mask(sa_tb, 1) {
            panic("aarch64: invalid combination of operands for SADDLP")
        }
        return p.setins(asimdmisc(mask(sa_ta, 1), 0, ubfx(sa_ta, 1, 2), 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SADDLP")
}

// SADDLV instruction have one single form across one single category:
//
// 1. Signed Add Long across Vector
//
//    SADDLV  <V><d>, <Vn>.<T>
//
// Signed Add Long across Vector. This instruction adds every vector element in the
// source SIMD&FP register together, and writes the scalar result to the
// destination SIMD&FP register. The destination scalar is twice as long as the
// source vector elements. All the values in this instruction are signed integer
// values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SADDLV(v0, v1 interface{}) *Instruction {
    p := self.alloc("SADDLV", 2, asm.Operands { v0, v1 })
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b00
            case SRegister: sa_v = 0b01
            case DRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SADDLV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_t, 1, 2) != sa_v {
            panic("aarch64: invalid combination of operands for SADDLV")
        }
        return p.setins(asimdall(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 3, sa_vn, sa_d))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SADDLV")
}

// SADDW instruction have one single form across one single category:
//
// 1. Signed Add Wide
//
//    SADDW  <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>
//
// Signed Add Wide. This instruction adds vector elements of the first source
// SIMD&FP register to the corresponding vector elements in the lower or upper half
// of the second source SIMD&FP register, places the results in a vector, and
// writes the vector to the SIMD&FP destination register.
//
// The SADDW instruction extracts the second source vector from the lower half of
// the second source register. The SADDW2 instruction extracts the second source
// vector from the upper half of the second source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SADDW(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SADDW", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch vfmt(v2) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SADDW")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SADDW")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 1, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SADDW")
}

// SADDW2 instruction have one single form across one single category:
//
// 1. Signed Add Wide
//
//    SADDW2  <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>
//
// Signed Add Wide. This instruction adds vector elements of the first source
// SIMD&FP register to the corresponding vector elements in the lower or upper half
// of the second source SIMD&FP register, places the results in a vector, and
// writes the vector to the SIMD&FP destination register.
//
// The SADDW instruction extracts the second source vector from the lower half of
// the second source register. The SADDW2 instruction extracts the second source
// vector from the upper half of the second source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SADDW2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SADDW2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch vfmt(v2) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SADDW2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SADDW2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 1, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SADDW2")
}

// SB instruction have one single form across one single category:
//
// 1. Speculation Barrier
//
//    SB
//
// Speculation Barrier is a barrier that controls speculation.
//
// The semantics of the Speculation Barrier are that the execution, until the
// barrier completes, of any instruction that appears later in the program order
// than the barrier:
//
//     * Cannot be performed speculatively to the extent that such speculation
//       can be observed through side-channels as a result of control flow
//       speculation or data value speculation.
//     * Can be speculatively executed as a result of predicting that a
//       potentially exception generating instruction has not generated an
//       exception.
//
// In particular, any instruction that appears later in the program order than the
// barrier cannot cause a speculative allocation into any caching structure where
// the allocation of that entry could be indicative of any data value present in
// memory or in the registers.
//
// The SB instruction:
//
//     * Cannot be speculatively executed as a result of control flow
//       speculation or data value speculation.
//     * Can be speculatively executed as a result of predicting that a
//       potentially exception generating instruction has not generated an
//       exception. The potentially exception generating instruction can
//       complete once it is known not to be speculative, and all data values
//       generated by instructions appearing in program order before the SB
//       instruction have their predicted values confirmed.
//
// When the prediction of the instruction stream is not informed by data taken from
// the register outputs of the speculative execution of instructions appearing in
// program order after an uncompleted SB instruction, the SB instruction has no
// effect on the use of prediction resources to predict the instruction stream that
// is being fetched.
//
func (self *Program) SB() *Instruction {
    p := self.alloc("SB", 0, asm.Operands {})
    self.Arch.Require(FEAT_SB)
    p.Domain = DomainSystem
    return p.setins(barriers(0, 7, 31))
}

// SBC instruction have 2 forms across one single category:
//
// 1. Subtract with Carry
//
//    SBC  <Wd>, <Wn>, <Wm>
//    SBC  <Xd>, <Xn>, <Xm>
//
// Subtract with Carry subtracts a register value and the value of NOT (Carry flag)
// from a register value, and writes the result to the destination register.
//
func (self *Program) SBC(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SBC", 3, asm.Operands { v0, v1, v2 })
    // SBC  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(addsub_carry(0, 1, 0, sa_wm, sa_wn, sa_wd))
    }
    // SBC  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(addsub_carry(1, 1, 0, sa_xm, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SBC")
}

// SBCS instruction have 2 forms across one single category:
//
// 1. Subtract with Carry, setting flags
//
//    SBCS  <Wd>, <Wn>, <Wm>
//    SBCS  <Xd>, <Xn>, <Xm>
//
// Subtract with Carry, setting flags, subtracts a register value and the value of
// NOT (Carry flag) from a register value, and writes the result to the destination
// register. It updates the condition flags based on the result.
//
func (self *Program) SBCS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SBCS", 3, asm.Operands { v0, v1, v2 })
    // SBCS  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(addsub_carry(0, 1, 1, sa_wm, sa_wn, sa_wd))
    }
    // SBCS  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(addsub_carry(1, 1, 1, sa_xm, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SBCS")
}

// SBFIZ instruction have 2 forms across one single category:
//
// 1. Signed Bitfield Insert in Zero
//
//    SBFIZ  <Wd>, <Wn>, #<lsb>, #<width>
//    SBFIZ  <Xd>, <Xn>, #<lsb>, #<width>
//
// Signed Bitfield Insert in Zeros copies a bitfield of <width> bits from the least
// significant bits of the source register to bit position <lsb> of the destination
// register, setting the destination bits below the bitfield to zero, and the bits
// above the bitfield to a copy of the most significant bit of the bitfield.
//
func (self *Program) SBFIZ(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("SBFIZ", 4, asm.Operands { v0, v1, v2, v3 })
    // SBFIZ  <Wd>, <Wn>, #<lsb>, #<width>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) && isBFxWidth(v2, v3, 32) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_lsb := -asUimm5(v2) % 32
        sa_width := asUimm5(v3) - 1
        return p.setins(bitfield(0, 0, 0, sa_lsb, sa_width, sa_wn, sa_wd))
    }
    // SBFIZ  <Xd>, <Xn>, #<lsb>, #<width>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) && isBFxWidth(v2, v3, 64) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_lsb_2 := -asUimm6(v2) % 64
        sa_width_1 := asUimm6(v3) - 1
        return p.setins(bitfield(1, 0, 1, sa_lsb_2, sa_width_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SBFIZ")
}

// SBFM instruction have 2 forms across one single category:
//
// 1. Signed Bitfield Move
//
//    SBFM  <Wd>, <Wn>, #<immr>, #<imms>
//    SBFM  <Xd>, <Xn>, #<immr>, #<imms>
//
// Signed Bitfield Move is usually accessed via one of its aliases, which are
// always preferred for disassembly.
//
// If <imms> is greater than or equal to <immr> , this copies a bitfield of (
// <imms> - <immr> +1) bits starting from bit position <immr> in the source
// register to the least significant bits of the destination register.
//
// If <imms> is less than <immr> , this copies a bitfield of ( <imms> +1) bits from
// the least significant bits of the source register to bit position (regsize-
// <immr> ) of the destination register, where regsize is the destination register
// size of 32 or 64 bits.
//
// In both cases the destination bits below the bitfield are set to zero, and the
// bits above the bitfield are set to a copy of the most significant bit of the
// bitfield.
//
func (self *Program) SBFM(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("SBFM", 4, asm.Operands { v0, v1, v2, v3 })
    // SBFM  <Wd>, <Wn>, #<immr>, #<imms>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) && isInRange(v3, 0, 31) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_immr := asUimm6(v2)
        sa_imms := asUimm6(v3)
        return p.setins(bitfield(0, 0, 0, sa_immr, sa_imms, sa_wn, sa_wd))
    }
    // SBFM  <Xd>, <Xn>, #<immr>, #<imms>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) && isInRange(v3, 0, 63) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_immr_1 := asUimm6(v2)
        sa_imms_1 := asUimm6(v3)
        return p.setins(bitfield(1, 0, 1, sa_immr_1, sa_imms_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SBFM")
}

// SBFX instruction have 2 forms across one single category:
//
// 1. Signed Bitfield Extract
//
//    SBFX  <Wd>, <Wn>, #<lsb>, #<width>
//    SBFX  <Xd>, <Xn>, #<lsb>, #<width>
//
// Signed Bitfield Extract copies a bitfield of <width> bits starting from bit
// position <lsb> in the source register to the least significant bits of the
// destination register, and sets destination bits above the bitfield to a copy of
// the most significant bit of the bitfield.
//
func (self *Program) SBFX(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("SBFX", 4, asm.Operands { v0, v1, v2, v3 })
    // SBFX  <Wd>, <Wn>, #<lsb>, #<width>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) && isBFxWidth(v2, v3, 32) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_lsb_1 := asUimm5(v2)
        sa_width := sa_lsb_1 + asUimm5(v3) - 1
        return p.setins(bitfield(0, 0, 0, sa_lsb_1, sa_width, sa_wn, sa_wd))
    }
    // SBFX  <Xd>, <Xn>, #<lsb>, #<width>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) && isBFxWidth(v2, v3, 64) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_lsb_3 := asUimm6(v2)
        sa_width_1 := sa_lsb_3 + asUimm6(v3) - 1
        return p.setins(bitfield(1, 0, 1, sa_lsb_3, sa_width_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SBFX")
}

// SCVTF instruction have 18 forms across 4 categories:
//
// 1. Signed fixed-point Convert to Floating-point (vector)
//
//    SCVTF  <Vd>.<T>, <Vn>.<T>, #<fbits>
//    SCVTF  <V><d>, <V><n>, #<fbits>
//
// Signed fixed-point Convert to Floating-point (vector). This instruction converts
// each element in a vector from fixed-point to floating-point using the rounding
// mode that is specified by the FPCR , and writes the result to the SIMD&FP
// destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Signed integer Convert to Floating-point (vector)
//
//    SCVTF  <Vd>.<T>, <Vn>.<T>
//    SCVTF  <Vd>.<T>, <Vn>.<T>
//    SCVTF  <V><d>, <V><n>
//    SCVTF  <Hd>, <Hn>
//
// Signed integer Convert to Floating-point (vector). This instruction converts
// each element in a vector from signed integer to floating-point using the
// rounding mode that is specified by the FPCR , and writes the result to the
// SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 3. Signed fixed-point Convert to Floating-point (scalar)
//
//    SCVTF  <Dd>, <Wn>, #<fbits>
//    SCVTF  <Dd>, <Xn>, #<fbits>
//    SCVTF  <Hd>, <Wn>, #<fbits>
//    SCVTF  <Hd>, <Xn>, #<fbits>
//    SCVTF  <Sd>, <Wn>, #<fbits>
//    SCVTF  <Sd>, <Xn>, #<fbits>
//
// Signed fixed-point Convert to Floating-point (scalar). This instruction converts
// the signed value in the 32-bit or 64-bit general-purpose source register to a
// floating-point value using the rounding mode that is specified by the FPCR , and
// writes the result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 4. Signed integer Convert to Floating-point (scalar)
//
//    SCVTF  <Dd>, <Wn>
//    SCVTF  <Dd>, <Xn>
//    SCVTF  <Hd>, <Wn>
//    SCVTF  <Hd>, <Xn>
//    SCVTF  <Sd>, <Wn>
//    SCVTF  <Sd>, <Xn>
//
// Signed integer Convert to Floating-point (scalar). This instruction converts the
// signed integer value in the general-purpose source register to a floating-point
// value using the rounding mode that is specified by the FPCR , and writes the
// result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SCVTF(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("SCVTF", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("SCVTF", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction SCVTF takes 2 or 3 operands")
    }
    // SCVTF  <Vd>.<T>, <Vn>.<T>, #<fbits>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(vv[0]) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_fbits uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0010: sa_fbits = 32 - uint32(asLit(vv[0]))
            case 0b0100: sa_fbits = 64 - uint32(asLit(vv[0]))
            case 0b1000: sa_fbits = 128 - uint32(asLit(vv[0]))
            default: panic("aarch64: invalid operand 'sa_fbits' for SCVTF")
        }
        if ubfx(sa_fbits, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SCVTF")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 0, ubfx(sa_fbits, 3, 4), mask(sa_fbits, 3), 28, sa_vn, sa_vd))
    }
    // SCVTF  <V><d>, <V><n>, #<fbits>
    if len(vv) == 1 && isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(vv[0]) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_fbits_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b0010
            case SRegister: sa_v = 0b0100
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SCVTF")
        }
        switch v0.(type) {
            case HRegister: sa_v__bit_mask = 0b1110
            case SRegister: sa_v__bit_mask = 0b1100
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SCVTF")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b0010: sa_fbits_1 = 32 - uint32(asLit(vv[0]))
            case 0b0100: sa_fbits_1 = 64 - uint32(asLit(vv[0]))
            case 0b1000: sa_fbits_1 = 128 - uint32(asLit(vv[0]))
            default: panic("aarch64: invalid operand 'sa_fbits_1' for SCVTF")
        }
        if ubfx(sa_fbits_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SCVTF")
        }
        return p.setins(asisdshf(0, ubfx(sa_fbits_1, 3, 4), mask(sa_fbits_1, 3), 28, sa_n, sa_d))
    }
    // SCVTF  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 29, sa_vn, sa_vd))
    }
    // SCVTF  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 0, 0, 29, sa_vn, sa_vd))
    }
    // SCVTF  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for SCVTF")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdmisc(0, size, 29, sa_n, sa_d))
    }
    // SCVTF  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(0, 0, 29, sa_hn, sa_hd))
    }
    // SCVTF  <Dd>, <Wn>, #<fbits>
    if len(vv) == 1 && isDr(v0) && isWr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 1, 0, 2, sa_fbits, sa_wn, sa_dd))
    }
    // SCVTF  <Dd>, <Xn>, #<fbits>
    if len(vv) == 1 && isDr(v0) && isXr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 1, 0, 2, sa_fbits_1, sa_xn, sa_dd))
    }
    // SCVTF  <Hd>, <Wn>, #<fbits>
    if len(vv) == 1 && isHr(v0) && isWr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 3, 0, 2, sa_fbits, sa_wn, sa_hd))
    }
    // SCVTF  <Hd>, <Xn>, #<fbits>
    if len(vv) == 1 && isHr(v0) && isXr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 3, 0, 2, sa_fbits_1, sa_xn, sa_hd))
    }
    // SCVTF  <Sd>, <Wn>, #<fbits>
    if len(vv) == 1 && isSr(v0) && isWr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 0, 0, 2, sa_fbits, sa_wn, sa_sd))
    }
    // SCVTF  <Sd>, <Xn>, #<fbits>
    if len(vv) == 1 && isSr(v0) && isXr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 0, 0, 2, sa_fbits_1, sa_xn, sa_sd))
    }
    // SCVTF  <Dd>, <Wn>
    if isDr(v0) && isWr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 0, 2, sa_wn, sa_dd))
    }
    // SCVTF  <Dd>, <Xn>
    if isDr(v0) && isXr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 0, 2, sa_xn, sa_dd))
    }
    // SCVTF  <Hd>, <Wn>
    if isHr(v0) && isWr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 0, 2, sa_wn, sa_hd))
    }
    // SCVTF  <Hd>, <Xn>
    if isHr(v0) && isXr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 0, 2, sa_xn, sa_hd))
    }
    // SCVTF  <Sd>, <Wn>
    if isSr(v0) && isWr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 0, 2, sa_wn, sa_sd))
    }
    // SCVTF  <Sd>, <Xn>
    if isSr(v0) && isXr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 0, 2, sa_xn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SCVTF")
}

// SDIV instruction have 2 forms across one single category:
//
// 1. Signed Divide
//
//    SDIV  <Wd>, <Wn>, <Wm>
//    SDIV  <Xd>, <Xn>, <Xm>
//
// Signed Divide divides a signed integer register value by another signed integer
// register value, and writes the result to the destination register. The condition
// flags are not affected.
//
func (self *Program) SDIV(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SDIV", 3, asm.Operands { v0, v1, v2 })
    // SDIV  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 3, sa_wn, sa_wd))
    }
    // SDIV  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 3, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SDIV")
}

// SDOT instruction have 2 forms across 2 categories:
//
// 1. Dot Product signed arithmetic (vector, by element)
//
//    SDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.4B[<index>]
//
// Dot Product signed arithmetic (vector, by element). This instruction performs
// the dot product of the four 8-bit elements in each 32-bit element of the first
// source register with the four 8-bit elements of an indexed 32-bit element in the
// second source register, accumulating the result into the corresponding 32-bit
// element of the destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .DP indicates whether this instruction is supported.
//
// 2. Dot Product signed arithmetic (vector)
//
//    SDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Dot Product signed arithmetic (vector). This instruction performs the dot
// product of the four signed 8-bit elements in each 32-bit element of the first
// source register with the four signed 8-bit elements of the corresponding 32-bit
// element in the second source register, accumulating the result into the
// corresponding 32-bit element of the destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .DP indicates whether this instruction is supported.
//
func (self *Program) SDOT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SDOT", 3, asm.Operands { v0, v1, v2 })
    // SDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.4B[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVri(v2) &&
       vmoder(v2) == Mode4B {
        self.Arch.Require(FEAT_DotProd)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b0
            case Vec16B: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for SDOT")
        }
        return p.setins(asimdelem(
            sa_ta,
            0,
            2,
            mask(sa_index, 1),
            ubfx(sa_vm, 4, 1),
            mask(sa_vm, 4),
            14,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_DotProd)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b0
            case Vec16B: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for SDOT")
        }
        return p.setins(asimdsame2(sa_ta, 0, 2, sa_vm, 2, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SDOT")
}

// SETE instruction have one single form across one single category:
//
// 1. Memory Set
//
//    SETE  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set. These instructions perform a memory set using the value in the
// bottom byte of the source register. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: SETP, then SETM, and then SETE.
//
// SETP performs some preconditioning of the arguments suitable for using the SETM
// instruction, and performs an implementation defined amount of the memory set.
// SETM performs an implementation defined amount of the memory set. SETE performs
// the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETP, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETP, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETE(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETE", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_2 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 8, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETE")
}

// SETEN instruction have one single form across one single category:
//
// 1. Memory Set, non-temporal
//
//    SETEN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set, non-temporal. These instructions perform a memory set using the
// value in the bottom byte of the source register. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: SETPN, then SETMN, and then SETEN.
//
// SETPN performs some preconditioning of the arguments suitable for using the
// SETMN instruction, and performs an implementation defined amount of the memory
// set. SETMN performs an implementation defined amount of the memory set. SETEN
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETPN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETEN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETEN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_2 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 10, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETEN")
}

// SETET instruction have one single form across one single category:
//
// 1. Memory Set, unprivileged
//
//    SETET  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set, unprivileged. These instructions perform a memory set using the
// value in the bottom byte of the source register. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: SETPT, then SETMT, and then SETET.
//
// SETPT performs some preconditioning of the arguments suitable for using the
// SETMT instruction, and performs an implementation defined amount of the memory
// set. SETMT performs an implementation defined amount of the memory set. SETET
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETPT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETET(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETET", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_2 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 9, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETET")
}

// SETETN instruction have one single form across one single category:
//
// 1. Memory Set, unprivileged and non-temporal
//
//    SETETN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set, unprivileged and non-temporal. These instructions perform a memory
// set using the value in the bottom byte of the source register. The prologue,
// main, and epilogue instructions are expected to be run in succession and to
// appear consecutively in memory: SETPTN, then SETMTN, and then SETETN.
//
// SETPTN performs some preconditioning of the arguments suitable for using the
// SETMTN instruction, and performs an implementation defined amount of the memory
// set. SETMTN performs an implementation defined amount of the memory set. SETETN
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETETN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETETN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_2 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 11, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETETN")
}

// SETF16 instruction have one single form across one single category:
//
// 1. Evaluation of 8 or 16 bit flag values
//
//    SETF16  <Wn>
//
// Set the PSTATE.NZV flags based on the value in the specified general-purpose
// register. SETF8 treats the value as an 8 bit value, and SETF16 treats the value
// as an 16 bit value.
//
// The PSTATE.C flag is not affected by these instructions.
//
func (self *Program) SETF16(v0 interface{}) *Instruction {
    p := self.alloc("SETF16", 1, asm.Operands { v0 })
    if isWr(v0) {
        self.Arch.Require(FEAT_FlagM)
        p.Domain = asm.DomainGeneric
        sa_wn := uint32(v0.(asm.Register).ID())
        return p.setins(setf(0, 0, 1, 0, 1, sa_wn, 0, 13))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETF16")
}

// SETF8 instruction have one single form across one single category:
//
// 1. Evaluation of 8 or 16 bit flag values
//
//    SETF8  <Wn>
//
// Set the PSTATE.NZV flags based on the value in the specified general-purpose
// register. SETF8 treats the value as an 8 bit value, and SETF16 treats the value
// as an 16 bit value.
//
// The PSTATE.C flag is not affected by these instructions.
//
func (self *Program) SETF8(v0 interface{}) *Instruction {
    p := self.alloc("SETF8", 1, asm.Operands { v0 })
    if isWr(v0) {
        self.Arch.Require(FEAT_FlagM)
        p.Domain = asm.DomainGeneric
        sa_wn := uint32(v0.(asm.Register).ID())
        return p.setins(setf(0, 0, 1, 0, 0, sa_wn, 0, 13))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETF8")
}

// SETGE instruction have one single form across one single category:
//
// 1. Memory Set with tag setting
//
//    SETGE  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting. These instructions perform a memory set using the
// value in the bottom byte of the source register and store an Allocation Tag to
// memory for each Tag Granule written. The Allocation Tag is calculated from the
// Logical Address Tag in the register which holds the first address that the set
// is made to. The prologue, main, and epilogue instructions are expected to be run
// in succession and to appear consecutively in memory: SETGP, then SETGM, and then
// SETGE.
//
// SETGP performs some preconditioning of the arguments suitable for using the
// SETGM instruction, and performs an implementation defined amount of the memory
// set. SETGM performs an implementation defined amount of the memory set. SETGE
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGP, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGP, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGE(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGE", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_2 := uint32(v1.(asm.Register).ID())
        sa_xs_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs_1, 8, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGE")
}

// SETGEN instruction have one single form across one single category:
//
// 1. Memory Set with tag setting, non-temporal
//
//    SETGEN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting, non-temporal. These instructions perform a memory
// set using the value in the bottom byte of the source register and store an
// Allocation Tag to memory for each Tag Granule written. The Allocation Tag is
// calculated from the Logical Address Tag in the register which holds the first
// address that the set is made to. The prologue, main, and epilogue instructions
// are expected to be run in succession and to appear consecutively in memory:
// SETGPN, then SETGMN, and then SETGEN.
//
// SETGPN performs some preconditioning of the arguments suitable for using the
// SETGMN instruction, and performs an implementation defined amount of the memory
// set. SETGMN performs an implementation defined amount of the memory set. SETGEN
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGPN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGEN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGEN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_2 := uint32(v1.(asm.Register).ID())
        sa_xs_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs_1, 10, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGEN")
}

// SETGET instruction have one single form across one single category:
//
// 1. Memory Set with tag setting, unprivileged
//
//    SETGET  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting, unprivileged. These instructions perform a memory
// set using the value in the bottom byte of the source register and store an
// Allocation Tag to memory for each Tag Granule written. The Allocation Tag is
// calculated from the Logical Address Tag in the register which holds the first
// address that the set is made to. The prologue, main, and epilogue instructions
// are expected to be run in succession and to appear consecutively in memory:
// SETGPT, then SETGMT, and then SETGET.
//
// SETGPT performs some preconditioning of the arguments suitable for using the
// SETGMT instruction, and performs an implementation defined amount of the memory
// set. SETGMT performs an implementation defined amount of the memory set. SETGET
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGPT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGET(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGET", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_2 := uint32(v1.(asm.Register).ID())
        sa_xs_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs_1, 9, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGET")
}

// SETGETN instruction have one single form across one single category:
//
// 1. Memory Set with tag setting, unprivileged and non-temporal
//
//    SETGETN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting, unprivileged and non-temporal. These instructions
// perform a memory set using the value in the bottom byte of the source register
// and store an Allocation Tag to memory for each Tag Granule written. The
// Allocation Tag is calculated from the Logical Address Tag in the register which
// holds the first address that the set is made to. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: SETGPTN, then SETGMTN, and then SETGETN.
//
// SETGPTN performs some preconditioning of the arguments suitable for using the
// SETGMTN instruction, and performs an implementation defined amount of the memory
// set. SETGMTN performs an implementation defined amount of the memory set.
// SETGETN performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGETN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGETN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_2 := uint32(v1.(asm.Register).ID())
        sa_xs_1 := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs_1, 11, sa_xn_2, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGETN")
}

// SETGM instruction have one single form across one single category:
//
// 1. Memory Set with tag setting
//
//    SETGM  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting. These instructions perform a memory set using the
// value in the bottom byte of the source register and store an Allocation Tag to
// memory for each Tag Granule written. The Allocation Tag is calculated from the
// Logical Address Tag in the register which holds the first address that the set
// is made to. The prologue, main, and epilogue instructions are expected to be run
// in succession and to appear consecutively in memory: SETGP, then SETGM, and then
// SETGE.
//
// SETGP performs some preconditioning of the arguments suitable for using the
// SETGM instruction, and performs an implementation defined amount of the memory
// set. SETGM performs an implementation defined amount of the memory set. SETGE
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGP, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGP, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGM(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGM", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs, 4, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGM")
}

// SETGMN instruction have one single form across one single category:
//
// 1. Memory Set with tag setting, non-temporal
//
//    SETGMN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting, non-temporal. These instructions perform a memory
// set using the value in the bottom byte of the source register and store an
// Allocation Tag to memory for each Tag Granule written. The Allocation Tag is
// calculated from the Logical Address Tag in the register which holds the first
// address that the set is made to. The prologue, main, and epilogue instructions
// are expected to be run in succession and to appear consecutively in memory:
// SETGPN, then SETGMN, and then SETGEN.
//
// SETGPN performs some preconditioning of the arguments suitable for using the
// SETGMN instruction, and performs an implementation defined amount of the memory
// set. SETGMN performs an implementation defined amount of the memory set. SETGEN
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGPN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGMN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGMN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs, 6, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGMN")
}

// SETGMT instruction have one single form across one single category:
//
// 1. Memory Set with tag setting, unprivileged
//
//    SETGMT  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting, unprivileged. These instructions perform a memory
// set using the value in the bottom byte of the source register and store an
// Allocation Tag to memory for each Tag Granule written. The Allocation Tag is
// calculated from the Logical Address Tag in the register which holds the first
// address that the set is made to. The prologue, main, and epilogue instructions
// are expected to be run in succession and to appear consecutively in memory:
// SETGPT, then SETGMT, and then SETGET.
//
// SETGPT performs some preconditioning of the arguments suitable for using the
// SETGMT instruction, and performs an implementation defined amount of the memory
// set. SETGMT performs an implementation defined amount of the memory set. SETGET
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGPT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGMT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGMT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs, 5, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGMT")
}

// SETGMTN instruction have one single form across one single category:
//
// 1. Memory Set with tag setting, unprivileged and non-temporal
//
//    SETGMTN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting, unprivileged and non-temporal. These instructions
// perform a memory set using the value in the bottom byte of the source register
// and store an Allocation Tag to memory for each Tag Granule written. The
// Allocation Tag is calculated from the Logical Address Tag in the register which
// holds the first address that the set is made to. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: SETGPTN, then SETGMTN, and then SETGETN.
//
// SETGPTN performs some preconditioning of the arguments suitable for using the
// SETGMTN instruction, and performs an implementation defined amount of the memory
// set. SETGMTN performs an implementation defined amount of the memory set.
// SETGETN performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGMTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGMTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs, 7, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGMTN")
}

// SETGP instruction have one single form across one single category:
//
// 1. Memory Set with tag setting
//
//    SETGP  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting. These instructions perform a memory set using the
// value in the bottom byte of the source register and store an Allocation Tag to
// memory for each Tag Granule written. The Allocation Tag is calculated from the
// Logical Address Tag in the register which holds the first address that the set
// is made to. The prologue, main, and epilogue instructions are expected to be run
// in succession and to appear consecutively in memory: SETGP, then SETGM, and then
// SETGE.
//
// SETGP performs some preconditioning of the arguments suitable for using the
// SETGM instruction, and performs an implementation defined amount of the memory
// set. SETGM performs an implementation defined amount of the memory set. SETGE
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGP, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGP, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGP", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs, 0, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGP")
}

// SETGPN instruction have one single form across one single category:
//
// 1. Memory Set with tag setting, non-temporal
//
//    SETGPN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting, non-temporal. These instructions perform a memory
// set using the value in the bottom byte of the source register and store an
// Allocation Tag to memory for each Tag Granule written. The Allocation Tag is
// calculated from the Logical Address Tag in the register which holds the first
// address that the set is made to. The prologue, main, and epilogue instructions
// are expected to be run in succession and to appear consecutively in memory:
// SETGPN, then SETGMN, and then SETGEN.
//
// SETGPN performs some preconditioning of the arguments suitable for using the
// SETGMN instruction, and performs an implementation defined amount of the memory
// set. SETGMN performs an implementation defined amount of the memory set. SETGEN
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGPN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGPN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGPN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs, 2, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGPN")
}

// SETGPT instruction have one single form across one single category:
//
// 1. Memory Set with tag setting, unprivileged
//
//    SETGPT  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting, unprivileged. These instructions perform a memory
// set using the value in the bottom byte of the source register and store an
// Allocation Tag to memory for each Tag Granule written. The Allocation Tag is
// calculated from the Logical Address Tag in the register which holds the first
// address that the set is made to. The prologue, main, and epilogue instructions
// are expected to be run in succession and to appear consecutively in memory:
// SETGPT, then SETGMT, and then SETGET.
//
// SETGPT performs some preconditioning of the arguments suitable for using the
// SETGMT instruction, and performs an implementation defined amount of the memory
// set. SETGMT performs an implementation defined amount of the memory set. SETGET
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGPT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGPT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGPT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs, 1, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGPT")
}

// SETGPTN instruction have one single form across one single category:
//
// 1. Memory Set with tag setting, unprivileged and non-temporal
//
//    SETGPTN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set with tag setting, unprivileged and non-temporal. These instructions
// perform a memory set using the value in the bottom byte of the source register
// and store an Allocation Tag to memory for each Tag Granule written. The
// Allocation Tag is calculated from the Logical Address Tag in the register which
// holds the first address that the set is made to. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: SETGPTN, then SETGMTN, and then SETGETN.
//
// SETGPTN performs some preconditioning of the arguments suitable for using the
// SETGMTN instruction, and performs an implementation defined amount of the memory
// set. SETGMTN performs an implementation defined amount of the memory set.
// SETGETN performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETGPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETGPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFF0 .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETGMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* number of bytes remaining to be set in the memory set in total.
//
// For SETGMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETGETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETGETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETGPTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETGPTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 1, 3, sa_xs, 3, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETGPTN")
}

// SETM instruction have one single form across one single category:
//
// 1. Memory Set
//
//    SETM  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set. These instructions perform a memory set using the value in the
// bottom byte of the source register. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: SETP, then SETM, and then SETE.
//
// SETP performs some preconditioning of the arguments suitable for using the SETM
// instruction, and performs an implementation defined amount of the memory set.
// SETM performs an implementation defined amount of the memory set. SETE performs
// the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETP, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETP, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETM(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETM", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 4, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETM")
}

// SETMN instruction have one single form across one single category:
//
// 1. Memory Set, non-temporal
//
//    SETMN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set, non-temporal. These instructions perform a memory set using the
// value in the bottom byte of the source register. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: SETPN, then SETMN, and then SETEN.
//
// SETPN performs some preconditioning of the arguments suitable for using the
// SETMN instruction, and performs an implementation defined amount of the memory
// set. SETMN performs an implementation defined amount of the memory set. SETEN
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETPN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETMN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETMN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 6, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETMN")
}

// SETMT instruction have one single form across one single category:
//
// 1. Memory Set, unprivileged
//
//    SETMT  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set, unprivileged. These instructions perform a memory set using the
// value in the bottom byte of the source register. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: SETPT, then SETMT, and then SETET.
//
// SETPT performs some preconditioning of the arguments suitable for using the
// SETMT instruction, and performs an implementation defined amount of the memory
// set. SETMT performs an implementation defined amount of the memory set. SETET
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETPT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETMT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETMT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 5, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETMT")
}

// SETMTN instruction have one single form across one single category:
//
// 1. Memory Set, unprivileged and non-temporal
//
//    SETMTN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set, unprivileged and non-temporal. These instructions perform a memory
// set using the value in the bottom byte of the source register. The prologue,
// main, and epilogue instructions are expected to be run in succession and to
// appear consecutively in memory: SETPTN, then SETMTN, and then SETETN.
//
// SETPTN performs some preconditioning of the arguments suitable for using the
// SETMTN instruction, and performs an implementation defined amount of the memory
// set. SETMTN performs an implementation defined amount of the memory set. SETETN
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETMTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETMTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd_1 := uint32(mbase(v0).ID())
        sa_xn_1 := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 7, sa_xn_1, sa_xd_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETMTN")
}

// SETP instruction have one single form across one single category:
//
// 1. Memory Set
//
//    SETP  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set. These instructions perform a memory set using the value in the
// bottom byte of the source register. The prologue, main, and epilogue
// instructions are expected to be run in succession and to appear consecutively in
// memory: SETP, then SETM, and then SETE.
//
// SETP performs some preconditioning of the arguments suitable for using the SETM
// instruction, and performs an implementation defined amount of the memory set.
// SETM performs an implementation defined amount of the memory set. SETE performs
// the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETP, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETP, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETM, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETM, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETE, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETE, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETP", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 0, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETP")
}

// SETPN instruction have one single form across one single category:
//
// 1. Memory Set, non-temporal
//
//    SETPN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set, non-temporal. These instructions perform a memory set using the
// value in the bottom byte of the source register. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: SETPN, then SETMN, and then SETEN.
//
// SETPN performs some preconditioning of the arguments suitable for using the
// SETMN instruction, and performs an implementation defined amount of the memory
// set. SETMN performs an implementation defined amount of the memory set. SETEN
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETPN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETPN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETMN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETMN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETEN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETEN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETPN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETPN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 2, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETPN")
}

// SETPT instruction have one single form across one single category:
//
// 1. Memory Set, unprivileged
//
//    SETPT  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set, unprivileged. These instructions perform a memory set using the
// value in the bottom byte of the source register. The prologue, main, and
// epilogue instructions are expected to be run in succession and to appear
// consecutively in memory: SETPT, then SETMT, and then SETET.
//
// SETPT performs some preconditioning of the arguments suitable for using the
// SETMT instruction, and performs an implementation defined amount of the memory
// set. SETMT performs an implementation defined amount of the memory set. SETET
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETPT, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETPT, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETMT, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETMT, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETET, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETET, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETPT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETPT", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 1, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETPT")
}

// SETPTN instruction have one single form across one single category:
//
// 1. Memory Set, unprivileged and non-temporal
//
//    SETPTN  [<Xd>]!, <Xn>!, <Xs>
//
// Memory Set, unprivileged and non-temporal. These instructions perform a memory
// set using the value in the bottom byte of the source register. The prologue,
// main, and epilogue instructions are expected to be run in succession and to
// appear consecutively in memory: SETPTN, then SETMTN, and then SETETN.
//
// SETPTN performs some preconditioning of the arguments suitable for using the
// SETMTN instruction, and performs an implementation defined amount of the memory
// set. SETMTN performs an implementation defined amount of the memory set. SETETN
// performs the last part of the memory set.
//
// NOTE: 
//     The inclusion of implementation defined amounts of memory set allows
//     some optimization of the size that can be performed.
//
// The architecture supports two algorithms for the memory set: option A and option
// B. Which algorithm is used is implementation defined .
//
// NOTE: 
//     Portable software should not assume that the choice of algorithm is
//     constant.
//
// After execution of SETPTN, option A (which results in encoding PSTATE.C = 0):
//
//     * If Xn<63> == 1, the set size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + saturated Xn.
//     * Xn holds -1* saturated Xn + an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// After execution of SETPTN, option B (which results in encoding PSTATE.C = 1):
//
//     * If Xn<63> == 1, the copy size is saturated to 0x7FFFFFFFFFFFFFFF .
//     * Xd holds the original Xd + an implementation defined number of bytes
//       set.
//     * Xn holds the saturated Xn - an implementation defined number of bytes
//       set.
//     * PSTATE.{N,Z,V} are set to {0,0,0}.
//
// For SETMTN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with
//       -1* the number of bytes remaining to be set in the memory set in
//       total.
//
// For SETMTN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with the number of bytes
//           remaining to be set in the memory set in total.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For SETETN, option A (encoded by PSTATE.C = 0), the format of the arguments is:
//
//     * Xn is treated as a signed 64-bit number.
//     * Xn holds -1* the number of bytes remaining to be set in the memory set
//       in total.
//     * Xd holds the lowest address that the set is made to -Xn.
//     * At the end of the instruction, the value of Xn is written back with 0.
//
// For SETETN, option B (encoded by PSTATE.C = 1), the format of the arguments is:
//
//     * Xn holds the number of bytes remaining to be set in the memory set in
//       total.
//     * Xd holds the lowest address that the set is made to.
//     * At the end of the instruction:
//
//         * the value of Xn is written back with 0.
//         * the value of Xd is written back with the lowest address that
//           has not been set.
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly Memory Copy and Memory Set SET* .
//
func (self *Program) SETPTN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SETPTN", 3, asm.Operands { v0, v1, v2 })
    if isMem(v0) &&
       isXr(mbase(v0)) &&
       midx(v0) == nil &&
       moffs(v0) == 0 &&
       mext(v0) == PreIndex &&
       isXr(v1) &&
       isXr(v2) {
        self.Arch.Require(FEAT_MOPS)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(mbase(v0).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xs := uint32(v2.(asm.Register).ID())
        return p.setins(memcms(0, 0, 3, sa_xs, 3, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SETPTN")
}

// SEV instruction have one single form across one single category:
//
// 1. Send Event
//
//    SEV
//
// Send Event is a hint instruction. It causes an event to be signaled to all PEs
// in the multiprocessor system. For more information, see Wait for Event mechanism
// and Send event .
//
func (self *Program) SEV() *Instruction {
    p := self.alloc("SEV", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(hints(0, 4))
}

// SEVL instruction have one single form across one single category:
//
// 1. Send Event Local
//
//    SEVL
//
// Send Event Local is a hint instruction that causes an event to be signaled
// locally without requiring the event to be signaled to other PEs in the
// multiprocessor system. It can prime a wait-loop which starts with a WFE
// instruction.
//
func (self *Program) SEVL() *Instruction {
    p := self.alloc("SEVL", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(hints(0, 5))
}

// SHA1C instruction have one single form across one single category:
//
// 1. SHA1 hash update (choose)
//
//    SHA1C  <Qd>, <Sn>, <Vm>.4S
//
// SHA1 hash update (choose).
//
func (self *Program) SHA1C(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA1C", 3, asm.Operands { v0, v1, v2 })
    if isQr(v0) && isSr(v1) && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SHA1)
        p.Domain = DomainAdvSimd
        sa_qd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha3(0, sa_vm, 0, sa_sn, sa_qd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA1C")
}

// SHA1H instruction have one single form across one single category:
//
// 1. SHA1 fixed rotate
//
//    SHA1H  <Sd>, <Sn>
//
// SHA1 fixed rotate.
//
func (self *Program) SHA1H(v0, v1 interface{}) *Instruction {
    p := self.alloc("SHA1H", 2, asm.Operands { v0, v1 })
    if isSr(v0) && isSr(v1) {
        self.Arch.Require(FEAT_SHA1)
        p.Domain = DomainAdvSimd
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        return p.setins(cryptosha2(0, 0, sa_sn, sa_sd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA1H")
}

// SHA1M instruction have one single form across one single category:
//
// 1. SHA1 hash update (majority)
//
//    SHA1M  <Qd>, <Sn>, <Vm>.4S
//
// SHA1 hash update (majority).
//
func (self *Program) SHA1M(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA1M", 3, asm.Operands { v0, v1, v2 })
    if isQr(v0) && isSr(v1) && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SHA1)
        p.Domain = DomainAdvSimd
        sa_qd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha3(0, sa_vm, 2, sa_sn, sa_qd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA1M")
}

// SHA1P instruction have one single form across one single category:
//
// 1. SHA1 hash update (parity)
//
//    SHA1P  <Qd>, <Sn>, <Vm>.4S
//
// SHA1 hash update (parity).
//
func (self *Program) SHA1P(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA1P", 3, asm.Operands { v0, v1, v2 })
    if isQr(v0) && isSr(v1) && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SHA1)
        p.Domain = DomainAdvSimd
        sa_qd := uint32(v0.(asm.Register).ID())
        sa_sn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha3(0, sa_vm, 1, sa_sn, sa_qd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA1P")
}

// SHA1SU0 instruction have one single form across one single category:
//
// 1. SHA1 schedule update 0
//
//    SHA1SU0  <Vd>.4S, <Vn>.4S, <Vm>.4S
//
// SHA1 schedule update 0.
//
func (self *Program) SHA1SU0(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA1SU0", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SHA1)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha3(0, sa_vm, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA1SU0")
}

// SHA1SU1 instruction have one single form across one single category:
//
// 1. SHA1 schedule update 1
//
//    SHA1SU1  <Vd>.4S, <Vn>.4S
//
// SHA1 schedule update 1.
//
func (self *Program) SHA1SU1(v0, v1 interface{}) *Instruction {
    p := self.alloc("SHA1SU1", 2, asm.Operands { v0, v1 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S {
        self.Arch.Require(FEAT_SHA1)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(cryptosha2(0, 1, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA1SU1")
}

// SHA256H instruction have one single form across one single category:
//
// 1. SHA256 hash update (part 1)
//
//    SHA256H  <Qd>, <Qn>, <Vm>.4S
//
// SHA256 hash update (part 1).
//
func (self *Program) SHA256H(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA256H", 3, asm.Operands { v0, v1, v2 })
    if isQr(v0) && isQr(v1) && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SHA256)
        p.Domain = DomainAdvSimd
        sa_qd := uint32(v0.(asm.Register).ID())
        sa_qn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha3(0, sa_vm, 4, sa_qn, sa_qd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA256H")
}

// SHA256H2 instruction have one single form across one single category:
//
// 1. SHA256 hash update (part 2)
//
//    SHA256H2  <Qd>, <Qn>, <Vm>.4S
//
// SHA256 hash update (part 2).
//
func (self *Program) SHA256H2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA256H2", 3, asm.Operands { v0, v1, v2 })
    if isQr(v0) && isQr(v1) && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SHA256)
        p.Domain = DomainAdvSimd
        sa_qd := uint32(v0.(asm.Register).ID())
        sa_qn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha3(0, sa_vm, 5, sa_qn, sa_qd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA256H2")
}

// SHA256SU0 instruction have one single form across one single category:
//
// 1. SHA256 schedule update 0
//
//    SHA256SU0  <Vd>.4S, <Vn>.4S
//
// SHA256 schedule update 0.
//
func (self *Program) SHA256SU0(v0, v1 interface{}) *Instruction {
    p := self.alloc("SHA256SU0", 2, asm.Operands { v0, v1 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S {
        self.Arch.Require(FEAT_SHA256)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(cryptosha2(0, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA256SU0")
}

// SHA256SU1 instruction have one single form across one single category:
//
// 1. SHA256 schedule update 1
//
//    SHA256SU1  <Vd>.4S, <Vn>.4S, <Vm>.4S
//
// SHA256 schedule update 1.
//
func (self *Program) SHA256SU1(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA256SU1", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SHA256)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha3(0, sa_vm, 6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA256SU1")
}

// SHA512H instruction have one single form across one single category:
//
// 1. SHA512 Hash update part 1
//
//    SHA512H  <Qd>, <Qn>, <Vm>.2D
//
// SHA512 Hash update part 1 takes the values from the three 128-bit source SIMD&FP
// registers and produces a 128-bit output value that combines the sigma1 and chi
// functions of two iterations of the SHA512 computation. It returns this value to
// the destination SIMD&FP register.
//
// This instruction is implemented only when FEAT_SHA512 is implemented.
//
func (self *Program) SHA512H(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA512H", 3, asm.Operands { v0, v1, v2 })
    if isQr(v0) && isQr(v1) && isVr(v2) && vfmt(v2) == Vec2D {
        self.Arch.Require(FEAT_SHA512)
        p.Domain = DomainAdvSimd
        sa_qd := uint32(v0.(asm.Register).ID())
        sa_qn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha512_3(sa_vm, 0, 0, sa_qn, sa_qd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA512H")
}

// SHA512H2 instruction have one single form across one single category:
//
// 1. SHA512 Hash update part 2
//
//    SHA512H2  <Qd>, <Qn>, <Vm>.2D
//
// SHA512 Hash update part 2 takes the values from the three 128-bit source SIMD&FP
// registers and produces a 128-bit output value that combines the sigma0 and
// majority functions of two iterations of the SHA512 computation. It returns this
// value to the destination SIMD&FP register.
//
// This instruction is implemented only when FEAT_SHA512 is implemented.
//
func (self *Program) SHA512H2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA512H2", 3, asm.Operands { v0, v1, v2 })
    if isQr(v0) && isQr(v1) && isVr(v2) && vfmt(v2) == Vec2D {
        self.Arch.Require(FEAT_SHA512)
        p.Domain = DomainAdvSimd
        sa_qd := uint32(v0.(asm.Register).ID())
        sa_qn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha512_3(sa_vm, 0, 1, sa_qn, sa_qd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA512H2")
}

// SHA512SU0 instruction have one single form across one single category:
//
// 1. SHA512 Schedule Update 0
//
//    SHA512SU0  <Vd>.2D, <Vn>.2D
//
// SHA512 Schedule Update 0 takes the values from the two 128-bit source SIMD&FP
// registers and produces a 128-bit output value that combines the gamma0 functions
// of two iterations of the SHA512 schedule update that are performed after the
// first 16 iterations within a block. It returns this value to the destination
// SIMD&FP register.
//
// This instruction is implemented only when FEAT_SHA512 is implemented.
//
func (self *Program) SHA512SU0(v0, v1 interface{}) *Instruction {
    p := self.alloc("SHA512SU0", 2, asm.Operands { v0, v1 })
    if isVr(v0) && vfmt(v0) == Vec2D && isVr(v1) && vfmt(v1) == Vec2D {
        self.Arch.Require(FEAT_SHA512)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(cryptosha512_2(0, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA512SU0")
}

// SHA512SU1 instruction have one single form across one single category:
//
// 1. SHA512 Schedule Update 1
//
//    SHA512SU1  <Vd>.2D, <Vn>.2D, <Vm>.2D
//
// SHA512 Schedule Update 1 takes the values from the three source SIMD&FP
// registers and produces a 128-bit output value that combines the gamma1 functions
// of two iterations of the SHA512 schedule update that are performed after the
// first 16 iterations within a block. It returns this value to the destination
// SIMD&FP register.
//
// This instruction is implemented only when FEAT_SHA512 is implemented.
//
func (self *Program) SHA512SU1(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHA512SU1", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec2D && isVr(v1) && vfmt(v1) == Vec2D && isVr(v2) && vfmt(v2) == Vec2D {
        self.Arch.Require(FEAT_SHA512)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha512_3(sa_vm, 0, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHA512SU1")
}

// SHADD instruction have one single form across one single category:
//
// 1. Signed Halving Add
//
//    SHADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Signed Halving Add. This instruction adds corresponding signed integer values
// from the two source SIMD&FP registers, shifts each result right one bit, places
// the results into a vector, and writes the vector to the destination SIMD&FP
// register.
//
// The results are truncated. For rounded results, see SRHADD .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SHADD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHADD", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 0, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHADD")
}

// SHL instruction have 2 forms across one single category:
//
// 1. Shift Left (immediate)
//
//    SHL  <Vd>.<T>, <Vn>.<T>, #<shift>
//    SHL  <V><d>, <V><n>, #<shift>
//
// Shift Left (immediate). This instruction reads each value from a vector, left
// shifts each result by an immediate value, writes the final result to a vector,
// and writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SHL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHL", 3, asm.Operands { v0, v1, v2 })
    // SHL  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift = uint32(asLit(v2)) + 32
            case 0b1000: sa_shift = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift' for SHL")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SHL")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 10, sa_vn, sa_vd))
    }
    // SHL  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 0, 63) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SHL")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift_1' for SHL")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SHL")
        }
        return p.setins(asisdshf(0, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 10, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SHL")
}

// SHLL instruction have one single form across one single category:
//
// 1. Shift Left Long (by element size)
//
//    SHLL  <Vd>.<Ta>, <Vn>.<Tb>, #<shift>
//
// Shift Left Long (by element size). This instruction reads each vector element in
// the lower or upper half of the source SIMD&FP register, left shifts each result
// by the element size, writes the final result to a vector, and writes the vector
// to the destination SIMD&FP register. The destination vector elements are twice
// as long as the source vector elements.
//
// The SHLL instruction extracts vector elements from the lower half of the source
// register. The SHLL2 instruction extracts vector elements from the upper half of
// the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SHLL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHLL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isIntLit(v2, 8, 16, 32) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        switch asLit(v2) {
            case 8: sa_shift = 0b00
            case 16: sa_shift = 0b01
            case 32: sa_shift = 0b10
            default: panic("aarch64: invalid operand 'sa_shift' for SHLL")
        }
        if sa_shift != sa_ta || sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SHLL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SHLL")
        }
        return p.setins(asimdmisc(0, 1, sa_shift, 19, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHLL")
}

// SHLL2 instruction have one single form across one single category:
//
// 1. Shift Left Long (by element size)
//
//    SHLL2  <Vd>.<Ta>, <Vn>.<Tb>, #<shift>
//
// Shift Left Long (by element size). This instruction reads each vector element in
// the lower or upper half of the source SIMD&FP register, left shifts each result
// by the element size, writes the final result to a vector, and writes the vector
// to the destination SIMD&FP register. The destination vector elements are twice
// as long as the source vector elements.
//
// The SHLL instruction extracts vector elements from the lower half of the source
// register. The SHLL2 instruction extracts vector elements from the upper half of
// the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SHLL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHLL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isIntLit(v2, 8, 16, 32) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        switch asLit(v2) {
            case 8: sa_shift = 0b00
            case 16: sa_shift = 0b01
            case 32: sa_shift = 0b10
            default: panic("aarch64: invalid operand 'sa_shift' for SHLL2")
        }
        if sa_shift != sa_ta || sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SHLL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SHLL2")
        }
        return p.setins(asimdmisc(1, 1, sa_shift, 19, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHLL2")
}

// SHRN instruction have one single form across one single category:
//
// 1. Shift Right Narrow (immediate)
//
//    SHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Shift Right Narrow (immediate). This instruction reads each unsigned integer
// value from the source SIMD&FP register, right shifts each result by an immediate
// value, puts the final result into a vector, and writes the vector to the lower
// or upper half of the destination SIMD&FP register. The destination vector
// elements are half as long as the source vector elements. The results are
// truncated. For rounded results, see RSHRN .
//
// The RSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the RSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SHRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHRN", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SHRN")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SHRN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SHRN")
        }
        return p.setins(asimdshf(0, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 16, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHRN")
}

// SHRN2 instruction have one single form across one single category:
//
// 1. Shift Right Narrow (immediate)
//
//    SHRN2  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Shift Right Narrow (immediate). This instruction reads each unsigned integer
// value from the source SIMD&FP register, right shifts each result by an immediate
// value, puts the final result into a vector, and writes the vector to the lower
// or upper half of the destination SIMD&FP register. The destination vector
// elements are half as long as the source vector elements. The results are
// truncated. For rounded results, see RSHRN .
//
// The RSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the RSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SHRN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHRN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SHRN2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SHRN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SHRN2")
        }
        return p.setins(asimdshf(1, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 16, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHRN2")
}

// SHSUB instruction have one single form across one single category:
//
// 1. Signed Halving Subtract
//
//    SHSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Signed Halving Subtract. This instruction subtracts the elements in the vector
// in the second source SIMD&FP register from the corresponding elements in the
// vector in the first source SIMD&FP register, shifts each result right one bit,
// places each result into elements of a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SHSUB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SHSUB", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 4, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SHSUB")
}

// SLI instruction have 2 forms across one single category:
//
// 1. Shift Left and Insert (immediate)
//
//    SLI  <Vd>.<T>, <Vn>.<T>, #<shift>
//    SLI  <V><d>, <V><n>, #<shift>
//
// Shift Left and Insert (immediate). This instruction reads each vector element in
// the source SIMD&FP register, left shifts each vector element by an immediate
// value, and inserts the result into the corresponding vector element in the
// destination SIMD&FP register such that the new zero bits created by the shift
// are not inserted but retain their existing value. Bits shifted out of the left
// of each vector element in the source register are lost.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.sli_operation_shift_by_3.svg]
// shift left by 3 for an 8-bit vector element
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SLI(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SLI", 3, asm.Operands { v0, v1, v2 })
    // SLI  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift = uint32(asLit(v2)) + 32
            case 0b1000: sa_shift = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift' for SLI")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SLI")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 10, sa_vn, sa_vd))
    }
    // SLI  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 0, 63) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SLI")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SLI")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift_1' for SLI")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SLI")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 10, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SLI")
}

// SM3PARTW1 instruction have one single form across one single category:
//
// 1. SM3PARTW1
//
//    SM3PARTW1  <Vd>.4S, <Vn>.4S, <Vm>.4S
//
// SM3PARTW1 takes three 128-bit vectors from the three source SIMD&FP registers
// and returns a 128-bit result in the destination SIMD&FP register. The result is
// obtained by a three-way exclusive-OR of the elements within the input vectors
// with some fixed rotations, see the Operation pseudocode for more information.
//
// This instruction is implemented only when FEAT_SM3 is implemented.
//
func (self *Program) SM3PARTW1(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SM3PARTW1", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SM3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha512_3(sa_vm, 1, 0, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SM3PARTW1")
}

// SM3PARTW2 instruction have one single form across one single category:
//
// 1. SM3PARTW2
//
//    SM3PARTW2  <Vd>.4S, <Vn>.4S, <Vm>.4S
//
// SM3PARTW2 takes three 128-bit vectors from three source SIMD&FP registers and
// returns a 128-bit result in the destination SIMD&FP register. The result is
// obtained by a three-way exclusive-OR of the elements within the input vectors
// with some fixed rotations, see the Operation pseudocode for more information.
//
// This instruction is implemented only when FEAT_SM3 is implemented.
//
func (self *Program) SM3PARTW2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SM3PARTW2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SM3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha512_3(sa_vm, 1, 1, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SM3PARTW2")
}

// SM3SS1 instruction have one single form across one single category:
//
// 1. SM3SS1
//
//    SM3SS1  <Vd>.4S, <Vn>.4S, <Vm>.4S, <Va>.4S
//
// SM3SS1 rotates the top 32 bits of the 128-bit vector in the first source SIMD&FP
// register by 12, and adds that 32-bit value to the two other 32-bit values held
// in the top 32 bits of each of the 128-bit vectors in the second and third source
// SIMD&FP registers, rotating this result left by 7 and writing the final result
// into the top 32 bits of the vector in the destination SIMD&FP register, with the
// bottom 96 bits of the vector being written to 0.
//
// This instruction is implemented only when FEAT_SM3 is implemented.
//
func (self *Program) SM3SS1(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("SM3SS1", 4, asm.Operands { v0, v1, v2, v3 })
    if isVr(v0) &&
       vfmt(v0) == Vec4S &&
       isVr(v1) &&
       vfmt(v1) == Vec4S &&
       isVr(v2) &&
       vfmt(v2) == Vec4S &&
       isVr(v3) &&
       vfmt(v3) == Vec4S {
        self.Arch.Require(FEAT_SM3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        sa_va := uint32(v3.(asm.Register).ID())
        return p.setins(crypto4(2, sa_vm, sa_va, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SM3SS1")
}

// SM3TT1A instruction have one single form across one single category:
//
// 1. SM3TT1A
//
//    SM3TT1A  <Vd>.4S, <Vn>.4S, <Vm>.S[<imm2>]
//
// SM3TT1A takes three 128-bit vectors from three source SIMD&FP registers and a
// 2-bit immediate index value, and returns a 128-bit result in the destination
// SIMD&FP register. It performs a three-way exclusive-OR of the three 32-bit
// fields held in the upper three elements of the first source vector, and adds the
// resulting 32-bit value and the following three other 32-bit values:
//
//     * The bottom 32-bit element of the first source vector, Vd, that was
//       used for the three-way exclusive-OR.
//     * The result of the exclusive-OR of the top 32-bit element of the second
//       source vector, Vn, with a rotation left by 12 of the top 32-bit
//       element of the first source vector.
//     * A 32-bit element indexed out of the third source vector, Vm.
//
// The result of this addition is returned as the top element of the result. The
// other elements of the result are taken from elements of the first source vector,
// with the element returned in bits<63:32> being rotated left by 9.
//
// This instruction is implemented only when FEAT_SM3 is implemented.
//
func (self *Program) SM3TT1A(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SM3TT1A", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S && isVri(v2) && vmoder(v2) == ModeS {
        self.Arch.Require(FEAT_SM3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_imm2 := uint32(vidxr(v2))
        return p.setins(crypto3_imm2(sa_vm, sa_imm2, 0, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SM3TT1A")
}

// SM3TT1B instruction have one single form across one single category:
//
// 1. SM3TT1B
//
//    SM3TT1B  <Vd>.4S, <Vn>.4S, <Vm>.S[<imm2>]
//
// SM3TT1B takes three 128-bit vectors from three source SIMD&FP registers and a
// 2-bit immediate index value, and returns a 128-bit result in the destination
// SIMD&FP register. It performs a 32-bit majority function between the three
// 32-bit fields held in the upper three elements of the first source vector, and
// adds the resulting 32-bit value and the following three other 32-bit values:
//
//     * The bottom 32-bit element of the first source vector, Vd, that was
//       used for the 32-bit majority function.
//     * The result of the exclusive-OR of the top 32-bit element of the second
//       source vector, Vn, with a rotation left by 12 of the top 32-bit
//       element of the first source vector.
//     * A 32-bit element indexed out of the third source vector, Vm.
//
// The result of this addition is returned as the top element of the result. The
// other elements of the result are taken from elements of the first source vector,
// with the element returned in bits<63:32> being rotated left by 9.
//
// This instruction is implemented only when FEAT_SM3 is implemented.
//
func (self *Program) SM3TT1B(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SM3TT1B", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S && isVri(v2) && vmoder(v2) == ModeS {
        self.Arch.Require(FEAT_SM3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_imm2 := uint32(vidxr(v2))
        return p.setins(crypto3_imm2(sa_vm, sa_imm2, 1, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SM3TT1B")
}

// SM3TT2A instruction have one single form across one single category:
//
// 1. SM3TT2A
//
//    SM3TT2A  <Vd>.4S, <Vn>.4S, <Vm>.S[<imm2>]
//
// SM3TT2A takes three 128-bit vectors from three source SIMD&FP register and a
// 2-bit immediate index value, and returns a 128-bit result in the destination
// SIMD&FP register. It performs a three-way exclusive-OR of the three 32-bit
// fields held in the upper three elements of the first source vector, and adds the
// resulting 32-bit value and the following three other 32-bit values:
//
//     * The bottom 32-bit element of the first source vector, Vd, that was
//       used for the three-way exclusive-OR.
//     * The 32-bit element held in the top 32 bits of the second source
//       vector, Vn.
//     * A 32-bit element indexed out of the third source vector, Vm.
//
// A three-way exclusive-OR is performed of the result of this addition, the result
// of the addition rotated left by 9, and the result of the addition rotated left
// by 17. The result of this exclusive-OR is returned as the top element of the
// returned result. The other elements of this result are taken from elements of
// the first source vector, with the element returned in bits<63:32> being rotated
// left by 19.
//
// This instruction is implemented only when FEAT_SM3 is implemented.
//
func (self *Program) SM3TT2A(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SM3TT2A", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S && isVri(v2) && vmoder(v2) == ModeS {
        self.Arch.Require(FEAT_SM3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_imm2 := uint32(vidxr(v2))
        return p.setins(crypto3_imm2(sa_vm, sa_imm2, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SM3TT2A")
}

// SM3TT2B instruction have one single form across one single category:
//
// 1. SM3TT2B
//
//    SM3TT2B  <Vd>.4S, <Vn>.4S, <Vm>.S[<imm2>]
//
// SM3TT2B takes three 128-bit vectors from three source SIMD&FP registers, and a
// 2-bit immediate index value, and returns a 128-bit result in the destination
// SIMD&FP register. It performs a 32-bit majority function between the three
// 32-bit fields held in the upper three elements of the first source vector, and
// adds the resulting 32-bit value and the following three other 32-bit values:
//
//     * The bottom 32-bit element of the first source vector, Vd, that was
//       used for the 32-bit majority function.
//     * The 32-bit element held in the top 32 bits of the second source
//       vector, Vn.
//     * A 32-bit element indexed out of the third source vector, Vm.
//
// A three-way exclusive-OR is performed of the result of this addition, the result
// of the addition rotated left by 9, and the result of the addition rotated left
// by 17. The result of this exclusive-OR is returned as the top element of the
// returned result. The other elements of this result are taken from elements of
// the first source vector, with the element returned in bits<63:32> being rotated
// left by 19.
//
// This instruction is implemented only when FEAT_SM3 is implemented.
//
func (self *Program) SM3TT2B(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SM3TT2B", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S && isVri(v2) && vmoder(v2) == ModeS {
        self.Arch.Require(FEAT_SM3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_imm2 := uint32(vidxr(v2))
        return p.setins(crypto3_imm2(sa_vm, sa_imm2, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SM3TT2B")
}

// SM4E instruction have one single form across one single category:
//
// 1. SM4 Encode
//
//    SM4E  <Vd>.4S, <Vn>.4S
//
// SM4 Encode takes input data as a 128-bit vector from the first source SIMD&FP
// register, and four iterations of the round key held as the elements of the
// 128-bit vector in the second source SIMD&FP register. It encrypts the data by
// four rounds, in accordance with the SM4 standard, returning the 128-bit result
// to the destination SIMD&FP register.
//
// This instruction is implemented only when FEAT_SM4 is implemented.
//
func (self *Program) SM4E(v0, v1 interface{}) *Instruction {
    p := self.alloc("SM4E", 2, asm.Operands { v0, v1 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S {
        self.Arch.Require(FEAT_SM4)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(cryptosha512_2(1, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SM4E")
}

// SM4EKEY instruction have one single form across one single category:
//
// 1. SM4 Key
//
//    SM4EKEY  <Vd>.4S, <Vn>.4S, <Vm>.4S
//
// SM4 Key takes an input as a 128-bit vector from the first source SIMD&FP
// register and a 128-bit constant from the second SIMD&FP register. It derives
// four iterations of the output key, in accordance with the SM4 standard,
// returning the 128-bit result to the destination SIMD&FP register.
//
// This instruction is implemented only when FEAT_SM4 is implemented.
//
func (self *Program) SM4EKEY(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SM4EKEY", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec4S && isVr(v2) && vfmt(v2) == Vec4S {
        self.Arch.Require(FEAT_SM4)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(cryptosha512_3(sa_vm, 1, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SM4EKEY")
}

// SMADDL instruction have one single form across one single category:
//
// 1. Signed Multiply-Add Long
//
//    SMADDL  <Xd>, <Wn>, <Wm>, <Xa>
//
// Signed Multiply-Add Long multiplies two 32-bit register values, adds a 64-bit
// register value, and writes the result to the 64-bit destination register.
//
func (self *Program) SMADDL(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("SMADDL", 4, asm.Operands { v0, v1, v2, v3 })
    if isXr(v0) && isWr(v1) && isWr(v2) && isXr(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_xa := uint32(v3.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 1, sa_wm, 0, sa_xa, sa_wn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMADDL")
}

// SMAX instruction have 5 forms across 3 categories:
//
// 1. Signed Maximum (vector)
//
//    SMAX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Signed Maximum (vector). This instruction compares corresponding elements in the
// vectors in the two source SIMD&FP registers, places the larger of each pair of
// signed integer values into a vector, and writes the vector to the destination
// SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed Maximum (immediate)
//
//    SMAX  <Wd>, <Wn>, #<simm>
//    SMAX  <Xd>, <Xn>, #<simm>
//
// Signed Maximum (immediate) determines the signed maximum of the source register
// value and immediate, and writes the result to the destination register.
//
// 3. Signed Maximum (register)
//
//    SMAX  <Wd>, <Wn>, <Wm>
//    SMAX  <Xd>, <Xn>, <Xm>
//
// Signed Maximum (register) determines the signed maximum of the two source
// register values and writes the result to the destination register.
//
func (self *Program) SMAX(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMAX", 3, asm.Operands { v0, v1, v2 })
    // SMAX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 12, sa_vn, sa_vd))
    }
    // SMAX  <Wd>, <Wn>, #<simm>
    if isWr(v0) && isWr(v1) && isInRange(v2, -128, 127) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_simm := asImm8(v2)
        return p.setins(minmax_imm(0, 0, 0, 0, sa_simm, sa_wn, sa_wd))
    }
    // SMAX  <Xd>, <Xn>, #<simm>
    if isXr(v0) && isXr(v1) && isInRange(v2, -128, 127) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_simm := asImm8(v2)
        return p.setins(minmax_imm(1, 0, 0, 0, sa_simm, sa_xn, sa_xd))
    }
    // SMAX  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 24, sa_wn, sa_wd))
    }
    // SMAX  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 24, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SMAX")
}

// SMAXP instruction have one single form across one single category:
//
// 1. Signed Maximum Pairwise
//
//    SMAXP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Signed Maximum Pairwise. This instruction creates a vector by concatenating the
// vector elements of the first source SIMD&FP register after the vector elements
// of the second source SIMD&FP register, reads each pair of adjacent vector
// elements in the two source SIMD&FP registers, writes the largest of each pair of
// signed integer values into a vector, and writes the vector to the destination
// SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMAXP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMAXP", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMAXP")
}

// SMAXV instruction have one single form across one single category:
//
// 1. Signed Maximum across Vector
//
//    SMAXV  <V><d>, <Vn>.<T>
//
// Signed Maximum across Vector. This instruction compares all the vector elements
// in the source SIMD&FP register, and writes the largest of the values as a scalar
// to the destination SIMD&FP register. All the values in this instruction are
// signed integer values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMAXV(v0, v1 interface{}) *Instruction {
    p := self.alloc("SMAXV", 2, asm.Operands { v0, v1 })
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SMAXV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_t, 1, 2) != sa_v {
            panic("aarch64: invalid combination of operands for SMAXV")
        }
        return p.setins(asimdall(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 10, sa_vn, sa_d))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMAXV")
}

// SMC instruction have one single form across one single category:
//
// 1. Secure Monitor Call
//
//    SMC  #<imm>
//
// Secure Monitor Call causes an exception to EL3.
//
// SMC is available only for software executing at EL1 or higher. It is undefined
// in EL0.
//
// If the values of HCR_EL2 .TSC and SCR_EL3 .SMD are both 0, execution of an SMC
// instruction at EL1 or higher generates a Secure Monitor Call exception,
// recording it in ESR_ELx , using the EC value 0x17 , that is taken to EL3.
//
// If the value of HCR_EL2 .TSC is 1 and EL2 is enabled in the current Security
// state, execution of an SMC instruction at EL1 generates an exception that is
// taken to EL2, regardless of the value of SCR_EL3 .SMD.
//
// If the value of HCR_EL2 .TSC is 0 and the value of SCR_EL3 .SMD is 1, the SMC
// instruction is undefined .
//
func (self *Program) SMC(v0 interface{}) *Instruction {
    p := self.alloc("SMC", 1, asm.Operands { v0 })
    if isInRange(v0, 0, 65535) {
        p.Domain = DomainSystem
        sa_imm := asUimm16(v0)
        return p.setins(exception(0, sa_imm, 0, 3))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMC")
}

// SMIN instruction have 5 forms across 3 categories:
//
// 1. Signed Minimum (vector)
//
//    SMIN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Signed Minimum (vector). This instruction compares corresponding elements in the
// vectors in the two source SIMD&FP registers, places the smaller of each of the
// two signed integer values into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed Minimum (immediate)
//
//    SMIN  <Wd>, <Wn>, #<simm>
//    SMIN  <Xd>, <Xn>, #<simm>
//
// Signed Minimum (immediate) determines the signed minimum of the source register
// value and immediate, and writes the result to the destination register.
//
// 3. Signed Minimum (register)
//
//    SMIN  <Wd>, <Wn>, <Wm>
//    SMIN  <Xd>, <Xn>, <Xm>
//
// Signed Minimum (register) determines the signed minimum of the two source
// register values and writes the result to the destination register.
//
func (self *Program) SMIN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMIN", 3, asm.Operands { v0, v1, v2 })
    // SMIN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 13, sa_vn, sa_vd))
    }
    // SMIN  <Wd>, <Wn>, #<simm>
    if isWr(v0) && isWr(v1) && isInRange(v2, -128, 127) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_simm := asImm8(v2)
        return p.setins(minmax_imm(0, 0, 0, 2, sa_simm, sa_wn, sa_wd))
    }
    // SMIN  <Xd>, <Xn>, #<simm>
    if isXr(v0) && isXr(v1) && isInRange(v2, -128, 127) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_simm := asImm8(v2)
        return p.setins(minmax_imm(1, 0, 0, 2, sa_simm, sa_xn, sa_xd))
    }
    // SMIN  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 26, sa_wn, sa_wd))
    }
    // SMIN  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 26, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SMIN")
}

// SMINP instruction have one single form across one single category:
//
// 1. Signed Minimum Pairwise
//
//    SMINP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Signed Minimum Pairwise. This instruction creates a vector by concatenating the
// vector elements of the first source SIMD&FP register after the vector elements
// of the second source SIMD&FP register, reads each pair of adjacent vector
// elements in the two source SIMD&FP registers, writes the smallest of each pair
// of signed integer values into a vector, and writes the vector to the destination
// SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMINP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMINP", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 21, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMINP")
}

// SMINV instruction have one single form across one single category:
//
// 1. Signed Minimum across Vector
//
//    SMINV  <V><d>, <Vn>.<T>
//
// Signed Minimum across Vector. This instruction compares all the vector elements
// in the source SIMD&FP register, and writes the smallest of the values as a
// scalar to the destination SIMD&FP register. All the values in this instruction
// are signed integer values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMINV(v0, v1 interface{}) *Instruction {
    p := self.alloc("SMINV", 2, asm.Operands { v0, v1 })
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SMINV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_t, 1, 2) != sa_v {
            panic("aarch64: invalid combination of operands for SMINV")
        }
        return p.setins(asimdall(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 26, sa_vn, sa_d))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMINV")
}

// SMLAL instruction have 2 forms across 2 categories:
//
// 1. Signed Multiply-Add Long (vector, by element)
//
//    SMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed Multiply-Add Long (vector, by element). This instruction multiplies each
// vector element in the lower or upper half of the first source SIMD&FP register
// by the specified vector element in the second source SIMD&FP register, and
// accumulates the results with the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied. All the values in this instruction are signed integer values.
//
// The SMLAL instruction extracts vector elements from the lower half of the first
// source register. The SMLAL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed Multiply-Add Long (vector)
//
//    SMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Multiply-Add Long (vector). This instruction multiplies corresponding
// signed integer values in the lower or upper half of the vectors of the two
// source SIMD&FP registers, and accumulates the results with the vector elements
// of the destination SIMD&FP register. The destination vector elements are twice
// as long as the elements that are multiplied.
//
// The SMLAL instruction extracts each source vector from the lower half of each
// source register. The SMLAL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMLAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMLAL", 3, asm.Operands { v0, v1, v2 })
    // SMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SMLAL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SMLAL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SMLAL")
        }
        return p.setins(asimdelem(
            0,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            2,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SMLAL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SMLAL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 8, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SMLAL")
}

// SMLAL2 instruction have 2 forms across 2 categories:
//
// 1. Signed Multiply-Add Long (vector, by element)
//
//    SMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed Multiply-Add Long (vector, by element). This instruction multiplies each
// vector element in the lower or upper half of the first source SIMD&FP register
// by the specified vector element in the second source SIMD&FP register, and
// accumulates the results with the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied. All the values in this instruction are signed integer values.
//
// The SMLAL instruction extracts vector elements from the lower half of the first
// source register. The SMLAL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed Multiply-Add Long (vector)
//
//    SMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Multiply-Add Long (vector). This instruction multiplies corresponding
// signed integer values in the lower or upper half of the vectors of the two
// source SIMD&FP registers, and accumulates the results with the vector elements
// of the destination SIMD&FP register. The destination vector elements are twice
// as long as the elements that are multiplied.
//
// The SMLAL instruction extracts each source vector from the lower half of each
// source register. The SMLAL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMLAL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMLAL2", 3, asm.Operands { v0, v1, v2 })
    // SMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SMLAL2")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SMLAL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SMLAL2")
        }
        return p.setins(asimdelem(
            1,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            2,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SMLAL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SMLAL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 8, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SMLAL2")
}

// SMLSL instruction have 2 forms across 2 categories:
//
// 1. Signed Multiply-Subtract Long (vector, by element)
//
//    SMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed Multiply-Subtract Long (vector, by element). This instruction multiplies
// each vector element in the lower or upper half of the first source SIMD&FP
// register by the specified vector element of the second source SIMD&FP register
// and subtracts the results from the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The SMLSL instruction extracts vector elements from the lower half of the first
// source register. The SMLSL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed Multiply-Subtract Long (vector)
//
//    SMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Multiply-Subtract Long (vector). This instruction multiplies
// corresponding signed integer values in the lower or upper half of the vectors of
// the two source SIMD&FP registers, and subtracts the results from the vector
// elements of the destination SIMD&FP register. The destination vector elements
// are twice as long as the elements that are multiplied.
//
// The SMLSL instruction extracts each source vector from the lower half of each
// source register. The SMLSL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMLSL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMLSL", 3, asm.Operands { v0, v1, v2 })
    // SMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SMLSL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SMLSL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SMLSL")
        }
        return p.setins(asimdelem(
            0,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            6,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SMLSL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SMLSL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 10, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SMLSL")
}

// SMLSL2 instruction have 2 forms across 2 categories:
//
// 1. Signed Multiply-Subtract Long (vector, by element)
//
//    SMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed Multiply-Subtract Long (vector, by element). This instruction multiplies
// each vector element in the lower or upper half of the first source SIMD&FP
// register by the specified vector element of the second source SIMD&FP register
// and subtracts the results from the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The SMLSL instruction extracts vector elements from the lower half of the first
// source register. The SMLSL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed Multiply-Subtract Long (vector)
//
//    SMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Multiply-Subtract Long (vector). This instruction multiplies
// corresponding signed integer values in the lower or upper half of the vectors of
// the two source SIMD&FP registers, and subtracts the results from the vector
// elements of the destination SIMD&FP register. The destination vector elements
// are twice as long as the elements that are multiplied.
//
// The SMLSL instruction extracts each source vector from the lower half of each
// source register. The SMLSL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMLSL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMLSL2", 3, asm.Operands { v0, v1, v2 })
    // SMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SMLSL2")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SMLSL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SMLSL2")
        }
        return p.setins(asimdelem(
            1,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            6,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SMLSL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SMLSL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 10, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SMLSL2")
}

// SMMLA instruction have one single form across one single category:
//
// 1. Signed 8-bit integer matrix multiply-accumulate (vector)
//
//    SMMLA  <Vd>.4S, <Vn>.16B, <Vm>.16B
//
// Signed 8-bit integer matrix multiply-accumulate. This instruction multiplies the
// 2x8 matrix of signed 8-bit integer values in the first source vector by the 8x2
// matrix of signed 8-bit integer values in the second source vector. The resulting
// 2x2 32-bit integer matrix product is destructively added to the 32-bit integer
// matrix accumulator in the destination vector. This is equivalent to performing
// an 8-way dot product per destination element.
//
// From Armv8.2 to Armv8.5, this is an optional instruction. From Armv8.6 it is
// mandatory for implementations that include Advanced SIMD to support it.
// ID_AA64ISAR1_EL1 .I8MM indicates whether this instruction is supported.
//
func (self *Program) SMMLA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMMLA", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec16B && isVr(v2) && vfmt(v2) == Vec16B {
        self.Arch.Require(FEAT_I8MM)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame2(1, 0, 2, sa_vm, 4, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMMLA")
}

// SMNEGL instruction have one single form across one single category:
//
// 1. Signed Multiply-Negate Long
//
//    SMNEGL  <Xd>, <Wn>, <Wm>
//
// Signed Multiply-Negate Long multiplies two 32-bit register values, negates the
// product, and writes the result to the 64-bit destination register.
//
func (self *Program) SMNEGL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMNEGL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 1, sa_wm, 1, 31, sa_wn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMNEGL")
}

// SMOV instruction have 2 forms across one single category:
//
// 1. Signed Move vector element to general-purpose register
//
//    SMOV  <Wd>, <Vn>.<Ts>[<index>]
//    SMOV  <Xd>, <Vn>.<Ts>[<index>]
//
// Signed Move vector element to general-purpose register. This instruction reads
// the signed integer from the source SIMD&FP register, sign-extends it to form a
// 32-bit or 64-bit value, and writes the result to destination general-purpose
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMOV(v0, v1 interface{}) *Instruction {
    p := self.alloc("SMOV", 2, asm.Operands { v0, v1 })
    // SMOV  <Wd>, <Vn>.<Ts>[<index>]
    if isWr(v0) && isVri(v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_ts__bit_mask uint32
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(VidxRegister).ID())
        switch vmoder(v1) {
            case ModeB: sa_ts = 0b00001
            case ModeH: sa_ts = 0b00010
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v1) {
            case ModeB: sa_ts__bit_mask = 0b00001
            case ModeH: sa_ts__bit_mask = 0b00011
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v1))
        if sa_index != sa_ts & sa_ts__bit_mask {
            panic("aarch64: invalid combination of operands for SMOV")
        }
        return p.setins(asimdins(0, 0, sa_index, 5, sa_vn, sa_wd))
    }
    // SMOV  <Xd>, <Vn>.<Ts>[<index>]
    if isXr(v0) && isVri(v1) {
        p.Domain = DomainAdvSimd
        var sa_ts_1 uint32
        var sa_ts_1__bit_mask uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(VidxRegister).ID())
        switch vmoder(v1) {
            case ModeB: sa_ts_1 = 0b00001
            case ModeH: sa_ts_1 = 0b00010
            case ModeS: sa_ts_1 = 0b00100
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v1) {
            case ModeB: sa_ts_1__bit_mask = 0b00001
            case ModeH: sa_ts_1__bit_mask = 0b00011
            case ModeS: sa_ts_1__bit_mask = 0b00111
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v1))
        if sa_index_1 != sa_ts_1 & sa_ts_1__bit_mask {
            panic("aarch64: invalid combination of operands for SMOV")
        }
        return p.setins(asimdins(1, 0, sa_index_1, 5, sa_vn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SMOV")
}

// SMSTART instruction have one single form across one single category:
//
// 1. Enables access to Streaming SVE mode and SME architectural state
//
//    SMSTART  {<option>}
//
// Enables access to Streaming SVE mode and SME architectural state.
//
// SMSTART enters Streaming SVE mode, and enables the SME ZA storage.
//
// SMSTART SM enters Streaming SVE mode, but does not enable the SME ZA storage.
//
// SMSTART ZA enables the SME ZA storage, but does not cause an entry to Streaming
// SVE mode.
//
func (self *Program) SMSTART(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("SMSTART", 0, asm.Operands {})
        case 1  : p = self.alloc("SMSTART", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction SMSTART takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isSMEOption(vv[0])) {
        self.Arch.Require(FEAT_SME)
        p.Domain = DomainSystem
        sa_pstatefield := uint32(0b0111)
        if len(vv) >= 1 {
            sa_pstatefield = uint32(vv[0].(SMEOption))
        }
        return p.setins(pstate(3, mask(sa_pstatefield, 4), 3, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMSTART")
}

// SMSTOP instruction have one single form across one single category:
//
// 1. Disables access to Streaming SVE mode and SME architectural state
//
//    SMSTOP  {<option>}
//
// Disables access to Streaming SVE mode and SME architectural state.
//
// SMSTOP exits Streaming SVE mode, and disables the SME ZA storage.
//
// SMSTOP SM exits Streaming SVE mode, but does not disable the SME ZA storage.
//
// SMSTOP ZA disables the SME ZA storage, but does not cause an exit from Streaming
// SVE mode.
//
func (self *Program) SMSTOP(vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("SMSTOP", 0, asm.Operands {})
        case 1  : p = self.alloc("SMSTOP", 1, asm.Operands { vv[0] })
        default : panic("aarch64: instruction SMSTOP takes 0 or 1 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && (len(vv) == 0 || isSMEOption(vv[0])) {
        self.Arch.Require(FEAT_SME)
        p.Domain = DomainSystem
        sa_pstatefield := uint32(0b0111)
        if len(vv) >= 1 {
            sa_pstatefield = uint32(vv[0].(SMEOption))
        }
        return p.setins(pstate(3, mask(sa_pstatefield, 4), 3, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMSTOP")
}

// SMSUBL instruction have one single form across one single category:
//
// 1. Signed Multiply-Subtract Long
//
//    SMSUBL  <Xd>, <Wn>, <Wm>, <Xa>
//
// Signed Multiply-Subtract Long multiplies two 32-bit register values, subtracts
// the product from a 64-bit register value, and writes the result to the 64-bit
// destination register.
//
func (self *Program) SMSUBL(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("SMSUBL", 4, asm.Operands { v0, v1, v2, v3 })
    if isXr(v0) && isWr(v1) && isWr(v2) && isXr(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_xa := uint32(v3.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 1, sa_wm, 1, sa_xa, sa_wn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMSUBL")
}

// SMULH instruction have one single form across one single category:
//
// 1. Signed Multiply High
//
//    SMULH  <Xd>, <Xn>, <Xm>
//
// Signed Multiply High multiplies two 64-bit register values, and writes
// bits[127:64] of the 128-bit result to the 64-bit destination register.
//
func (self *Program) SMULH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMULH", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 2, sa_xm, 0, 31, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SMULH")
}

// SMULL instruction have 3 forms across 3 categories:
//
// 1. Signed Multiply Long
//
//    SMULL  <Xd>, <Wn>, <Wm>
//
// Signed Multiply Long multiplies two 32-bit register values, and writes the
// result to the 64-bit destination register.
//
// 2. Signed Multiply Long (vector, by element)
//
//    SMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed Multiply Long (vector, by element). This instruction multiplies each
// vector element in the lower or upper half of the first source SIMD&FP register
// by the specified vector element of the second source SIMD&FP register, places
// the result in a vector, and writes the vector to the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The SMULL instruction extracts vector elements from the lower half of the first
// source register. The SMULL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 3. Signed Multiply Long (vector)
//
//    SMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Multiply Long (vector). This instruction multiplies corresponding signed
// integer values in the lower or upper half of the vectors of the two source
// SIMD&FP registers, places the results in a vector, and writes the vector to the
// destination SIMD&FP register.
//
// The destination vector elements are twice as long as the elements that are
// multiplied.
//
// The SMULL instruction extracts each source vector from the lower half of each
// source register. The SMULL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMULL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMULL", 3, asm.Operands { v0, v1, v2 })
    // SMULL  <Xd>, <Wn>, <Wm>
    if isXr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 1, sa_wm, 0, 31, sa_wn, sa_xd))
    }
    // SMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SMULL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SMULL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SMULL")
        }
        return p.setins(asimdelem(
            0,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            10,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SMULL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SMULL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 12, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SMULL")
}

// SMULL2 instruction have 2 forms across 2 categories:
//
// 1. Signed Multiply Long (vector, by element)
//
//    SMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed Multiply Long (vector, by element). This instruction multiplies each
// vector element in the lower or upper half of the first source SIMD&FP register
// by the specified vector element of the second source SIMD&FP register, places
// the result in a vector, and writes the vector to the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The SMULL instruction extracts vector elements from the lower half of the first
// source register. The SMULL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed Multiply Long (vector)
//
//    SMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Multiply Long (vector). This instruction multiplies corresponding signed
// integer values in the lower or upper half of the vectors of the two source
// SIMD&FP registers, places the results in a vector, and writes the vector to the
// destination SIMD&FP register.
//
// The destination vector elements are twice as long as the elements that are
// multiplied.
//
// The SMULL instruction extracts each source vector from the lower half of each
// source register. The SMULL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SMULL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SMULL2", 3, asm.Operands { v0, v1, v2 })
    // SMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SMULL2")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SMULL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SMULL2")
        }
        return p.setins(asimdelem(
            1,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            10,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SMULL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SMULL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 12, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SMULL2")
}

// SQABS instruction have 2 forms across one single category:
//
// 1. Signed saturating Absolute value
//
//    SQABS  <Vd>.<T>, <Vn>.<T>
//    SQABS  <V><d>, <V><n>
//
// Signed saturating Absolute value. This instruction reads each vector element
// from the source SIMD&FP register, puts the absolute value of the result into a
// vector, and writes the vector to the destination SIMD&FP register. All the
// values in this instruction are signed integer values.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQABS(v0, v1 interface{}) *Instruction {
    p := self.alloc("SQABS", 2, asm.Operands { v0, v1 })
    // SQABS  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 7, sa_vn, sa_vd))
    }
    // SQABS  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SQABS")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(0, sa_v, 7, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQABS")
}

// SQADD instruction have 2 forms across one single category:
//
// 1. Signed saturating Add
//
//    SQADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SQADD  <V><d>, <V><n>, <V><m>
//
// Signed saturating Add. This instruction adds the values of corresponding
// elements of the two source SIMD&FP registers, places the results into a vector,
// and writes the vector to the destination SIMD&FP register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQADD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQADD", 3, asm.Operands { v0, v1, v2 })
    // SQADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 1, sa_vn, sa_vd))
    }
    // SQADD  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SQADD")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 1, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQADD")
}

// SQDMLAL instruction have 4 forms across 2 categories:
//
// 1. Signed saturating Doubling Multiply-Add Long (by element)
//
//    SQDMLAL  <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
//    SQDMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed saturating Doubling Multiply-Add Long (by element). This instruction
// multiplies each vector element in the lower or upper half of the first source
// SIMD&FP register by the specified vector element of the second source SIMD&FP
// register, doubles the results, and accumulates the final results with the vector
// elements of the destination SIMD&FP register. The destination vector elements
// are twice as long as the elements that are multiplied.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMLAL instruction extracts vector elements from the lower half of the
// first source register. The SQDMLAL2 instruction extracts vector elements from
// the upper half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed saturating Doubling Multiply-Add Long
//
//    SQDMLAL  <Va><d>, <Vb><n>, <Vb><m>
//    SQDMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed saturating Doubling Multiply-Add Long. This instruction multiplies
// corresponding signed integer values in the lower or upper half of the vectors of
// the two source SIMD&FP registers, doubles the results, and accumulates the final
// results with the vector elements of the destination SIMD&FP register. The
// destination vector elements are twice as long as the elements that are
// multiplied.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMLAL instruction extracts each source vector from the lower half of each
// source register. The SQDMLAL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQDMLAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQDMLAL", 3, asm.Operands { v0, v1, v2 })
    // SQDMLAL  <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_va = 0b01
            case DRegister: sa_va = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMLAL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_vb = 0b01
            case SRegister: sa_vb = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMLAL")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ts || sa_ts != sa_va || sa_va != sa_vb || sa_vb != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMLAL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMLAL")
        }
        return p.setins(asisdelem(
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            3,
            ubfx(sa_index, 1, 1),
            sa_n,
            sa_d,
        ))
    }
    // SQDMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMLAL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMLAL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQDMLAL")
        }
        return p.setins(asimdelem(
            0,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            3,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQDMLAL  <Va><d>, <Vb><n>, <Vb><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_va = 0b01
            case DRegister: sa_va = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMLAL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_vb = 0b01
            case SRegister: sa_vb = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMLAL")
        }
        sa_m := uint32(v2.(asm.Register).ID())
        if sa_va != sa_vb {
            panic("aarch64: invalid combination of operands for SQDMLAL")
        }
        return p.setins(asisddiff(0, sa_va, sa_m, 9, sa_n, sa_d))
    }
    // SQDMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQDMLAL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQDMLAL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 9, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQDMLAL")
}

// SQDMLAL2 instruction have 2 forms across 2 categories:
//
// 1. Signed saturating Doubling Multiply-Add Long (by element)
//
//    SQDMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed saturating Doubling Multiply-Add Long (by element). This instruction
// multiplies each vector element in the lower or upper half of the first source
// SIMD&FP register by the specified vector element of the second source SIMD&FP
// register, doubles the results, and accumulates the final results with the vector
// elements of the destination SIMD&FP register. The destination vector elements
// are twice as long as the elements that are multiplied.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMLAL instruction extracts vector elements from the lower half of the
// first source register. The SQDMLAL2 instruction extracts vector elements from
// the upper half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed saturating Doubling Multiply-Add Long
//
//    SQDMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed saturating Doubling Multiply-Add Long. This instruction multiplies
// corresponding signed integer values in the lower or upper half of the vectors of
// the two source SIMD&FP registers, doubles the results, and accumulates the final
// results with the vector elements of the destination SIMD&FP register. The
// destination vector elements are twice as long as the elements that are
// multiplied.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMLAL instruction extracts each source vector from the lower half of each
// source register. The SQDMLAL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQDMLAL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQDMLAL2", 3, asm.Operands { v0, v1, v2 })
    // SQDMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMLAL2")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMLAL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQDMLAL2")
        }
        return p.setins(asimdelem(
            1,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            3,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQDMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQDMLAL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQDMLAL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 9, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQDMLAL2")
}

// SQDMLSL instruction have 4 forms across 2 categories:
//
// 1. Signed saturating Doubling Multiply-Subtract Long (by element)
//
//    SQDMLSL  <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
//    SQDMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed saturating Doubling Multiply-Subtract Long (by element). This instruction
// multiplies each vector element in the lower or upper half of the first source
// SIMD&FP register by the specified vector element of the second source SIMD&FP
// register, doubles the results, and subtracts the final results from the vector
// elements of the destination SIMD&FP register. The destination vector elements
// are twice as long as the elements that are multiplied. All the values in this
// instruction are signed integer values.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMLSL instruction extracts vector elements from the lower half of the
// first source register. The SQDMLSL2 instruction extracts vector elements from
// the upper half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed saturating Doubling Multiply-Subtract Long
//
//    SQDMLSL  <Va><d>, <Vb><n>, <Vb><m>
//    SQDMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed saturating Doubling Multiply-Subtract Long. This instruction multiplies
// corresponding signed integer values in the lower or upper half of the vectors of
// the two source SIMD&FP registers, doubles the results, and subtracts the final
// results from the vector elements of the destination SIMD&FP register. The
// destination vector elements are twice as long as the elements that are
// multiplied.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMLSL instruction extracts each source vector from the lower half of each
// source register. The SQDMLSL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQDMLSL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQDMLSL", 3, asm.Operands { v0, v1, v2 })
    // SQDMLSL  <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_va = 0b01
            case DRegister: sa_va = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMLSL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_vb = 0b01
            case SRegister: sa_vb = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMLSL")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ts || sa_ts != sa_va || sa_va != sa_vb || sa_vb != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMLSL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMLSL")
        }
        return p.setins(asisdelem(
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            7,
            ubfx(sa_index, 1, 1),
            sa_n,
            sa_d,
        ))
    }
    // SQDMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMLSL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMLSL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQDMLSL")
        }
        return p.setins(asimdelem(
            0,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            7,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQDMLSL  <Va><d>, <Vb><n>, <Vb><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_va = 0b01
            case DRegister: sa_va = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMLSL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_vb = 0b01
            case SRegister: sa_vb = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMLSL")
        }
        sa_m := uint32(v2.(asm.Register).ID())
        if sa_va != sa_vb {
            panic("aarch64: invalid combination of operands for SQDMLSL")
        }
        return p.setins(asisddiff(0, sa_va, sa_m, 11, sa_n, sa_d))
    }
    // SQDMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQDMLSL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQDMLSL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 11, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQDMLSL")
}

// SQDMLSL2 instruction have 2 forms across 2 categories:
//
// 1. Signed saturating Doubling Multiply-Subtract Long (by element)
//
//    SQDMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed saturating Doubling Multiply-Subtract Long (by element). This instruction
// multiplies each vector element in the lower or upper half of the first source
// SIMD&FP register by the specified vector element of the second source SIMD&FP
// register, doubles the results, and subtracts the final results from the vector
// elements of the destination SIMD&FP register. The destination vector elements
// are twice as long as the elements that are multiplied. All the values in this
// instruction are signed integer values.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMLSL instruction extracts vector elements from the lower half of the
// first source register. The SQDMLSL2 instruction extracts vector elements from
// the upper half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed saturating Doubling Multiply-Subtract Long
//
//    SQDMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed saturating Doubling Multiply-Subtract Long. This instruction multiplies
// corresponding signed integer values in the lower or upper half of the vectors of
// the two source SIMD&FP registers, doubles the results, and subtracts the final
// results from the vector elements of the destination SIMD&FP register. The
// destination vector elements are twice as long as the elements that are
// multiplied.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMLSL instruction extracts each source vector from the lower half of each
// source register. The SQDMLSL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQDMLSL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQDMLSL2", 3, asm.Operands { v0, v1, v2 })
    // SQDMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMLSL2")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMLSL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQDMLSL2")
        }
        return p.setins(asimdelem(
            1,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            7,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQDMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQDMLSL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQDMLSL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 11, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQDMLSL2")
}

// SQDMULH instruction have 4 forms across 2 categories:
//
// 1. Signed saturating Doubling Multiply returning High half (by element)
//
//    SQDMULH  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//    SQDMULH  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
//
// Signed saturating Doubling Multiply returning High half (by element). This
// instruction multiplies each vector element in the first source SIMD&FP register
// by the specified vector element of the second source SIMD&FP register, doubles
// the results, places the most significant half of the final results into a
// vector, and writes the vector to the destination SIMD&FP register.
//
// The results are truncated. For rounded results, see SQRDMULH .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed saturating Doubling Multiply returning High half
//
//    SQDMULH  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SQDMULH  <V><d>, <V><n>, <V><m>
//
// Signed saturating Doubling Multiply returning High half. This instruction
// multiplies the values of corresponding elements of the two source SIMD&FP
// registers, doubles the results, places the most significant half of the final
// results into a vector, and writes the vector to the destination SIMD&FP
// register.
//
// The results are truncated. For rounded results, see SQRDMULH .
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQDMULH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQDMULH", 3, asm.Operands { v0, v1, v2 })
    // SQDMULH  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != ubfx(sa_t, 1, 2) || ubfx(sa_t, 1, 2) != sa_ts || sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMULH")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMULH")
        }
        return p.setins(asimdelem(
            mask(sa_t, 1),
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            12,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQDMULH  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMULH")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ts || sa_ts != sa_v || sa_v != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMULH")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMULH")
        }
        return p.setins(asisdelem(
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            12,
            ubfx(sa_index, 1, 1),
            sa_n,
            sa_d,
        ))
    }
    // SQDMULH  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 22, sa_vn, sa_vd))
    }
    // SQDMULH  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMULH")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 22, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQDMULH")
}

// SQDMULL instruction have 4 forms across 2 categories:
//
// 1. Signed saturating Doubling Multiply Long (by element)
//
//    SQDMULL  <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
//    SQDMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed saturating Doubling Multiply Long (by element). This instruction
// multiplies each vector element in the lower or upper half of the first source
// SIMD&FP register by the specified vector element of the second source SIMD&FP
// register, doubles the results, places the final results in a vector, and writes
// the vector to the destination SIMD&FP register. All the values in this
// instruction are signed integer values.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMULL instruction extracts the first source vector from the lower half of
// the first source register. The SQDMULL2 instruction extracts the first source
// vector from the upper half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed saturating Doubling Multiply Long
//
//    SQDMULL  <Va><d>, <Vb><n>, <Vb><m>
//    SQDMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed saturating Doubling Multiply Long. This instruction multiplies
// corresponding vector elements in the lower or upper half of the two source
// SIMD&FP registers, doubles the results, places the final results in a vector,
// and writes the vector to the destination SIMD&FP register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMULL instruction extracts each source vector from the lower half of each
// source register. The SQDMULL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQDMULL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQDMULL", 3, asm.Operands { v0, v1, v2 })
    // SQDMULL  <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_va = 0b01
            case DRegister: sa_va = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMULL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_vb = 0b01
            case SRegister: sa_vb = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMULL")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ts || sa_ts != sa_va || sa_va != sa_vb || sa_vb != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMULL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMULL")
        }
        return p.setins(asisdelem(
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            11,
            ubfx(sa_index, 1, 1),
            sa_n,
            sa_d,
        ))
    }
    // SQDMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMULL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMULL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQDMULL")
        }
        return p.setins(asimdelem(
            0,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            11,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQDMULL  <Va><d>, <Vb><n>, <Vb><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_va = 0b01
            case DRegister: sa_va = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMULL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_vb = 0b01
            case SRegister: sa_vb = 0b10
            default: panic("aarch64: invalid scalar operand size for SQDMULL")
        }
        sa_m := uint32(v2.(asm.Register).ID())
        if sa_va != sa_vb {
            panic("aarch64: invalid combination of operands for SQDMULL")
        }
        return p.setins(asisddiff(0, sa_va, sa_m, 13, sa_n, sa_d))
    }
    // SQDMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQDMULL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQDMULL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 13, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQDMULL")
}

// SQDMULL2 instruction have 2 forms across 2 categories:
//
// 1. Signed saturating Doubling Multiply Long (by element)
//
//    SQDMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Signed saturating Doubling Multiply Long (by element). This instruction
// multiplies each vector element in the lower or upper half of the first source
// SIMD&FP register by the specified vector element of the second source SIMD&FP
// register, doubles the results, places the final results in a vector, and writes
// the vector to the destination SIMD&FP register. All the values in this
// instruction are signed integer values.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMULL instruction extracts the first source vector from the lower half of
// the first source register. The SQDMULL2 instruction extracts the first source
// vector from the upper half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed saturating Doubling Multiply Long
//
//    SQDMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed saturating Doubling Multiply Long. This instruction multiplies
// corresponding vector elements in the lower or upper half of the two source
// SIMD&FP registers, doubles the results, places the final results in a vector,
// and writes the vector to the destination SIMD&FP register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQDMULL instruction extracts each source vector from the lower half of each
// source register. The SQDMULL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQDMULL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQDMULL2", 3, asm.Operands { v0, v1, v2 })
    // SQDMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQDMULL2")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQDMULL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQDMULL2")
        }
        return p.setins(asimdelem(
            1,
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            11,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQDMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQDMULL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQDMULL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 13, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQDMULL2")
}

// SQNEG instruction have 2 forms across one single category:
//
// 1. Signed saturating Negate
//
//    SQNEG  <Vd>.<T>, <Vn>.<T>
//    SQNEG  <V><d>, <V><n>
//
// Signed saturating Negate. This instruction reads each vector element from the
// source SIMD&FP register, negates each value, places the result into a vector,
// and writes the vector to the destination SIMD&FP register. All the values in
// this instruction are signed integer values.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQNEG(v0, v1 interface{}) *Instruction {
    p := self.alloc("SQNEG", 2, asm.Operands { v0, v1 })
    // SQNEG  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 7, sa_vn, sa_vd))
    }
    // SQNEG  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SQNEG")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(1, sa_v, 7, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQNEG")
}

// SQRDMLAH instruction have 4 forms across 2 categories:
//
// 1. Signed Saturating Rounding Doubling Multiply Accumulate returning High Half
//    (by element)
//
//    SQRDMLAH  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//    SQRDMLAH  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
//
// Signed Saturating Rounding Doubling Multiply Accumulate returning High Half (by
// element). This instruction multiplies the vector elements of the first source
// SIMD&FP register with the value of a vector element of the second source SIMD&FP
// register without saturating the multiply results, doubles the results, and
// accumulates the most significant half of the final results with the vector
// elements of the destination SIMD&FP register. The results are rounded.
//
// If any of the results overflow, they are saturated. The cumulative saturation
// bit, FPSR .QC, is set if saturation occurs.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed Saturating Rounding Doubling Multiply Accumulate returning High Half
//    (vector)
//
//    SQRDMLAH  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SQRDMLAH  <V><d>, <V><n>, <V><m>
//
// Signed Saturating Rounding Doubling Multiply Accumulate returning High Half
// (vector). This instruction multiplies the vector elements of the first source
// SIMD&FP register with the corresponding vector elements of the second source
// SIMD&FP register without saturating the multiply results, doubles the results,
// and accumulates the most significant half of the final results with the vector
// elements of the destination SIMD&FP register. The results are rounded.
//
// If any of the results overflow, they are saturated. The cumulative saturation
// bit, FPSR .QC, is set if saturation occurs.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQRDMLAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQRDMLAH", 3, asm.Operands { v0, v1, v2 })
    // SQRDMLAH  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_RDM)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != ubfx(sa_t, 1, 2) || ubfx(sa_t, 1, 2) != sa_ts || sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQRDMLAH")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQRDMLAH")
        }
        return p.setins(asimdelem(
            mask(sa_t, 1),
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            13,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQRDMLAH  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) && isSameType(v0, v1) {
        self.Arch.Require(FEAT_RDM)
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SQRDMLAH")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ts || sa_ts != sa_v || sa_v != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQRDMLAH")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQRDMLAH")
        }
        return p.setins(asisdelem(
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            13,
            ubfx(sa_index, 1, 1),
            sa_n,
            sa_d,
        ))
    }
    // SQRDMLAH  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_RDM)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame2(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 0, sa_vn, sa_vd))
    }
    // SQRDMLAH  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        self.Arch.Require(FEAT_RDM)
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SQRDMLAH")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame2(1, sa_v, sa_m, 0, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQRDMLAH")
}

// SQRDMLSH instruction have 4 forms across 2 categories:
//
// 1. Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by
//    element)
//
//    SQRDMLSH  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//    SQRDMLSH  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
//
// Signed Saturating Rounding Doubling Multiply Subtract returning High Half (by
// element). This instruction multiplies the vector elements of the first source
// SIMD&FP register with the value of a vector element of the second source SIMD&FP
// register without saturating the multiply results, doubles the results, and
// subtracts the most significant half of the final results from the vector
// elements of the destination SIMD&FP register. The results are rounded.
//
// If any of the results overflow, they are saturated. The cumulative saturation
// bit, FPSR .QC, is set if saturation occurs.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed Saturating Rounding Doubling Multiply Subtract returning High Half
//    (vector)
//
//    SQRDMLSH  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SQRDMLSH  <V><d>, <V><n>, <V><m>
//
// Signed Saturating Rounding Doubling Multiply Subtract returning High Half
// (vector). This instruction multiplies the vector elements of the first source
// SIMD&FP register with the corresponding vector elements of the second source
// SIMD&FP register without saturating the multiply results, doubles the results,
// and subtracts the most significant half of the final results from the vector
// elements of the destination SIMD&FP register. The results are rounded.
//
// If any of the results overflow, they are saturated. The cumulative saturation
// bit, FPSR .QC, is set if saturation occurs.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQRDMLSH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQRDMLSH", 3, asm.Operands { v0, v1, v2 })
    // SQRDMLSH  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_RDM)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != ubfx(sa_t, 1, 2) || ubfx(sa_t, 1, 2) != sa_ts || sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQRDMLSH")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQRDMLSH")
        }
        return p.setins(asimdelem(
            mask(sa_t, 1),
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            15,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQRDMLSH  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) && isSameType(v0, v1) {
        self.Arch.Require(FEAT_RDM)
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SQRDMLSH")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ts || sa_ts != sa_v || sa_v != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQRDMLSH")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQRDMLSH")
        }
        return p.setins(asisdelem(
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            15,
            ubfx(sa_index, 1, 1),
            sa_n,
            sa_d,
        ))
    }
    // SQRDMLSH  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_RDM)
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame2(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 1, sa_vn, sa_vd))
    }
    // SQRDMLSH  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        self.Arch.Require(FEAT_RDM)
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SQRDMLSH")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame2(1, sa_v, sa_m, 1, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQRDMLSH")
}

// SQRDMULH instruction have 4 forms across 2 categories:
//
// 1. Signed saturating Rounding Doubling Multiply returning High half (by element)
//
//    SQRDMULH  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
//    SQRDMULH  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
//
// Signed saturating Rounding Doubling Multiply returning High half (by element).
// This instruction multiplies each vector element in the first source SIMD&FP
// register by the specified vector element of the second source SIMD&FP register,
// doubles the results, places the most significant half of the final results into
// a vector, and writes the vector to the destination SIMD&FP register.
//
// The results are rounded. For truncated results, see SQDMULH .
//
// If any of the results overflows, they are saturated. If saturation occurs, the
// cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed saturating Rounding Doubling Multiply returning High half
//
//    SQRDMULH  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SQRDMULH  <V><d>, <V><n>, <V><m>
//
// Signed saturating Rounding Doubling Multiply returning High half. This
// instruction multiplies the values of corresponding elements of the two source
// SIMD&FP registers, doubles the results, places the most significant half of the
// final results into a vector, and writes the vector to the destination SIMD&FP
// register.
//
// The results are rounded. For truncated results, see SQDMULH .
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQRDMULH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQRDMULH", 3, asm.Operands { v0, v1, v2 })
    // SQRDMULH  <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVri(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != ubfx(sa_t, 1, 2) || ubfx(sa_t, 1, 2) != sa_ts || sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQRDMULH")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQRDMULH")
        }
        return p.setins(asimdelem(
            mask(sa_t, 1),
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            13,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // SQRDMULH  <V><d>, <V><n>, <Vm>.<Ts>[<index>]
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isVri(v2) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SQRDMULH")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ts || sa_ts != sa_v || sa_v != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for SQRDMULH")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for SQRDMULH")
        }
        return p.setins(asisdelem(
            0,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            13,
            ubfx(sa_index, 1, 1),
            sa_n,
            sa_d,
        ))
    }
    // SQRDMULH  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 22, sa_vn, sa_vd))
    }
    // SQRDMULH  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for SQRDMULH")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 22, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQRDMULH")
}

// SQRSHL instruction have 2 forms across one single category:
//
// 1. Signed saturating Rounding Shift Left (register)
//
//    SQRSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SQRSHL  <V><d>, <V><n>, <V><m>
//
// Signed saturating Rounding Shift Left (register). This instruction takes each
// vector element in the first source SIMD&FP register, shifts it by a value from
// the least significant byte of the corresponding vector element of the second
// source SIMD&FP register, places the results into a vector, and writes the vector
// to the destination SIMD&FP register.
//
// If the shift value is positive, the operation is a left shift. Otherwise, it is
// a right shift. The results are rounded. For truncated results, see SQSHL .
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQRSHL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQRSHL", 3, asm.Operands { v0, v1, v2 })
    // SQRSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 11, sa_vn, sa_vd))
    }
    // SQRSHL  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SQRSHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 11, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQRSHL")
}

// SQRSHRN instruction have 2 forms across one single category:
//
// 1. Signed saturating Rounded Shift Right Narrow (immediate)
//
//    SQRSHRN  <Vb><d>, <Va><n>, #<shift>
//    SQRSHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Signed saturating Rounded Shift Right Narrow (immediate). This instruction reads
// each vector element in the source SIMD&FP register, right shifts each result by
// an immediate value, saturates each shifted result to a value that is half the
// original width, puts the final result into a vector, and writes the vector to
// the lower or upper half of the destination SIMD&FP register. All the values in
// this instruction are signed integer values. The destination vector elements are
// half as long as the source vector elements. The results are rounded. For
// truncated results, see SQSHRN .
//
// The SQRSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQRSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQRSHRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQRSHRN", 3, asm.Operands { v0, v1, v2 })
    // SQRSHRN  <Vb><d>, <Va><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_va uint32
        var sa_va__bit_mask uint32
        var sa_vb uint32
        var sa_vb__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_vb = 0b0001
            case HRegister: sa_vb = 0b0010
            case SRegister: sa_vb = 0b0100
            default: panic("aarch64: invalid scalar operand size for SQRSHRN")
        }
        switch v0.(type) {
            case BRegister: sa_vb__bit_mask = 0b1111
            case HRegister: sa_vb__bit_mask = 0b1110
            case SRegister: sa_vb__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for SQRSHRN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_va = 0b0001
            case SRegister: sa_va = 0b0010
            case DRegister: sa_va = 0b0100
            default: panic("aarch64: invalid scalar operand size for SQRSHRN")
        }
        switch v1.(type) {
            case HRegister: sa_va__bit_mask = 0b1111
            case SRegister: sa_va__bit_mask = 0b1110
            case DRegister: sa_va__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for SQRSHRN")
        }
        switch sa_vb {
            case 0b0001: sa_shift_1 = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift_1 = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift_1 = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for SQRSHRN")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_va & sa_va__bit_mask || sa_va & sa_va__bit_mask != sa_vb & sa_vb__bit_mask {
            panic("aarch64: invalid combination of operands for SQRSHRN")
        }
        return p.setins(asisdshf(0, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 19, sa_n, sa_d))
    }
    // SQRSHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SQRSHRN")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQRSHRN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQRSHRN")
        }
        return p.setins(asimdshf(0, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 19, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQRSHRN")
}

// SQRSHRN2 instruction have one single form across one single category:
//
// 1. Signed saturating Rounded Shift Right Narrow (immediate)
//
//    SQRSHRN2  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Signed saturating Rounded Shift Right Narrow (immediate). This instruction reads
// each vector element in the source SIMD&FP register, right shifts each result by
// an immediate value, saturates each shifted result to a value that is half the
// original width, puts the final result into a vector, and writes the vector to
// the lower or upper half of the destination SIMD&FP register. All the values in
// this instruction are signed integer values. The destination vector elements are
// half as long as the source vector elements. The results are rounded. For
// truncated results, see SQSHRN .
//
// The SQRSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQRSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQRSHRN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQRSHRN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SQRSHRN2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQRSHRN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQRSHRN2")
        }
        return p.setins(asimdshf(1, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 19, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SQRSHRN2")
}

// SQRSHRUN instruction have 2 forms across one single category:
//
// 1. Signed saturating Rounded Shift Right Unsigned Narrow (immediate)
//
//    SQRSHRUN  <Vb><d>, <Va><n>, #<shift>
//    SQRSHRUN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Signed saturating Rounded Shift Right Unsigned Narrow (immediate). This
// instruction reads each signed integer value in the vector of the source SIMD&FP
// register, right shifts each value by an immediate value, saturates the result to
// an unsigned integer value that is half the original width, places the final
// result into a vector, and writes the vector to the destination SIMD&FP register.
// The results are rounded. For truncated results, see SQSHRUN .
//
// The SQRSHRUN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQRSHRUN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQRSHRUN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQRSHRUN", 3, asm.Operands { v0, v1, v2 })
    // SQRSHRUN  <Vb><d>, <Va><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_va uint32
        var sa_va__bit_mask uint32
        var sa_vb uint32
        var sa_vb__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_vb = 0b0001
            case HRegister: sa_vb = 0b0010
            case SRegister: sa_vb = 0b0100
            default: panic("aarch64: invalid scalar operand size for SQRSHRUN")
        }
        switch v0.(type) {
            case BRegister: sa_vb__bit_mask = 0b1111
            case HRegister: sa_vb__bit_mask = 0b1110
            case SRegister: sa_vb__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for SQRSHRUN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_va = 0b0001
            case SRegister: sa_va = 0b0010
            case DRegister: sa_va = 0b0100
            default: panic("aarch64: invalid scalar operand size for SQRSHRUN")
        }
        switch v1.(type) {
            case HRegister: sa_va__bit_mask = 0b1111
            case SRegister: sa_va__bit_mask = 0b1110
            case DRegister: sa_va__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for SQRSHRUN")
        }
        switch sa_vb {
            case 0b0001: sa_shift_1 = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift_1 = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift_1 = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for SQRSHRUN")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_va & sa_va__bit_mask || sa_va & sa_va__bit_mask != sa_vb & sa_vb__bit_mask {
            panic("aarch64: invalid combination of operands for SQRSHRUN")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 17, sa_n, sa_d))
    }
    // SQRSHRUN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SQRSHRUN")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQRSHRUN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQRSHRUN")
        }
        return p.setins(asimdshf(0, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 17, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQRSHRUN")
}

// SQRSHRUN2 instruction have one single form across one single category:
//
// 1. Signed saturating Rounded Shift Right Unsigned Narrow (immediate)
//
//    SQRSHRUN2  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Signed saturating Rounded Shift Right Unsigned Narrow (immediate). This
// instruction reads each signed integer value in the vector of the source SIMD&FP
// register, right shifts each value by an immediate value, saturates the result to
// an unsigned integer value that is half the original width, places the final
// result into a vector, and writes the vector to the destination SIMD&FP register.
// The results are rounded. For truncated results, see SQSHRUN .
//
// The SQRSHRUN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQRSHRUN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQRSHRUN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQRSHRUN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SQRSHRUN2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQRSHRUN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQRSHRUN2")
        }
        return p.setins(asimdshf(1, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 17, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SQRSHRUN2")
}

// SQSHL instruction have 4 forms across 2 categories:
//
// 1. Signed saturating Shift Left (immediate)
//
//    SQSHL  <Vd>.<T>, <Vn>.<T>, #<shift>
//    SQSHL  <V><d>, <V><n>, #<shift>
//
// Signed saturating Shift Left (immediate). This instruction reads each vector
// element in the source SIMD&FP register, shifts each result by an immediate
// value, places the final result in a vector, and writes the vector to the
// destination SIMD&FP register. The results are truncated. For rounded results,
// see UQRSHL .
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Signed saturating Shift Left (register)
//
//    SQSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SQSHL  <V><d>, <V><n>, <V><m>
//
// Signed saturating Shift Left (register). This instruction takes each element in
// the vector of the first source SIMD&FP register, shifts each element by a value
// from the least significant byte of the corresponding element of the second
// source SIMD&FP register, places the results in a vector, and writes the vector
// to the destination SIMD&FP register.
//
// If the shift value is positive, the operation is a left shift. Otherwise, it is
// a right shift. The results are truncated. For rounded results, see SQRSHL .
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQSHL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQSHL", 3, asm.Operands { v0, v1, v2 })
    // SQSHL  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift = uint32(asLit(v2)) + 32
            case 0b1000: sa_shift = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift' for SQSHL")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQSHL")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 14, sa_vn, sa_vd))
    }
    // SQSHL  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(v2) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b0001
            case HRegister: sa_v = 0b0010
            case SRegister: sa_v = 0b0100
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SQSHL")
        }
        switch v0.(type) {
            case BRegister: sa_v__bit_mask = 0b1111
            case HRegister: sa_v__bit_mask = 0b1110
            case SRegister: sa_v__bit_mask = 0b1100
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SQSHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b0001: sa_shift_1 = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift_1 = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift_1 = uint32(asLit(v2)) + 32
            case 0b1000: sa_shift_1 = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift_1' for SQSHL")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SQSHL")
        }
        return p.setins(asisdshf(0, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 14, sa_n, sa_d))
    }
    // SQSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 9, sa_vn, sa_vd))
    }
    // SQSHL  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SQSHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 9, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQSHL")
}

// SQSHLU instruction have 2 forms across one single category:
//
// 1. Signed saturating Shift Left Unsigned (immediate)
//
//    SQSHLU  <Vd>.<T>, <Vn>.<T>, #<shift>
//    SQSHLU  <V><d>, <V><n>, #<shift>
//
// Signed saturating Shift Left Unsigned (immediate). This instruction reads each
// signed integer value in the vector of the source SIMD&FP register, shifts each
// value by an immediate value, saturates the shifted result to an unsigned integer
// value, places the result in a vector, and writes the vector to the destination
// SIMD&FP register. The results are truncated. For rounded results, see UQRSHL .
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQSHLU(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQSHLU", 3, asm.Operands { v0, v1, v2 })
    // SQSHLU  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift = uint32(asLit(v2)) + 32
            case 0b1000: sa_shift = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift' for SQSHLU")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQSHLU")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 12, sa_vn, sa_vd))
    }
    // SQSHLU  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(v2) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b0001
            case HRegister: sa_v = 0b0010
            case SRegister: sa_v = 0b0100
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SQSHLU")
        }
        switch v0.(type) {
            case BRegister: sa_v__bit_mask = 0b1111
            case HRegister: sa_v__bit_mask = 0b1110
            case SRegister: sa_v__bit_mask = 0b1100
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SQSHLU")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b0001: sa_shift_1 = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift_1 = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift_1 = uint32(asLit(v2)) + 32
            case 0b1000: sa_shift_1 = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift_1' for SQSHLU")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SQSHLU")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 12, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQSHLU")
}

// SQSHRN instruction have 2 forms across one single category:
//
// 1. Signed saturating Shift Right Narrow (immediate)
//
//    SQSHRN  <Vb><d>, <Va><n>, #<shift>
//    SQSHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Signed saturating Shift Right Narrow (immediate). This instruction reads each
// vector element in the source SIMD&FP register, right shifts and truncates each
// result by an immediate value, saturates each shifted result to a value that is
// half the original width, puts the final result into a vector, and writes the
// vector to the lower or upper half of the destination SIMD&FP register. All the
// values in this instruction are signed integer values. The destination vector
// elements are half as long as the source vector elements. For rounded results,
// see SQRSHRN .
//
// The SQSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQSHRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQSHRN", 3, asm.Operands { v0, v1, v2 })
    // SQSHRN  <Vb><d>, <Va><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_va uint32
        var sa_va__bit_mask uint32
        var sa_vb uint32
        var sa_vb__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_vb = 0b0001
            case HRegister: sa_vb = 0b0010
            case SRegister: sa_vb = 0b0100
            default: panic("aarch64: invalid scalar operand size for SQSHRN")
        }
        switch v0.(type) {
            case BRegister: sa_vb__bit_mask = 0b1111
            case HRegister: sa_vb__bit_mask = 0b1110
            case SRegister: sa_vb__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for SQSHRN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_va = 0b0001
            case SRegister: sa_va = 0b0010
            case DRegister: sa_va = 0b0100
            default: panic("aarch64: invalid scalar operand size for SQSHRN")
        }
        switch v1.(type) {
            case HRegister: sa_va__bit_mask = 0b1111
            case SRegister: sa_va__bit_mask = 0b1110
            case DRegister: sa_va__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for SQSHRN")
        }
        switch sa_vb {
            case 0b0001: sa_shift_1 = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift_1 = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift_1 = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for SQSHRN")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_va & sa_va__bit_mask || sa_va & sa_va__bit_mask != sa_vb & sa_vb__bit_mask {
            panic("aarch64: invalid combination of operands for SQSHRN")
        }
        return p.setins(asisdshf(0, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 18, sa_n, sa_d))
    }
    // SQSHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SQSHRN")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQSHRN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQSHRN")
        }
        return p.setins(asimdshf(0, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 18, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQSHRN")
}

// SQSHRN2 instruction have one single form across one single category:
//
// 1. Signed saturating Shift Right Narrow (immediate)
//
//    SQSHRN2  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Signed saturating Shift Right Narrow (immediate). This instruction reads each
// vector element in the source SIMD&FP register, right shifts and truncates each
// result by an immediate value, saturates each shifted result to a value that is
// half the original width, puts the final result into a vector, and writes the
// vector to the lower or upper half of the destination SIMD&FP register. All the
// values in this instruction are signed integer values. The destination vector
// elements are half as long as the source vector elements. For rounded results,
// see SQRSHRN .
//
// The SQSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQSHRN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQSHRN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SQSHRN2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQSHRN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQSHRN2")
        }
        return p.setins(asimdshf(1, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 18, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SQSHRN2")
}

// SQSHRUN instruction have 2 forms across one single category:
//
// 1. Signed saturating Shift Right Unsigned Narrow (immediate)
//
//    SQSHRUN  <Vb><d>, <Va><n>, #<shift>
//    SQSHRUN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Signed saturating Shift Right Unsigned Narrow (immediate). This instruction
// reads each signed integer value in the vector of the source SIMD&FP register,
// right shifts each value by an immediate value, saturates the result to an
// unsigned integer value that is half the original width, places the final result
// into a vector, and writes the vector to the destination SIMD&FP register. The
// results are truncated. For rounded results, see SQRSHRUN .
//
// The SQSHRUN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQSHRUN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQSHRUN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQSHRUN", 3, asm.Operands { v0, v1, v2 })
    // SQSHRUN  <Vb><d>, <Va><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_va uint32
        var sa_va__bit_mask uint32
        var sa_vb uint32
        var sa_vb__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_vb = 0b0001
            case HRegister: sa_vb = 0b0010
            case SRegister: sa_vb = 0b0100
            default: panic("aarch64: invalid scalar operand size for SQSHRUN")
        }
        switch v0.(type) {
            case BRegister: sa_vb__bit_mask = 0b1111
            case HRegister: sa_vb__bit_mask = 0b1110
            case SRegister: sa_vb__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for SQSHRUN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_va = 0b0001
            case SRegister: sa_va = 0b0010
            case DRegister: sa_va = 0b0100
            default: panic("aarch64: invalid scalar operand size for SQSHRUN")
        }
        switch v1.(type) {
            case HRegister: sa_va__bit_mask = 0b1111
            case SRegister: sa_va__bit_mask = 0b1110
            case DRegister: sa_va__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for SQSHRUN")
        }
        switch sa_vb {
            case 0b0001: sa_shift_1 = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift_1 = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift_1 = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for SQSHRUN")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_va & sa_va__bit_mask || sa_va & sa_va__bit_mask != sa_vb & sa_vb__bit_mask {
            panic("aarch64: invalid combination of operands for SQSHRUN")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 16, sa_n, sa_d))
    }
    // SQSHRUN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SQSHRUN")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQSHRUN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQSHRUN")
        }
        return p.setins(asimdshf(0, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 16, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQSHRUN")
}

// SQSHRUN2 instruction have one single form across one single category:
//
// 1. Signed saturating Shift Right Unsigned Narrow (immediate)
//
//    SQSHRUN2  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Signed saturating Shift Right Unsigned Narrow (immediate). This instruction
// reads each signed integer value in the vector of the source SIMD&FP register,
// right shifts each value by an immediate value, saturates the result to an
// unsigned integer value that is half the original width, places the final result
// into a vector, and writes the vector to the destination SIMD&FP register. The
// results are truncated. For rounded results, see SQRSHRUN .
//
// The SQSHRUN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQSHRUN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQSHRUN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQSHRUN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SQSHRUN2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SQSHRUN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQSHRUN2")
        }
        return p.setins(asimdshf(1, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 16, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SQSHRUN2")
}

// SQSUB instruction have 2 forms across one single category:
//
// 1. Signed saturating Subtract
//
//    SQSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SQSUB  <V><d>, <V><n>, <V><m>
//
// Signed saturating Subtract. This instruction subtracts the element values of the
// second source SIMD&FP register from the corresponding element values of the
// first source SIMD&FP register, places the results into a vector, and writes the
// vector to the destination SIMD&FP register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQSUB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SQSUB", 3, asm.Operands { v0, v1, v2 })
    // SQSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 5, sa_vn, sa_vd))
    }
    // SQSUB  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SQSUB")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 5, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQSUB")
}

// SQXTN instruction have 2 forms across one single category:
//
// 1. Signed saturating extract Narrow
//
//    SQXTN  <Vb><d>, <Va><n>
//    SQXTN  <Vd>.<Tb>, <Vn>.<Ta>
//
// Signed saturating extract Narrow. This instruction reads each vector element
// from the source SIMD&FP register, saturates the value to half the original
// width, places the result into a vector, and writes the vector to the lower or
// upper half of the destination SIMD&FP register. The destination vector elements
// are half as long as the source vector elements. All the values in this
// instruction are signed integer values.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQXTN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQXTN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQXTN(v0, v1 interface{}) *Instruction {
    p := self.alloc("SQXTN", 2, asm.Operands { v0, v1 })
    // SQXTN  <Vb><d>, <Va><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) {
        p.Domain = DomainAdvSimd
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_vb = 0b00
            case HRegister: sa_vb = 0b01
            case SRegister: sa_vb = 0b10
            default: panic("aarch64: invalid scalar operand size for SQXTN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_va = 0b00
            case SRegister: sa_va = 0b01
            case DRegister: sa_va = 0b10
            default: panic("aarch64: invalid scalar operand size for SQXTN")
        }
        if sa_va != sa_vb {
            panic("aarch64: invalid combination of operands for SQXTN")
        }
        return p.setins(asisdmisc(0, sa_va, 20, sa_n, sa_d))
    }
    // SQXTN  <Vd>.<Tb>, <Vn>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQXTN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQXTN")
        }
        return p.setins(asimdmisc(0, 0, sa_ta, 20, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQXTN")
}

// SQXTN2 instruction have one single form across one single category:
//
// 1. Signed saturating extract Narrow
//
//    SQXTN2  <Vd>.<Tb>, <Vn>.<Ta>
//
// Signed saturating extract Narrow. This instruction reads each vector element
// from the source SIMD&FP register, saturates the value to half the original
// width, places the result into a vector, and writes the vector to the lower or
// upper half of the destination SIMD&FP register. The destination vector elements
// are half as long as the source vector elements. All the values in this
// instruction are signed integer values.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQXTN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQXTN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQXTN2(v0, v1 interface{}) *Instruction {
    p := self.alloc("SQXTN2", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQXTN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQXTN2")
        }
        return p.setins(asimdmisc(1, 0, sa_ta, 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SQXTN2")
}

// SQXTUN instruction have 2 forms across one single category:
//
// 1. Signed saturating extract Unsigned Narrow
//
//    SQXTUN  <Vb><d>, <Va><n>
//    SQXTUN  <Vd>.<Tb>, <Vn>.<Ta>
//
// Signed saturating extract Unsigned Narrow. This instruction reads each signed
// integer value in the vector of the source SIMD&FP register, saturates the value
// to an unsigned integer value that is half the original width, places the result
// into a vector, and writes the vector to the lower or upper half of the
// destination SIMD&FP register. The destination vector elements are half as long
// as the source vector elements.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQXTUN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQXTUN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQXTUN(v0, v1 interface{}) *Instruction {
    p := self.alloc("SQXTUN", 2, asm.Operands { v0, v1 })
    // SQXTUN  <Vb><d>, <Va><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) {
        p.Domain = DomainAdvSimd
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_vb = 0b00
            case HRegister: sa_vb = 0b01
            case SRegister: sa_vb = 0b10
            default: panic("aarch64: invalid scalar operand size for SQXTUN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_va = 0b00
            case SRegister: sa_va = 0b01
            case DRegister: sa_va = 0b10
            default: panic("aarch64: invalid scalar operand size for SQXTUN")
        }
        if sa_va != sa_vb {
            panic("aarch64: invalid combination of operands for SQXTUN")
        }
        return p.setins(asisdmisc(1, sa_va, 18, sa_n, sa_d))
    }
    // SQXTUN  <Vd>.<Tb>, <Vn>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQXTUN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SQXTUN")
        }
        return p.setins(asimdmisc(0, 1, sa_ta, 18, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SQXTUN")
}

// SQXTUN2 instruction have one single form across one single category:
//
// 1. Signed saturating extract Unsigned Narrow
//
//    SQXTUN2  <Vd>.<Tb>, <Vn>.<Ta>
//
// Signed saturating extract Unsigned Narrow. This instruction reads each signed
// integer value in the vector of the source SIMD&FP register, saturates the value
// to an unsigned integer value that is half the original width, places the result
// into a vector, and writes the vector to the lower or upper half of the
// destination SIMD&FP register. The destination vector elements are half as long
// as the source vector elements.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The SQXTUN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SQXTUN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SQXTUN2(v0, v1 interface{}) *Instruction {
    p := self.alloc("SQXTUN2", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SQXTUN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SQXTUN2")
        }
        return p.setins(asimdmisc(1, 1, sa_ta, 18, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SQXTUN2")
}

// SRHADD instruction have one single form across one single category:
//
// 1. Signed Rounding Halving Add
//
//    SRHADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Signed Rounding Halving Add. This instruction adds corresponding signed integer
// values from the two source SIMD&FP registers, shifts each result right one bit,
// places the results into a vector, and writes the vector to the destination
// SIMD&FP register.
//
// The results are rounded. For truncated results, see SHADD .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SRHADD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SRHADD", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SRHADD")
}

// SRI instruction have 2 forms across one single category:
//
// 1. Shift Right and Insert (immediate)
//
//    SRI  <Vd>.<T>, <Vn>.<T>, #<shift>
//    SRI  <V><d>, <V><n>, #<shift>
//
// Shift Right and Insert (immediate). This instruction reads each vector element
// in the source SIMD&FP register, right shifts each vector element by an immediate
// value, and inserts the result into the corresponding vector element in the
// destination SIMD&FP register such that the new zero bits created by the shift
// are not inserted but retain their existing value. Bits shifted out of the right
// of each vector element of the source register are lost.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.sri_operation_shift_by_3.svg]
// shift right by 3 for an 8-bit vector element
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SRI(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SRI", 3, asm.Operands { v0, v1, v2 })
    // SRI  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            case 0b1000: sa_shift = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SRI")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SRI")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 8, sa_vn, sa_vd))
    }
    // SRI  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 1, 64) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SRI")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SRI")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for SRI")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SRI")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 8, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SRI")
}

// SRSHL instruction have 2 forms across one single category:
//
// 1. Signed Rounding Shift Left (register)
//
//    SRSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SRSHL  <V><d>, <V><n>, <V><m>
//
// Signed Rounding Shift Left (register). This instruction takes each signed
// integer value in the vector of the first source SIMD&FP register, shifts it by a
// value from the least significant byte of the corresponding element of the second
// source SIMD&FP register, places the results in a vector, and writes the vector
// to the destination SIMD&FP register.
//
// If the shift value is positive, the operation is a left shift. If the shift
// value is negative, it is a rounding right shift. For a truncating shift, see
// SSHL .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SRSHL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SRSHL", 3, asm.Operands { v0, v1, v2 })
    // SRSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 10, sa_vn, sa_vd))
    }
    // SRSHL  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SRSHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 10, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SRSHL")
}

// SRSHR instruction have 2 forms across one single category:
//
// 1. Signed Rounding Shift Right (immediate)
//
//    SRSHR  <Vd>.<T>, <Vn>.<T>, #<shift>
//    SRSHR  <V><d>, <V><n>, #<shift>
//
// Signed Rounding Shift Right (immediate). This instruction reads each vector
// element in the source SIMD&FP register, right shifts each result by an immediate
// value, places the final result into a vector, and writes the vector to the
// destination SIMD&FP register. All the values in this instruction are signed
// integer values. The results are rounded. For truncated results, see SSHR .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SRSHR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SRSHR", 3, asm.Operands { v0, v1, v2 })
    // SRSHR  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            case 0b1000: sa_shift = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SRSHR")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SRSHR")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 4, sa_vn, sa_vd))
    }
    // SRSHR  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 1, 64) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SRSHR")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SRSHR")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for SRSHR")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SRSHR")
        }
        return p.setins(asisdshf(0, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 4, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SRSHR")
}

// SRSRA instruction have 2 forms across one single category:
//
// 1. Signed Rounding Shift Right and Accumulate (immediate)
//
//    SRSRA  <Vd>.<T>, <Vn>.<T>, #<shift>
//    SRSRA  <V><d>, <V><n>, #<shift>
//
// Signed Rounding Shift Right and Accumulate (immediate). This instruction reads
// each vector element in the source SIMD&FP register, right shifts each result by
// an immediate value, and accumulates the final results with the vector elements
// of the destination SIMD&FP register. All the values in this instruction are
// signed integer values. The results are rounded. For truncated results, see SSRA
// .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SRSRA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SRSRA", 3, asm.Operands { v0, v1, v2 })
    // SRSRA  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            case 0b1000: sa_shift = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SRSRA")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SRSRA")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 6, sa_vn, sa_vd))
    }
    // SRSRA  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 1, 64) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SRSRA")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SRSRA")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for SRSRA")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SRSRA")
        }
        return p.setins(asisdshf(0, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 6, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SRSRA")
}

// SSBB instruction have one single form across one single category:
//
// 1. Speculative Store Bypass Barrier
//
//    SSBB
//
// Speculative Store Bypass Barrier is a memory barrier that prevents speculative
// loads from bypassing earlier stores to the same virtual address under certain
// conditions. For more information and details of the semantics, see Speculative
// Store Bypass Barrier (SSBB) .
//
func (self *Program) SSBB() *Instruction {
    p := self.alloc("SSBB", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(barriers(0, 4, 31))
}

// SSHL instruction have 2 forms across one single category:
//
// 1. Signed Shift Left (register)
//
//    SSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SSHL  <V><d>, <V><n>, <V><m>
//
// Signed Shift Left (register). This instruction takes each signed integer value
// in the vector of the first source SIMD&FP register, shifts each value by a value
// from the least significant byte of the corresponding element of the second
// source SIMD&FP register, places the results in a vector, and writes the vector
// to the destination SIMD&FP register.
//
// If the shift value is positive, the operation is a left shift. If the shift
// value is negative, it is a truncating right shift. For a rounding shift, see
// SRSHL .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SSHL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SSHL", 3, asm.Operands { v0, v1, v2 })
    // SSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), sa_vm, 8, sa_vn, sa_vd))
    }
    // SSHL  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SSHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(0, sa_v, sa_m, 8, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SSHL")
}

// SSHLL instruction have one single form across one single category:
//
// 1. Signed Shift Left Long (immediate)
//
//    SSHLL  <Vd>.<Ta>, <Vn>.<Tb>, #<shift>
//
// Signed Shift Left Long (immediate). This instruction reads each vector element
// from the source SIMD&FP register, left shifts each vector element by the
// specified shift amount, places the result into a vector, and writes the vector
// to the destination SIMD&FP register. The destination vector elements are twice
// as long as the source vector elements. All the values in this instruction are
// signed integer values.
//
// The SSHLL instruction extracts vector elements from the lower half of the source
// register. The SSHLL2 instruction extracts vector elements from the upper half of
// the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SSHLL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SSHLL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        switch sa_ta {
            case 0b0001: sa_shift = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift = uint32(asLit(v2)) + 32
            default: panic("aarch64: invalid operand 'sa_shift' for SSHLL")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SSHLL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SSHLL")
        }
        return p.setins(asimdshf(0, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SSHLL")
}

// SSHLL2 instruction have one single form across one single category:
//
// 1. Signed Shift Left Long (immediate)
//
//    SSHLL2  <Vd>.<Ta>, <Vn>.<Tb>, #<shift>
//
// Signed Shift Left Long (immediate). This instruction reads each vector element
// from the source SIMD&FP register, left shifts each vector element by the
// specified shift amount, places the result into a vector, and writes the vector
// to the destination SIMD&FP register. The destination vector elements are twice
// as long as the source vector elements. All the values in this instruction are
// signed integer values.
//
// The SSHLL instruction extracts vector elements from the lower half of the source
// register. The SSHLL2 instruction extracts vector elements from the upper half of
// the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SSHLL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SSHLL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        switch sa_ta {
            case 0b0001: sa_shift = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift = uint32(asLit(v2)) + 32
            default: panic("aarch64: invalid operand 'sa_shift' for SSHLL2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SSHLL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SSHLL2")
        }
        return p.setins(asimdshf(1, 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SSHLL2")
}

// SSHR instruction have 2 forms across one single category:
//
// 1. Signed Shift Right (immediate)
//
//    SSHR  <Vd>.<T>, <Vn>.<T>, #<shift>
//    SSHR  <V><d>, <V><n>, #<shift>
//
// Signed Shift Right (immediate). This instruction reads each vector element in
// the source SIMD&FP register, right shifts each result by an immediate value,
// places the final result into a vector, and writes the vector to the destination
// SIMD&FP register. All the values in this instruction are signed integer values.
// The results are truncated. For rounded results, see SRSHR .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SSHR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SSHR", 3, asm.Operands { v0, v1, v2 })
    // SSHR  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            case 0b1000: sa_shift = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SSHR")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SSHR")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 0, sa_vn, sa_vd))
    }
    // SSHR  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 1, 64) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SSHR")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SSHR")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for SSHR")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SSHR")
        }
        return p.setins(asisdshf(0, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 0, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SSHR")
}

// SSRA instruction have 2 forms across one single category:
//
// 1. Signed Shift Right and Accumulate (immediate)
//
//    SSRA  <Vd>.<T>, <Vn>.<T>, #<shift>
//    SSRA  <V><d>, <V><n>, #<shift>
//
// Signed Shift Right and Accumulate (immediate). This instruction reads each
// vector element in the source SIMD&FP register, right shifts each result by an
// immediate value, and accumulates the final results with the vector elements of
// the destination SIMD&FP register. All the values in this instruction are signed
// integer values. The results are truncated. For rounded results, see SRSRA .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SSRA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SSRA", 3, asm.Operands { v0, v1, v2 })
    // SSRA  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            case 0b1000: sa_shift = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for SSRA")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SSRA")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 0, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 2, sa_vn, sa_vd))
    }
    // SSRA  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 1, 64) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for SSRA")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for SSRA")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for SSRA")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for SSRA")
        }
        return p.setins(asisdshf(0, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 2, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SSRA")
}

// SSUBL instruction have one single form across one single category:
//
// 1. Signed Subtract Long
//
//    SSUBL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Subtract Long. This instruction subtracts each vector element in the
// lower or upper half of the second source SIMD&FP register from the corresponding
// vector element of the first source SIMD&FP register, places the results into a
// vector, and writes the vector to the destination SIMD&FP register. All the
// values in this instruction are signed integer values. The destination vector
// elements are twice as long as the source vector elements.
//
// The SSUBL instruction extracts each source vector from the lower half of each
// source register. The SSUBL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SSUBL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SSUBL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SSUBL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SSUBL")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SSUBL")
}

// SSUBL2 instruction have one single form across one single category:
//
// 1. Signed Subtract Long
//
//    SSUBL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Signed Subtract Long. This instruction subtracts each vector element in the
// lower or upper half of the second source SIMD&FP register from the corresponding
// vector element of the first source SIMD&FP register, places the results into a
// vector, and writes the vector to the destination SIMD&FP register. All the
// values in this instruction are signed integer values. The destination vector
// elements are twice as long as the source vector elements.
//
// The SSUBL instruction extracts each source vector from the lower half of each
// source register. The SSUBL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SSUBL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SSUBL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SSUBL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SSUBL2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SSUBL2")
}

// SSUBW instruction have one single form across one single category:
//
// 1. Signed Subtract Wide
//
//    SSUBW  <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>
//
// Signed Subtract Wide. This instruction subtracts each vector element in the
// lower or upper half of the second source SIMD&FP register from the corresponding
// vector element in the first source SIMD&FP register, places the result in a
// vector, and writes the vector to the SIMD&FP destination register. All the
// values in this instruction are signed integer values.
//
// The SSUBW instruction extracts the second source vector from the lower half of
// the second source register. The SSUBW2 instruction extracts the second source
// vector from the upper half of the second source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SSUBW(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SSUBW", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch vfmt(v2) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SSUBW")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SSUBW")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SSUBW")
}

// SSUBW2 instruction have one single form across one single category:
//
// 1. Signed Subtract Wide
//
//    SSUBW2  <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>
//
// Signed Subtract Wide. This instruction subtracts each vector element in the
// lower or upper half of the second source SIMD&FP register from the corresponding
// vector element in the first source SIMD&FP register, places the result in a
// vector, and writes the vector to the SIMD&FP destination register. All the
// values in this instruction are signed integer values.
//
// The SSUBW instruction extracts the second source vector from the lower half of
// the second source register. The SSUBW2 instruction extracts the second source
// vector from the upper half of the second source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SSUBW2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SSUBW2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch vfmt(v2) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SSUBW2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SSUBW2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SSUBW2")
}

// ST1 instruction have 24 forms across 2 categories:
//
// 1. Store multiple single-element structures from one, two, three, or four
//    registers
//
//    ST1  { <Vt>.<T> }, [<Xn|SP>]
//    ST1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
//    ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
//    ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
//    ST1  { <Vt>.<T> }, [<Xn|SP>], <imm>
//    ST1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
//    ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
//    ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
//    ST1  { <Vt>.<T> }, [<Xn|SP>], <Xm>
//    ST1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
//    ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
//    ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
//
// Store multiple single-element structures from one, two, three, or four
// registers. This instruction stores elements to memory from one, two, three, or
// four SIMD&FP registers, without interleaving. Every element of each register is
// stored.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Store a single-element structure from one lane of one register
//
//    ST1  { <Vt>.B }[<index>], [<Xn|SP>]
//    ST1  { <Vt>.D }[<index>], [<Xn|SP>]
//    ST1  { <Vt>.H }[<index>], [<Xn|SP>]
//    ST1  { <Vt>.S }[<index>], [<Xn|SP>]
//    ST1  { <Vt>.B }[<index>], [<Xn|SP>], #1
//    ST1  { <Vt>.B }[<index>], [<Xn|SP>], <Xm>
//    ST1  { <Vt>.D }[<index>], [<Xn|SP>], #8
//    ST1  { <Vt>.D }[<index>], [<Xn|SP>], <Xm>
//    ST1  { <Vt>.H }[<index>], [<Xn|SP>], #2
//    ST1  { <Vt>.H }[<index>], [<Xn|SP>], <Xm>
//    ST1  { <Vt>.S }[<index>], [<Xn|SP>], #4
//    ST1  { <Vt>.S }[<index>], [<Xn|SP>], <Xm>
//
// Store a single-element structure from one lane of one register. This instruction
// stores the specified element of a SIMD&FP register to memory.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ST1(v0, v1 interface{}) *Instruction {
    p := self.alloc("ST1", 2, asm.Operands { v0, v1 })
    // ST1  { <Vt>.<T> }, [<Xn|SP>]
    if isVec1(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 0, 7, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 0, 10, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 0, 6, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 0, 2, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T> }, [<Xn|SP>], <imm>
    if isVec1(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for ST1")
        }
        return p.setins(asisdlsep(sa_imm, 0, 31, 7, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm_1 := uint32(moffs(v1))
        if sa_imm_1 != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for ST1")
        }
        return p.setins(asisdlsep(sa_imm_1, 0, 31, 10, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm_2 := uint32(moffs(v1))
        if sa_imm_2 != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for ST1")
        }
        return p.setins(asisdlsep(sa_imm_2, 0, 31, 6, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm_3 := uint32(moffs(v1))
        if sa_imm_3 != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for ST1")
        }
        return p.setins(asisdlsep(sa_imm_3, 0, 31, 2, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T> }, [<Xn|SP>], <Xm>
    if isVec1(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 0, sa_xm, 7, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 0, sa_xm, 10, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 0, sa_xm, 6, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec1D: sa_t = 0b110
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST1")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 0, sa_xm, 2, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.B }[<index>], [<Xn|SP>]
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index, 3, 1),
            0,
            0,
            0,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST1  { <Vt>.D }[<index>], [<Xn|SP>]
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index_1, 0, 0, 0, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.H }[<index>], [<Xn|SP>]
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index_2, 3, 1),
            0,
            0,
            0,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST1  { <Vt>.S }[<index>], [<Xn|SP>]
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(ubfx(sa_index_3, 1, 1), 0, 0, 0, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.B }[<index>], [<Xn|SP>], #1
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 1 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            0,
            0,
            31,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST1  { <Vt>.B }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            0,
            0,
            sa_xm,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST1  { <Vt>.D }[<index>], [<Xn|SP>], #8
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 8 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 0, 0, 31, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.D }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 0, 0, sa_xm, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.H }[<index>], [<Xn|SP>], #2
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 2 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            0,
            0,
            31,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST1  { <Vt>.H }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            0,
            0,
            sa_xm,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST1  { <Vt>.S }[<index>], [<Xn|SP>], #4
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 4 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 0, 0, 31, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // ST1  { <Vt>.S }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 0, 0, sa_xm, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ST1")
}

// ST2 instruction have 15 forms across 2 categories:
//
// 1. Store multiple 2-element structures from two registers
//
//    ST2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
//    ST2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
//    ST2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
//
// Store multiple 2-element structures from two registers. This instruction stores
// multiple 2-element structures from two SIMD&FP registers to memory, with
// interleaving. Every element of each register is stored.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Store single 2-element structure from one lane of two registers
//
//    ST2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>]
//    ST2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>]
//    ST2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>]
//    ST2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>]
//    ST2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], #2
//    ST2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], <Xm>
//    ST2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], #16
//    ST2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], <Xm>
//    ST2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], #4
//    ST2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], <Xm>
//    ST2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], #8
//    ST2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], <Xm>
//
// Store single 2-element structure from one lane of two registers. This
// instruction stores a 2-element structure to memory from corresponding elements
// of two SIMD&FP registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ST2(v0, v1 interface{}) *Instruction {
    p := self.alloc("ST2", 2, asm.Operands { v0, v1 })
    // ST2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST2")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 0, 8, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST2")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for ST2")
        }
        return p.setins(asisdlsep(sa_imm, 0, 31, 8, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST2  { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>
    if isVec2(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST2")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 0, sa_xm, 8, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>]
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index, 3, 1),
            0,
            1,
            0,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>]
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index_1, 0, 1, 0, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>]
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index_2, 3, 1),
            0,
            1,
            0,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>]
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(ubfx(sa_index_3, 1, 1), 0, 1, 0, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // ST2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], #2
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 2 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            0,
            1,
            31,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST2  { <Vt>.B, <Vt2>.B }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            0,
            1,
            sa_xm,
            0,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], #16
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 16 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 0, 1, 31, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST2  { <Vt>.D, <Vt2>.D }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 0, 1, sa_xm, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], #4
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 4 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            0,
            1,
            31,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST2  { <Vt>.H, <Vt2>.H }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            0,
            1,
            sa_xm,
            2,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], #8
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 8 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 0, 1, 31, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // ST2  { <Vt>.S, <Vt2>.S }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec2(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 0, 1, sa_xm, 4, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ST2")
}

// ST2G instruction have 3 forms across one single category:
//
// 1. Store Allocation Tags
//
//    ST2G  <Xt|SP>, [<Xn|SP>{, #<simm>}]
//    ST2G  <Xt|SP>, [<Xn|SP>], #<simm>
//    ST2G  <Xt|SP>, [<Xn|SP>, #<simm>]!
//
// Store Allocation Tags stores an Allocation Tag to two Tag granules of memory.
// The address used for the store is calculated from the base register and an
// immediate signed offset scaled by the Tag granule. The Allocation Tag is
// calculated from the Logical Address Tag in the source register.
//
// This instruction generates an Unchecked access.
//
func (self *Program) ST2G(v0, v1 interface{}) *Instruction {
    p := self.alloc("ST2G", 2, asm.Operands { v0, v1 })
    // ST2G  <Xt|SP>, [<Xn|SP>{, #<simm>}]
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(2, sa_simm, 2, Rn, Rt))
    }
    // ST2G  <Xt|SP>, [<Xn|SP>], #<simm>
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == PostIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(2, sa_simm, 1, Rn, Rt))
    }
    // ST2G  <Xt|SP>, [<Xn|SP>, #<simm>]!
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == PreIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(2, sa_simm, 3, Rn, Rt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ST2G")
}

// ST3 instruction have 15 forms across 2 categories:
//
// 1. Store multiple 3-element structures from three registers
//
//    ST3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
//    ST3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
//    ST3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
//
// Store multiple 3-element structures from three registers. This instruction
// stores multiple 3-element structures to memory from three SIMD&FP registers,
// with interleaving. Every element of each register is stored.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Store single 3-element structure from one lane of three registers
//
//    ST3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>]
//    ST3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>]
//    ST3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>]
//    ST3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>]
//    ST3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], #3
//    ST3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], <Xm>
//    ST3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], #24
//    ST3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], <Xm>
//    ST3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], #6
//    ST3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], <Xm>
//    ST3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], #12
//    ST3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], <Xm>
//
// Store single 3-element structure from one lane of three registers. This
// instruction stores a 3-element structure to memory from corresponding elements
// of three SIMD&FP registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ST3(v0, v1 interface{}) *Instruction {
    p := self.alloc("ST3", 2, asm.Operands { v0, v1 })
    // ST3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST3")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 0, 4, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST3")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for ST3")
        }
        return p.setins(asisdlsep(sa_imm, 0, 31, 4, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST3  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>
    if isVec3(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST3")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 0, sa_xm, 4, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>]
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index, 3, 1),
            0,
            0,
            0,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>]
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index_1, 0, 0, 0, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>]
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index_2, 3, 1),
            0,
            0,
            0,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>]
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(ubfx(sa_index_3, 1, 1), 0, 0, 0, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // ST3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], #3
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 3 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            0,
            0,
            31,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST3  { <Vt>.B, <Vt2>.B, <Vt3>.B }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            0,
            0,
            sa_xm,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], #24
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 24 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 0, 0, 31, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST3  { <Vt>.D, <Vt2>.D, <Vt3>.D }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 0, 0, sa_xm, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], #6
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 6 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            0,
            0,
            31,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST3  { <Vt>.H, <Vt2>.H, <Vt3>.H }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            0,
            0,
            sa_xm,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], #12
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 12 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 0, 0, 31, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // ST3  { <Vt>.S, <Vt2>.S, <Vt3>.S }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec3(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 0, 0, sa_xm, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ST3")
}

// ST4 instruction have 15 forms across 2 categories:
//
// 1. Store multiple 4-element structures from four registers
//
//    ST4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
//    ST4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
//    ST4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
//
// Store multiple 4-element structures from four registers. This instruction stores
// multiple 4-element structures to memory from four SIMD&FP registers, with
// interleaving. Every element of each register is stored.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Store single 4-element structure from one lane of four registers
//
//    ST4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>]
//    ST4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>]
//    ST4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>]
//    ST4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>]
//    ST4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], #4
//    ST4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], <Xm>
//    ST4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], #32
//    ST4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], <Xm>
//    ST4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], #8
//    ST4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], <Xm>
//    ST4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], #16
//    ST4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], <Xm>
//
// Store single 4-element structure from one lane of four registers. This
// instruction stores a 4-element structure to memory from corresponding elements
// of four SIMD&FP registers.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ST4(v0, v1 interface{}) *Instruction {
    p := self.alloc("ST4", 2, asm.Operands { v0, v1 })
    // ST4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST4")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlse(mask(sa_t, 1), 0, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST4")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_imm := uint32(moffs(v1))
        if sa_imm != mask(sa_t, 1) {
            panic("aarch64: invalid combination of operands for ST4")
        }
        return p.setins(asisdlsep(sa_imm, 0, 31, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST4  { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>
    if isVec4(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isXr(midx(v1)) && mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vt := uint32(v0.(Vector).ID())
        switch velm(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: invalid vector arrangement for ST4")
        }
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsep(mask(sa_t, 1), 0, sa_xm, 0, ubfx(sa_t, 1, 2), sa_xn_sp, sa_vt))
    }
    // ST4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>]
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index, 3, 1),
            0,
            1,
            0,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>]
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index_1, 0, 1, 0, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>]
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(
            ubfx(sa_index_2, 3, 1),
            0,
            1,
            0,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>]
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(ubfx(sa_index_3, 1, 1), 0, 1, 0, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // ST4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], #4
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 4 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            0,
            1,
            31,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST4  { <Vt>.B, <Vt2>.B, <Vt3>.B, <Vt4>.B }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeB &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index, 3, 1),
            0,
            1,
            sa_xm,
            1,
            ubfx(sa_index, 2, 1),
            mask(sa_index, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], #32
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 32 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 0, 1, 31, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST4  { <Vt>.D, <Vt2>.D, <Vt3>.D, <Vt4>.D }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_1 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(sa_index_1, 0, 1, sa_xm, 5, 0, 1, sa_xn_sp, sa_vt))
    }
    // ST4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], #8
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 8 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            0,
            1,
            31,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST4  { <Vt>.H, <Vt2>.H, <Vt3>.H, <Vt4>.H }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeH &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_2 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(
            ubfx(sa_index_2, 3, 1),
            0,
            1,
            sa_xm,
            3,
            ubfx(sa_index_2, 2, 1),
            mask(sa_index_2, 2),
            sa_xn_sp,
            sa_vt,
        ))
    }
    // ST4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], #16
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 16 &&
       mext(v1) == PostIndex {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 0, 1, 31, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // ST4  { <Vt>.S, <Vt2>.S, <Vt3>.S, <Vt4>.S }[<index>], [<Xn|SP>], <Xm>
    if isIdxVec4(v0) &&
       vmodei(v0) == ModeS &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       mext(v1) == PostIndexReg {
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index_3 := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        return p.setins(asisdlsop(ubfx(sa_index_3, 1, 1), 0, 1, sa_xm, 5, mask(sa_index_3, 1), 0, sa_xn_sp, sa_vt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for ST4")
}

// ST64B instruction have one single form across one single category:
//
// 1. Single-copy Atomic 64-byte Store without Return
//
//    ST64B  <Xt>, [<Xn|SP> {,#0}]
//
// Single-copy Atomic 64-byte Store without Return stores eight 64-bit doublewords
// from consecutive registers, Xt to X(t+7) , to a memory location. The data that
// is stored is atomic and is required to be 64-byte-aligned.
//
func (self *Program) ST64B(v0, v1 interface{}) *Instruction {
    p := self.alloc("ST64B", 2, asm.Operands { v0, v1 })
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LS64)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, 31, 1, 1, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ST64B")
}

// ST64BV instruction have one single form across one single category:
//
// 1. Single-copy Atomic 64-byte Store with Return
//
//    ST64BV  <Xs>, <Xt>, [<Xn|SP>]
//
// Single-copy Atomic 64-byte Store with Return stores eight 64-bit doublewords
// from consecutive registers, Xt to X(t+7) , to a memory location, and writes the
// status result of the store to a register. The data that is stored is atomic and
// is required to be 64-byte aligned.
//
func (self *Program) ST64BV(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ST64BV", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LS64_V)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 1, 3, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ST64BV")
}

// ST64BV0 instruction have one single form across one single category:
//
// 1. Single-copy Atomic 64-byte EL0 Store with Return
//
//    ST64BV0  <Xs>, <Xt>, [<Xn|SP>]
//
// Single-copy Atomic 64-byte EL0 Store with Return stores eight 64-bit doublewords
// from consecutive registers, Xt to X(t+7) , to a memory location, with the bottom
// 32 bits taken from ACCDATA_EL1 , and writes the status result of the store to a
// register. The data that is stored is atomic and is required to be 64-byte
// aligned.
//
func (self *Program) ST64BV0(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ST64BV0", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LS64_ACCDATA)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 1, 2, sa_xn_sp, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ST64BV0")
}

// STADD instruction have 2 forms across one single category:
//
// 1. Atomic add on word or doubleword in memory, without return
//
//    STADD  <Ws>, [<Xn|SP>]
//    STADD  <Xs>, [<Xn|SP>]
//
// Atomic add on word or doubleword in memory, without return, atomically loads a
// 32-bit word or 64-bit doubleword from memory, adds the value held in a register
// to it, and stores the result back to memory.
//
//     * STADD does not have release semantics.
//     * STADDL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STADD(v0, v1 interface{}) *Instruction {
    p := self.alloc("STADD", 2, asm.Operands { v0, v1 })
    // STADD  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 0, sa_xn_sp, 31))
    }
    // STADD  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 0, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STADD")
}

// STADDB instruction have one single form across one single category:
//
// 1. Atomic add on byte in memory, without return
//
//    STADDB  <Ws>, [<Xn|SP>]
//
// Atomic add on byte in memory, without return, atomically loads an 8-bit byte
// from memory, adds the value held in a register to it, and stores the result back
// to memory.
//
//     * STADDB does not have release semantics.
//     * STADDLB stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STADDB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STADDB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 0, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STADDB")
}

// STADDH instruction have one single form across one single category:
//
// 1. Atomic add on halfword in memory, without return
//
//    STADDH  <Ws>, [<Xn|SP>]
//
// Atomic add on halfword in memory, without return, atomically loads a 16-bit
// halfword from memory, adds the value held in a register to it, and stores the
// result back to memory.
//
//     * STADDH does not have release semantics.
//     * STADDLH stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STADDH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STADDH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 0, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STADDH")
}

// STADDL instruction have 2 forms across one single category:
//
// 1. Atomic add on word or doubleword in memory, without return
//
//    STADDL  <Ws>, [<Xn|SP>]
//    STADDL  <Xs>, [<Xn|SP>]
//
// Atomic add on word or doubleword in memory, without return, atomically loads a
// 32-bit word or 64-bit doubleword from memory, adds the value held in a register
// to it, and stores the result back to memory.
//
//     * STADD does not have release semantics.
//     * STADDL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STADDL(v0, v1 interface{}) *Instruction {
    p := self.alloc("STADDL", 2, asm.Operands { v0, v1 })
    // STADDL  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 0, sa_xn_sp, 31))
    }
    // STADDL  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 0, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STADDL")
}

// STADDLB instruction have one single form across one single category:
//
// 1. Atomic add on byte in memory, without return
//
//    STADDLB  <Ws>, [<Xn|SP>]
//
// Atomic add on byte in memory, without return, atomically loads an 8-bit byte
// from memory, adds the value held in a register to it, and stores the result back
// to memory.
//
//     * STADDB does not have release semantics.
//     * STADDLB stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STADDLB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STADDLB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 0, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STADDLB")
}

// STADDLH instruction have one single form across one single category:
//
// 1. Atomic add on halfword in memory, without return
//
//    STADDLH  <Ws>, [<Xn|SP>]
//
// Atomic add on halfword in memory, without return, atomically loads a 16-bit
// halfword from memory, adds the value held in a register to it, and stores the
// result back to memory.
//
//     * STADDH does not have release semantics.
//     * STADDLH stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STADDLH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STADDLH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 0, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STADDLH")
}

// STCLR instruction have 2 forms across one single category:
//
// 1. Atomic bit clear on word or doubleword in memory, without return
//
//    STCLR  <Ws>, [<Xn|SP>]
//    STCLR  <Xs>, [<Xn|SP>]
//
// Atomic bit clear on word or doubleword in memory, without return, atomically
// loads a 32-bit word or 64-bit doubleword from memory, performs a bitwise AND
// with the complement of the value held in a register on it, and stores the result
// back to memory.
//
//     * STCLR does not have release semantics.
//     * STCLRL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STCLR(v0, v1 interface{}) *Instruction {
    p := self.alloc("STCLR", 2, asm.Operands { v0, v1 })
    // STCLR  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 1, sa_xn_sp, 31))
    }
    // STCLR  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 1, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STCLR")
}

// STCLRB instruction have one single form across one single category:
//
// 1. Atomic bit clear on byte in memory, without return
//
//    STCLRB  <Ws>, [<Xn|SP>]
//
// Atomic bit clear on byte in memory, without return, atomically loads an 8-bit
// byte from memory, performs a bitwise AND with the complement of the value held
// in a register on it, and stores the result back to memory.
//
//     * STCLRB does not have release semantics.
//     * STCLRLB stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STCLRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STCLRB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 1, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STCLRB")
}

// STCLRH instruction have one single form across one single category:
//
// 1. Atomic bit clear on halfword in memory, without return
//
//    STCLRH  <Ws>, [<Xn|SP>]
//
// Atomic bit clear on halfword in memory, without return, atomically loads a
// 16-bit halfword from memory, performs a bitwise AND with the complement of the
// value held in a register on it, and stores the result back to memory.
//
//     * STCLRH does not have release semantics.
//     * STCLRLH stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STCLRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STCLRH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 1, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STCLRH")
}

// STCLRL instruction have 2 forms across one single category:
//
// 1. Atomic bit clear on word or doubleword in memory, without return
//
//    STCLRL  <Ws>, [<Xn|SP>]
//    STCLRL  <Xs>, [<Xn|SP>]
//
// Atomic bit clear on word or doubleword in memory, without return, atomically
// loads a 32-bit word or 64-bit doubleword from memory, performs a bitwise AND
// with the complement of the value held in a register on it, and stores the result
// back to memory.
//
//     * STCLR does not have release semantics.
//     * STCLRL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STCLRL(v0, v1 interface{}) *Instruction {
    p := self.alloc("STCLRL", 2, asm.Operands { v0, v1 })
    // STCLRL  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 1, sa_xn_sp, 31))
    }
    // STCLRL  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 1, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STCLRL")
}

// STCLRLB instruction have one single form across one single category:
//
// 1. Atomic bit clear on byte in memory, without return
//
//    STCLRLB  <Ws>, [<Xn|SP>]
//
// Atomic bit clear on byte in memory, without return, atomically loads an 8-bit
// byte from memory, performs a bitwise AND with the complement of the value held
// in a register on it, and stores the result back to memory.
//
//     * STCLRB does not have release semantics.
//     * STCLRLB stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STCLRLB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STCLRLB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 1, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STCLRLB")
}

// STCLRLH instruction have one single form across one single category:
//
// 1. Atomic bit clear on halfword in memory, without return
//
//    STCLRLH  <Ws>, [<Xn|SP>]
//
// Atomic bit clear on halfword in memory, without return, atomically loads a
// 16-bit halfword from memory, performs a bitwise AND with the complement of the
// value held in a register on it, and stores the result back to memory.
//
//     * STCLRH does not have release semantics.
//     * STCLRLH stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STCLRLH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STCLRLH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 1, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STCLRLH")
}

// STEOR instruction have 2 forms across one single category:
//
// 1. Atomic Exclusive-OR on word or doubleword in memory, without return
//
//    STEOR  <Ws>, [<Xn|SP>]
//    STEOR  <Xs>, [<Xn|SP>]
//
// Atomic Exclusive-OR on word or doubleword in memory, without return, atomically
// loads a 32-bit word or 64-bit doubleword from memory, performs an exclusive-OR
// with the value held in a register on it, and stores the result back to memory.
//
//     * STEOR does not have release semantics.
//     * STEORL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STEOR(v0, v1 interface{}) *Instruction {
    p := self.alloc("STEOR", 2, asm.Operands { v0, v1 })
    // STEOR  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 2, sa_xn_sp, 31))
    }
    // STEOR  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 2, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STEOR")
}

// STEORB instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on byte in memory, without return
//
//    STEORB  <Ws>, [<Xn|SP>]
//
// Atomic Exclusive-OR on byte in memory, without return, atomically loads an 8-bit
// byte from memory, performs an exclusive-OR with the value held in a register on
// it, and stores the result back to memory.
//
//     * STEORB does not have release semantics.
//     * STEORLB stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STEORB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STEORB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 2, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STEORB")
}

// STEORH instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on halfword in memory, without return
//
//    STEORH  <Ws>, [<Xn|SP>]
//
// Atomic Exclusive-OR on halfword in memory, without return, atomically loads a
// 16-bit halfword from memory, performs an exclusive-OR with the value held in a
// register on it, and stores the result back to memory.
//
//     * STEORH does not have release semantics.
//     * STEORLH stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STEORH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STEORH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 2, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STEORH")
}

// STEORL instruction have 2 forms across one single category:
//
// 1. Atomic Exclusive-OR on word or doubleword in memory, without return
//
//    STEORL  <Ws>, [<Xn|SP>]
//    STEORL  <Xs>, [<Xn|SP>]
//
// Atomic Exclusive-OR on word or doubleword in memory, without return, atomically
// loads a 32-bit word or 64-bit doubleword from memory, performs an exclusive-OR
// with the value held in a register on it, and stores the result back to memory.
//
//     * STEOR does not have release semantics.
//     * STEORL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STEORL(v0, v1 interface{}) *Instruction {
    p := self.alloc("STEORL", 2, asm.Operands { v0, v1 })
    // STEORL  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 2, sa_xn_sp, 31))
    }
    // STEORL  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 2, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STEORL")
}

// STEORLB instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on byte in memory, without return
//
//    STEORLB  <Ws>, [<Xn|SP>]
//
// Atomic Exclusive-OR on byte in memory, without return, atomically loads an 8-bit
// byte from memory, performs an exclusive-OR with the value held in a register on
// it, and stores the result back to memory.
//
//     * STEORB does not have release semantics.
//     * STEORLB stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STEORLB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STEORLB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 2, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STEORLB")
}

// STEORLH instruction have one single form across one single category:
//
// 1. Atomic Exclusive-OR on halfword in memory, without return
//
//    STEORLH  <Ws>, [<Xn|SP>]
//
// Atomic Exclusive-OR on halfword in memory, without return, atomically loads a
// 16-bit halfword from memory, performs an exclusive-OR with the value held in a
// register on it, and stores the result back to memory.
//
//     * STEORH does not have release semantics.
//     * STEORLH stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STEORLH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STEORLH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 2, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STEORLH")
}

// STG instruction have 3 forms across one single category:
//
// 1. Store Allocation Tag
//
//    STG  <Xt|SP>, [<Xn|SP>{, #<simm>}]
//    STG  <Xt|SP>, [<Xn|SP>], #<simm>
//    STG  <Xt|SP>, [<Xn|SP>, #<simm>]!
//
// Store Allocation Tag stores an Allocation Tag to memory. The address used for
// the store is calculated from the base register and an immediate signed offset
// scaled by the Tag granule. The Allocation Tag is calculated from the Logical
// Address Tag in the source register.
//
// This instruction generates an Unchecked access.
//
func (self *Program) STG(v0, v1 interface{}) *Instruction {
    p := self.alloc("STG", 2, asm.Operands { v0, v1 })
    // STG  <Xt|SP>, [<Xn|SP>{, #<simm>}]
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(0, sa_simm, 2, Rn, Rt))
    }
    // STG  <Xt|SP>, [<Xn|SP>], #<simm>
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == PostIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(0, sa_simm, 1, Rn, Rt))
    }
    // STG  <Xt|SP>, [<Xn|SP>, #<simm>]!
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == PreIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(0, sa_simm, 3, Rn, Rt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STG")
}

// STGM instruction have one single form across one single category:
//
// 1. Store Tag Multiple
//
//    STGM  <Xt>, [<Xn|SP>]
//
// Store Tag Multiple writes a naturally aligned block of N Allocation Tags, where
// the size of N is identified in GMID_EL1.BS, and the Allocation Tag written to
// address A is taken from the source register at 4*A<7:4>+3:4*A<7:4>.
//
// This instruction is undefined at EL0.
//
// This instruction generates an Unchecked access.
//
func (self *Program) STGM(v0, v1 interface{}) *Instruction {
    p := self.alloc("STGM", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_MTE2)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt
        return p.setins(ldsttags(2, 0, 0, Rn, Rt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STGM")
}

// STGP instruction have 3 forms across one single category:
//
// 1. Store Allocation Tag and Pair of registers
//
//    STGP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
//    STGP  <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
//    STGP  <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
//
// Store Allocation Tag and Pair of registers stores an Allocation Tag and two
// 64-bit doublewords to memory, from two registers. The address used for the store
// is calculated from the base register and an immediate signed offset scaled by
// the Tag granule. The Allocation Tag is calculated from the Logical Address Tag
// in the base register.
//
// This instruction generates an Unchecked access.
//
func (self *Program) STGP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STGP", 3, asm.Operands { v0, v1, v2 })
    // STGP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2))
        imm7 := uint32(0b0000000)
        imm7 |= sa_imm
        Rt2 := uint32(0b00000)
        Rt2 |= sa_xt2
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt1
        return p.setins(ldstpair_off(1, 0, 0, imm7, Rt2, Rn, Rt))
    }
    // STGP  <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == PostIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2))
        imm7 := uint32(0b0000000)
        imm7 |= sa_imm_1
        Rt2 := uint32(0b00000)
        Rt2 |= sa_xt2
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt1
        return p.setins(ldstpair_post(1, 0, 0, imm7, Rt2, Rn, Rt))
    }
    // STGP  <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == PreIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2))
        imm7 := uint32(0b0000000)
        imm7 |= sa_imm_1
        Rt2 := uint32(0b00000)
        Rt2 |= sa_xt2
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt1
        return p.setins(ldstpair_pre(1, 0, 0, imm7, Rt2, Rn, Rt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STGP")
}

// STILP instruction have 4 forms across one single category:
//
// 1. Store-Release ordered Pair of registers
//
//    STILP  <Wt1>, <Wt2>, [<Xn|SP>, #-8]!
//    STILP  <Wt1>, <Wt2>, [<Xn|SP>]
//    STILP  <Xt1>, <Xt2>, [<Xn|SP>, #-16]!
//    STILP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Store-Release ordered Pair of registers calculates an address from a base
// register value and an optional offset, and stores two 32-bit words or two 64-bit
// doublewords to the calculated address, from two registers. For information on
// single-copy atomicity and alignment requirements, see Requirements for single-
// copy atomicity and Alignment of data accesses . The instruction also has memory
// ordering semantics, as described in Load-Acquire, Load-AcquirePC, and Store-
// Release , with the additional requirement that:
//
//     * When using the pre-index addressing mode, the Memory effects
//       associated with Xt2/Wt2 are Ordered-before the Memory effects
//       associated with Xt1/Wt1.
//     * For all other addressing modes, the Memory effects associated with
//       Xt1/Wt1 are Ordered-before the Memory effects associated with Xt2/Wt2.
//
// For information about memory accesses, see Load/Store addressing modes .
//
// STILP has the same constrained unpredictable behavior as STP . For information
// about this constrained unpredictable behavior, see Architectural Constraints on
// UNPREDICTABLE behaviors , and particularly STP .
//
func (self *Program) STILP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STILP", 3, asm.Operands { v0, v1, v2 })
    // STILP  <Wt1>, <Wt2>, [<Xn|SP>, #-8]!
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == -8 &&
       mext(v2) == PreIndex {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldiappstilp(2, 0, sa_wt2, 0, sa_xn_sp, sa_wt1))
    }
    // STILP  <Wt1>, <Wt2>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldiappstilp(2, 0, sa_wt2, 1, sa_xn_sp, sa_wt1))
    }
    // STILP  <Xt1>, <Xt2>, [<Xn|SP>, #-16]!
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == -16 &&
       mext(v2) == PreIndex {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldiappstilp(3, 0, sa_xt2, 0, sa_xn_sp, sa_xt1))
    }
    // STILP  <Xt1>, <Xt2>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldiappstilp(3, 0, sa_xt2, 1, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STILP")
}

// STL1 instruction have one single form across one single category:
//
// 1. Store-Release a single-element structure from one lane of one register
//
//    STL1  { <Vt>.D }[<index>], [<Xn|SP>]
//
// Store-Release a single-element structure from one lane of one register. This
// instruction stores the specified element of a SIMD&FP register to memory.
//
// The instruction also has memory ordering semantics, as described in Load-
// Acquire, Load-AcquirePC, and Store-Release . For information about memory
// accesses, see Load/Store addressing modes .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) STL1(v0, v1 interface{}) *Instruction {
    p := self.alloc("STL1", 2, asm.Operands { v0, v1 })
    if isIdxVec1(v0) &&
       vmodei(v0) == ModeD &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       moffs(v1) == 0 &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainAdvSimd
        sa_vt := uint32(v0.(IndexedVector).ID())
        sa_index := uint32(v0.(IndexedVector).Index())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(asisdlso(sa_index, 0, 0, 1, 4, 0, 1, sa_xn_sp, sa_vt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STL1")
}

// STLLR instruction have 2 forms across one single category:
//
// 1. Store LORelease Register
//
//    STLLR  <Wt>, [<Xn|SP>{,#0}]
//    STLLR  <Xt>, [<Xn|SP>{,#0}]
//
// Store LORelease Register stores a 32-bit word or a 64-bit doubleword to a memory
// location, from a register. The instruction also has memory ordering semantics as
// described in Load LOAcquire, Store LORelease . For information about memory
// accesses, see Load/Store addressing modes .
//
func (self *Program) STLLR(v0, v1 interface{}) *Instruction {
    p := self.alloc("STLLR", 2, asm.Operands { v0, v1 })
    // STLLR  <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LOR)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(2, 0, 31, 0, 31, sa_xn_sp, sa_wt))
    }
    // STLLR  <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LOR)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(3, 0, 31, 0, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STLLR")
}

// STLLRB instruction have one single form across one single category:
//
// 1. Store LORelease Register Byte
//
//    STLLRB  <Wt>, [<Xn|SP>{,#0}]
//
// Store LORelease Register Byte stores a byte from a 32-bit register to a memory
// location. The instruction also has memory ordering semantics as described in
// Load LOAcquire, Store LORelease . For information about memory accesses, see
// Load/Store addressing modes .
//
func (self *Program) STLLRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STLLRB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LOR)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(0, 0, 31, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STLLRB")
}

// STLLRH instruction have one single form across one single category:
//
// 1. Store LORelease Register Halfword
//
//    STLLRH  <Wt>, [<Xn|SP>{,#0}]
//
// Store LORelease Register Halfword stores a halfword from a 32-bit register to a
// memory location. The instruction also has memory ordering semantics as described
// in Load LOAcquire, Store LORelease . For information about memory accesses, see
// Load/Store addressing modes .
//
func (self *Program) STLLRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STLLRH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LOR)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(1, 0, 31, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STLLRH")
}

// STLR instruction have 4 forms across one single category:
//
// 1. Store-Release Register
//
//    STLR  <Wt>, [<Xn|SP>, #-4]!
//    STLR  <Xt>, [<Xn|SP>, #-8]!
//    STLR  <Wt>, [<Xn|SP>{,#0}]
//    STLR  <Xt>, [<Xn|SP>{,#0}]
//
// Store-Release Register stores a 32-bit word or a 64-bit doubleword to a memory
// location, from a register. The instruction also has memory ordering semantics as
// described in Load-Acquire, Store-Release . For information about memory
// accesses, see Load/Store addressing modes .
//
func (self *Program) STLR(v0, v1 interface{}) *Instruction {
    p := self.alloc("STLR", 2, asm.Operands { v0, v1 })
    // STLR  <Wt>, [<Xn|SP>, #-4]!
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == -4 && mext(v1) == PreIndex {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldapstl_writeback(2, 0, sa_xn_sp, sa_wt))
    }
    // STLR  <Xt>, [<Xn|SP>, #-8]!
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == -8 && mext(v1) == PreIndex {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldapstl_writeback(3, 0, sa_xn_sp, sa_xt))
    }
    // STLR  <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(2, 0, 31, 1, 31, sa_xn_sp, sa_wt))
    }
    // STLR  <Xt>, [<Xn|SP>{,#0}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(3, 0, 31, 1, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STLR")
}

// STLRB instruction have one single form across one single category:
//
// 1. Store-Release Register Byte
//
//    STLRB  <Wt>, [<Xn|SP>{,#0}]
//
// Store-Release Register Byte stores a byte from a 32-bit register to a memory
// location. The instruction also has memory ordering semantics as described in
// Load-Acquire, Store-Release . For information about memory accesses, see
// Load/Store addressing modes .
//
func (self *Program) STLRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STLRB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(0, 0, 31, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STLRB")
}

// STLRH instruction have one single form across one single category:
//
// 1. Store-Release Register Halfword
//
//    STLRH  <Wt>, [<Xn|SP>{,#0}]
//
// Store-Release Register Halfword stores a halfword from a 32-bit register to a
// memory location. The instruction also has memory ordering semantics as described
// in Load-Acquire, Store-Release . For information about memory accesses, see
// Load/Store addressing modes .
//
func (self *Program) STLRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STLRH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       (moffs(v1) == 0 || moffs(v1) == 0) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(ldstord(1, 0, 31, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STLRH")
}

// STLUR instruction have 7 forms across 2 categories:
//
// 1. Store-Release SIMD&FP Register (unscaled offset)
//
//    STLUR  <Bt>, [<Xn|SP>{, #<simm>}]
//    STLUR  <Dt>, [<Xn|SP>{, #<simm>}]
//    STLUR  <Ht>, [<Xn|SP>{, #<simm>}]
//    STLUR  <Qt>, [<Xn|SP>{, #<simm>}]
//    STLUR  <St>, [<Xn|SP>{, #<simm>}]
//
// Store-Release SIMD&FP Register (unscaled offset). This instruction stores a
// single SIMD&FP register to memory. The address that is used for the store is
// calculated from a base register value and an optional immediate offset.
//
// The instruction has memory ordering semantics, as described in Load-Acquire,
// Load-AcquirePC, and Store-Release .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Store-Release Register (unscaled)
//
//    STLUR  <Wt>, [<Xn|SP>{, #<simm>}]
//    STLUR  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Store-Release Register (unscaled) calculates an address from a base register
// value and an immediate offset, and stores a 32-bit word or a 64-bit doubleword
// to the calculated address, from a register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STLUR(v0, v1 interface{}) *Instruction {
    p := self.alloc("STLUR", 2, asm.Operands { v0, v1 })
    // STLUR  <Bt>, [<Xn|SP>{, #<simm>}]
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(0, 0, sa_simm, sa_xn_sp, sa_bt))
    }
    // STLUR  <Dt>, [<Xn|SP>{, #<simm>}]
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(3, 0, sa_simm, sa_xn_sp, sa_dt))
    }
    // STLUR  <Ht>, [<Xn|SP>{, #<simm>}]
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(1, 0, sa_simm, sa_xn_sp, sa_ht))
    }
    // STLUR  <Qt>, [<Xn|SP>{, #<simm>}]
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(0, 2, sa_simm, sa_xn_sp, sa_qt))
    }
    // STLUR  <St>, [<Xn|SP>{, #<simm>}]
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC3)
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_simd(2, 0, sa_simm, sa_xn_sp, sa_st))
    }
    // STLUR  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(2, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    // STLUR  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(3, 0, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STLUR")
}

// STLURB instruction have one single form across one single category:
//
// 1. Store-Release Register Byte (unscaled)
//
//    STLURB  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Store-Release Register Byte (unscaled) calculates an address from a base
// register value and an immediate offset, and stores a byte to the calculated
// address, from a 32-bit register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STLURB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STLURB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STLURB")
}

// STLURH instruction have one single form across one single category:
//
// 1. Store-Release Register Halfword (unscaled)
//
//    STLURH  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Store-Release Register Halfword (unscaled) calculates an address from a base
// register value and an immediate offset, and stores a halfword to the calculated
// address, from a 32-bit register.
//
// The instruction has memory ordering semantics as described in Load-Acquire,
// Load-AcquirePC, and Store-Release
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STLURH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STLURH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_LRCPC2)
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldapstl_unscaled(1, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STLURH")
}

// STLXP instruction have 2 forms across one single category:
//
// 1. Store-Release Exclusive Pair of registers
//
//    STLXP  <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]
//    STLXP  <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]
//
// Store-Release Exclusive Pair of registers stores two 32-bit words or two 64-bit
// doublewords to a memory location if the PE has exclusive access to the memory
// address, from two registers, and returns a status value of 0 if the store was
// successful, or of 1 if no store was performed. See Synchronization and
// semaphores . For information on single-copy atomicity and alignment
// requirements, see Requirements for single-copy atomicity and Alignment of data
// accesses . If a 64-bit pair Store-Exclusive succeeds, it causes a single-copy
// atomic update of the 128-bit memory location being updated. The instruction also
// has memory ordering semantics, as described in Load-Acquire, Store-Release . For
// information about memory accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STLXP .
//
func (self *Program) STLXP(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("STLXP", 4, asm.Operands { v0, v1, v2, v3 })
    // STLXP  <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       isMem(v3) &&
       isXrOrSP(mbase(v3)) &&
       midx(v3) == nil &&
       (moffs(v3) == 0 || moffs(v3) == 0) &&
       mext(v3) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt1 := uint32(v1.(asm.Register).ID())
        sa_wt2 := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v3).ID())
        return p.setins(ldstexclp(0, 0, sa_ws, 1, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // STLXP  <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       isMem(v3) &&
       isXrOrSP(mbase(v3)) &&
       midx(v3) == nil &&
       (moffs(v3) == 0 || moffs(v3) == 0) &&
       mext(v3) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xt1 := uint32(v1.(asm.Register).ID())
        sa_xt2 := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v3).ID())
        return p.setins(ldstexclp(1, 0, sa_ws, 1, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STLXP")
}

// STLXR instruction have 2 forms across one single category:
//
// 1. Store-Release Exclusive Register
//
//    STLXR  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//    STLXR  <Ws>, <Xt>, [<Xn|SP>{,#0}]
//
// Store-Release Exclusive Register stores a 32-bit word or a 64-bit doubleword to
// memory if the PE has exclusive access to the memory address, from two registers,
// and returns a status value of 0 if the store was successful, or of 1 if no store
// was performed. See Synchronization and semaphores . The memory access is atomic.
// The instruction also has memory ordering semantics as described in Load-Acquire,
// Store-Release . For information about memory accesses, see Load/Store addressing
// modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STLXR .
//
func (self *Program) STLXR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STLXR", 3, asm.Operands { v0, v1, v2 })
    // STLXR  <Ws>, <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclr(2, 0, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    // STLXR  <Ws>, <Xt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclr(3, 0, sa_ws, 1, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STLXR")
}

// STLXRB instruction have one single form across one single category:
//
// 1. Store-Release Exclusive Register Byte
//
//    STLXRB  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Store-Release Exclusive Register Byte stores a byte from a 32-bit register to
// memory if the PE has exclusive access to the memory address, and returns a
// status value of 0 if the store was successful, or of 1 if no store was
// performed. See Synchronization and semaphores . The memory access is atomic. The
// instruction also has memory ordering semantics as described in Load-Acquire,
// Store-Release . For information about memory accesses, see Load/Store addressing
// modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STLXRB .
//
func (self *Program) STLXRB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STLXRB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclr(0, 0, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STLXRB")
}

// STLXRH instruction have one single form across one single category:
//
// 1. Store-Release Exclusive Register Halfword
//
//    STLXRH  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Store-Release Exclusive Register Halfword stores a halfword from a 32-bit
// register to memory if the PE has exclusive access to the memory address, and
// returns a status value of 0 if the store was successful, or of 1 if no store was
// performed. See Synchronization and semaphores . The memory access is atomic. The
// instruction also has memory ordering semantics as described in Load-Acquire,
// Store-Release . For information about memory accesses, see Load/Store addressing
// modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STLXRH .
//
func (self *Program) STLXRH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STLXRH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclr(1, 0, sa_ws, 1, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STLXRH")
}

// STNP instruction have 5 forms across 2 categories:
//
// 1. Store Pair of SIMD&FP registers, with Non-temporal hint
//
//    STNP  <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]
//    STNP  <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]
//    STNP  <St1>, <St2>, [<Xn|SP>{, #<imm>}]
//
// Store Pair of SIMD&FP registers, with Non-temporal hint. This instruction stores
// a pair of SIMD&FP registers to memory, issuing a hint to the memory system that
// the access is non-temporal. The address used for the store is calculated from an
// address from a base register value and an immediate offset. For information
// about non-temporal pair instructions, see Load/Store SIMD and Floating-point
// Non-temporal pair .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Store Pair of Registers, with non-temporal hint
//
//    STNP  <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]
//    STNP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
//
// Store Pair of Registers, with non-temporal hint, calculates an address from a
// base register value and an immediate offset, and stores two 32-bit words or two
// 64-bit doublewords to the calculated address, from two registers. For
// information about memory accesses, see Load/Store addressing modes . For
// information about Non-temporal pair instructions, see Load/Store Non-temporal
// pair .
//
func (self *Program) STNP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STNP", 3, asm.Operands { v0, v1, v2 })
    // STNP  <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]
    if isDr(v0) &&
       isDr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_dt1 := uint32(v0.(asm.Register).ID())
        sa_dt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2) / 8)
        return p.setins(ldstnapair_offs(1, 1, 0, sa_imm, sa_dt2, sa_xn_sp, sa_dt1))
    }
    // STNP  <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]
    if isQr(v0) &&
       isQr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_qt1 := uint32(v0.(asm.Register).ID())
        sa_qt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 16)
        return p.setins(ldstnapair_offs(2, 1, 0, sa_imm_1, sa_qt2, sa_xn_sp, sa_qt1))
    }
    // STNP  <St1>, <St2>, [<Xn|SP>{, #<imm>}]
    if isSr(v0) &&
       isSr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_st1 := uint32(v0.(asm.Register).ID())
        sa_st2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_2 := uint32(moffs(v2) / 4)
        return p.setins(ldstnapair_offs(0, 1, 0, sa_imm_2, sa_st2, sa_xn_sp, sa_st1))
    }
    // STNP  <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2) / 4)
        return p.setins(ldstnapair_offs(0, 0, 0, sa_imm, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // STNP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 8)
        return p.setins(ldstnapair_offs(2, 0, 0, sa_imm_1, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STNP")
}

// STP instruction have 15 forms across 2 categories:
//
// 1. Store Pair of SIMD&FP registers
//
//    STP  <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]
//    STP  <Dt1>, <Dt2>, [<Xn|SP>], #<imm>
//    STP  <Dt1>, <Dt2>, [<Xn|SP>, #<imm>]!
//    STP  <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]
//    STP  <Qt1>, <Qt2>, [<Xn|SP>], #<imm>
//    STP  <Qt1>, <Qt2>, [<Xn|SP>, #<imm>]!
//    STP  <St1>, <St2>, [<Xn|SP>{, #<imm>}]
//    STP  <St1>, <St2>, [<Xn|SP>], #<imm>
//    STP  <St1>, <St2>, [<Xn|SP>, #<imm>]!
//
// Store Pair of SIMD&FP registers. This instruction stores a pair of SIMD&FP
// registers to memory. The address used for the store is calculated from a base
// register value and an immediate offset.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Store Pair of Registers
//
//    STP  <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]
//    STP  <Wt1>, <Wt2>, [<Xn|SP>], #<imm>
//    STP  <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!
//    STP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
//    STP  <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
//    STP  <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
//
// Store Pair of Registers calculates an address from a base register value and an
// immediate offset, and stores two 32-bit words or two 64-bit doublewords to the
// calculated address, from two registers. For information about memory accesses,
// see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STP .
//
func (self *Program) STP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STP", 3, asm.Operands { v0, v1, v2 })
    // STP  <Dt1>, <Dt2>, [<Xn|SP>{, #<imm>}]
    if isDr(v0) &&
       isDr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_dt1 := uint32(v0.(asm.Register).ID())
        sa_dt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_off(1, 1, 0, sa_imm, sa_dt2, sa_xn_sp, sa_dt1))
    }
    // STP  <Dt1>, <Dt2>, [<Xn|SP>], #<imm>
    if isDr(v0) &&
       isDr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == PostIndex {
        p.Domain = DomainFpSimd
        sa_dt1 := uint32(v0.(asm.Register).ID())
        sa_dt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_post(1, 1, 0, sa_imm_1, sa_dt2, sa_xn_sp, sa_dt1))
    }
    // STP  <Dt1>, <Dt2>, [<Xn|SP>, #<imm>]!
    if isDr(v0) &&
       isDr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == PreIndex {
        p.Domain = DomainFpSimd
        sa_dt1 := uint32(v0.(asm.Register).ID())
        sa_dt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_pre(1, 1, 0, sa_imm_1, sa_dt2, sa_xn_sp, sa_dt1))
    }
    // STP  <Qt1>, <Qt2>, [<Xn|SP>{, #<imm>}]
    if isQr(v0) &&
       isQr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_qt1 := uint32(v0.(asm.Register).ID())
        sa_qt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_2 := uint32(moffs(v2) / 16)
        return p.setins(ldstpair_off(2, 1, 0, sa_imm_2, sa_qt2, sa_xn_sp, sa_qt1))
    }
    // STP  <Qt1>, <Qt2>, [<Xn|SP>], #<imm>
    if isQr(v0) &&
       isQr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == PostIndex {
        p.Domain = DomainFpSimd
        sa_qt1 := uint32(v0.(asm.Register).ID())
        sa_qt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_3 := uint32(moffs(v2) / 16)
        return p.setins(ldstpair_post(2, 1, 0, sa_imm_3, sa_qt2, sa_xn_sp, sa_qt1))
    }
    // STP  <Qt1>, <Qt2>, [<Xn|SP>, #<imm>]!
    if isQr(v0) &&
       isQr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -1024, 1008) &&
       isMultipleOf(moffs(v2), 16) &&
       mext(v2) == PreIndex {
        p.Domain = DomainFpSimd
        sa_qt1 := uint32(v0.(asm.Register).ID())
        sa_qt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_3 := uint32(moffs(v2) / 16)
        return p.setins(ldstpair_pre(2, 1, 0, sa_imm_3, sa_qt2, sa_xn_sp, sa_qt1))
    }
    // STP  <St1>, <St2>, [<Xn|SP>{, #<imm>}]
    if isSr(v0) &&
       isSr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == Basic {
        p.Domain = DomainFpSimd
        sa_st1 := uint32(v0.(asm.Register).ID())
        sa_st2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_4 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_off(0, 1, 0, sa_imm_4, sa_st2, sa_xn_sp, sa_st1))
    }
    // STP  <St1>, <St2>, [<Xn|SP>], #<imm>
    if isSr(v0) &&
       isSr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PostIndex {
        p.Domain = DomainFpSimd
        sa_st1 := uint32(v0.(asm.Register).ID())
        sa_st2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_5 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_post(0, 1, 0, sa_imm_5, sa_st2, sa_xn_sp, sa_st1))
    }
    // STP  <St1>, <St2>, [<Xn|SP>, #<imm>]!
    if isSr(v0) &&
       isSr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PreIndex {
        p.Domain = DomainFpSimd
        sa_st1 := uint32(v0.(asm.Register).ID())
        sa_st2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_5 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_pre(0, 1, 0, sa_imm_5, sa_st2, sa_xn_sp, sa_st1))
    }
    // STP  <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_off(0, 0, 0, sa_imm, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // STP  <Wt1>, <Wt2>, [<Xn|SP>], #<imm>
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_post(0, 0, 0, sa_imm_1, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // STP  <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -256, 252) &&
       isMultipleOf(moffs(v2), 4) &&
       mext(v2) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt1 := uint32(v0.(asm.Register).ID())
        sa_wt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_1 := uint32(moffs(v2) / 4)
        return p.setins(ldstpair_pre(0, 0, 0, sa_imm_1, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // STP  <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_2 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_off(2, 0, 0, sa_imm_2, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // STP  <Xt1>, <Xt2>, [<Xn|SP>], #<imm>
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_3 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_post(2, 0, 0, sa_imm_3, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // STP  <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       isInRange(moffs(v2), -512, 504) &&
       isMultipleOf(moffs(v2), 8) &&
       mext(v2) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        sa_imm_3 := uint32(moffs(v2) / 8)
        return p.setins(ldstpair_pre(2, 0, 0, sa_imm_3, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STP")
}

// STR instruction have 29 forms across 4 categories:
//
// 1. Store SIMD&FP register (immediate offset)
//
//    STR  <Bt>, [<Xn|SP>], #<simm>
//    STR  <Bt>, [<Xn|SP>, #<simm>]!
//    STR  <Bt>, [<Xn|SP>{, #<pimm>}]
//    STR  <Dt>, [<Xn|SP>], #<simm>
//    STR  <Dt>, [<Xn|SP>, #<simm>]!
//    STR  <Dt>, [<Xn|SP>{, #<pimm>}]
//    STR  <Ht>, [<Xn|SP>], #<simm>
//    STR  <Ht>, [<Xn|SP>, #<simm>]!
//    STR  <Ht>, [<Xn|SP>{, #<pimm>}]
//    STR  <Qt>, [<Xn|SP>], #<simm>
//    STR  <Qt>, [<Xn|SP>, #<simm>]!
//    STR  <Qt>, [<Xn|SP>{, #<pimm>}]
//    STR  <St>, [<Xn|SP>], #<simm>
//    STR  <St>, [<Xn|SP>, #<simm>]!
//    STR  <St>, [<Xn|SP>{, #<pimm>}]
//
// Store SIMD&FP register (immediate offset). This instruction stores a single
// SIMD&FP register to memory. The address that is used for the store is calculated
// from a base register value and an immediate offset.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Store Register (immediate)
//
//    STR  <Wt>, [<Xn|SP>], #<simm>
//    STR  <Wt>, [<Xn|SP>, #<simm>]!
//    STR  <Wt>, [<Xn|SP>{, #<pimm>}]
//    STR  <Xt>, [<Xn|SP>], #<simm>
//    STR  <Xt>, [<Xn|SP>, #<simm>]!
//    STR  <Xt>, [<Xn|SP>{, #<pimm>}]
//
// Store Register (immediate) stores a word or a doubleword from a register to
// memory. The address that is used for the store is calculated from a base
// register and an immediate offset. For information about memory accesses, see
// Load/Store addressing modes .
//
// 3. Store SIMD&FP register (register offset)
//
//    STR  <Bt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
//    STR  <Bt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
//    STR  <Dt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//    STR  <Ht>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//    STR  <Qt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//    STR  <St>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//
// Store SIMD&FP register (register offset). This instruction stores a single
// SIMD&FP register to memory. The address that is used for the store is calculated
// from a base register value and an offset register value. The offset can be
// optionally shifted and extended.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 4. Store Register (register)
//
//    STR  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//    STR  <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//
// Store Register (register) calculates an address from a base register value and
// an offset register value, and stores a 32-bit word or a 64-bit doubleword to the
// calculated address, from a register. For information about memory accesses, see
// Load/Store addressing modes .
//
// The instruction uses an offset addressing mode, that calculates the address used
// for the memory access from a base register value and an offset register value.
// The offset can be optionally shifted and extended.
//
func (self *Program) STR(v0, v1 interface{}) *Instruction {
    p := self.alloc("STR", 2, asm.Operands { v0, v1 })
    // STR  <Bt>, [<Xn|SP>], #<simm>
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(0, 1, 0, sa_simm, sa_xn_sp, sa_bt))
    }
    // STR  <Bt>, [<Xn|SP>, #<simm>]!
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(0, 1, 0, sa_simm, sa_xn_sp, sa_bt))
    }
    // STR  <Bt>, [<Xn|SP>{, #<pimm>}]
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 4095) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1))
        return p.setins(ldst_pos(0, 1, 0, sa_pimm, sa_xn_sp, sa_bt))
    }
    // STR  <Dt>, [<Xn|SP>], #<simm>
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(3, 1, 0, sa_simm, sa_xn_sp, sa_dt))
    }
    // STR  <Dt>, [<Xn|SP>, #<simm>]!
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(3, 1, 0, sa_simm, sa_xn_sp, sa_dt))
    }
    // STR  <Dt>, [<Xn|SP>{, #<pimm>}]
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 32760) &&
       isMultipleOf(moffs(v1), 8) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_1 := uint32(moffs(v1) / 8)
        return p.setins(ldst_pos(3, 1, 0, sa_pimm_1, sa_xn_sp, sa_dt))
    }
    // STR  <Ht>, [<Xn|SP>], #<simm>
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(1, 1, 0, sa_simm, sa_xn_sp, sa_ht))
    }
    // STR  <Ht>, [<Xn|SP>, #<simm>]!
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(1, 1, 0, sa_simm, sa_xn_sp, sa_ht))
    }
    // STR  <Ht>, [<Xn|SP>{, #<pimm>}]
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 8190) &&
       isMultipleOf(moffs(v1), 2) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_2 := uint32(moffs(v1) / 2)
        return p.setins(ldst_pos(1, 1, 0, sa_pimm_2, sa_xn_sp, sa_ht))
    }
    // STR  <Qt>, [<Xn|SP>], #<simm>
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(0, 1, 2, sa_simm, sa_xn_sp, sa_qt))
    }
    // STR  <Qt>, [<Xn|SP>, #<simm>]!
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(0, 1, 2, sa_simm, sa_xn_sp, sa_qt))
    }
    // STR  <Qt>, [<Xn|SP>{, #<pimm>}]
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 65520) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_3 := uint32(moffs(v1) / 16)
        return p.setins(ldst_pos(0, 1, 2, sa_pimm_3, sa_xn_sp, sa_qt))
    }
    // STR  <St>, [<Xn|SP>], #<simm>
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(2, 1, 0, sa_simm, sa_xn_sp, sa_st))
    }
    // STR  <St>, [<Xn|SP>, #<simm>]!
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(2, 1, 0, sa_simm, sa_xn_sp, sa_st))
    }
    // STR  <St>, [<Xn|SP>{, #<pimm>}]
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 16380) &&
       isMultipleOf(moffs(v1), 4) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_4 := uint32(moffs(v1) / 4)
        return p.setins(ldst_pos(2, 1, 0, sa_pimm_4, sa_xn_sp, sa_st))
    }
    // STR  <Wt>, [<Xn|SP>], #<simm>
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(2, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    // STR  <Wt>, [<Xn|SP>, #<simm>]!
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(2, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    // STR  <Wt>, [<Xn|SP>{, #<pimm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 16380) &&
       isMultipleOf(moffs(v1), 4) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1) / 4)
        return p.setins(ldst_pos(2, 0, 0, sa_pimm, sa_xn_sp, sa_wt))
    }
    // STR  <Xt>, [<Xn|SP>], #<simm>
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(3, 0, 0, sa_simm, sa_xn_sp, sa_xt))
    }
    // STR  <Xt>, [<Xn|SP>, #<simm>]!
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(3, 0, 0, sa_simm, sa_xn_sp, sa_xt))
    }
    // STR  <Xt>, [<Xn|SP>{, #<pimm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 32760) &&
       isMultipleOf(moffs(v1), 8) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm_1 := uint32(moffs(v1) / 8)
        return p.setins(ldst_pos(3, 0, 0, sa_pimm_1, sa_xn_sp, sa_xt))
    }
    // STR  <Bt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       (mext(v1) == Basic || modt(mext(v1)) == ModLSL) {
        p.Domain = DomainFpSimd
        var sa_amount uint32
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            sa_amount = uint32(mext(v1).(Modifier).Amount())
        }
        return p.setins(ldst_regoff(0, 1, 0, sa_xm, 3, sa_amount, sa_xn_sp, sa_bt))
    }
    // STR  <Bt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
    if isBr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isWrOrXr(midx(v1)) && isMod(mext(v1)) {
        p.Domain = DomainFpSimd
        var sa_extend uint32
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        switch mext(v1).(Modifier).Type() {
            case ModUXTW: sa_extend = 0b010
            case ModSXTW: sa_extend = 0b110
            case ModSXTX: sa_extend = 0b111
            default: panic("aarch64: invalid modifier flags")
        }
        sa_amount := uint32(mext(v1).(Modifier).Amount())
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for STR")
        }
        return p.setins(ldst_regoff(0, 1, 0, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_bt))
    }
    // STR  <Dt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = DomainFpSimd
        var sa_amount_1 uint32
        sa_extend_1 := uint32(0b011)
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_1 = 0b0
            case 3: sa_amount_1 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend_1 & 1 != 0 || isXr(sa_xm) && sa_extend_1 & 1 != 1 {
            panic("aarch64: invalid combination of operands for STR")
        }
        return p.setins(ldst_regoff(3, 1, 0, sa_xm, sa_extend_1, sa_amount_1, sa_xn_sp, sa_dt))
    }
    // STR  <Ht>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = DomainFpSimd
        var sa_amount_2 uint32
        sa_extend_1 := uint32(0b011)
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_2 = 0b0
            case 1: sa_amount_2 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend_1 & 1 != 0 || isXr(sa_xm) && sa_extend_1 & 1 != 1 {
            panic("aarch64: invalid combination of operands for STR")
        }
        return p.setins(ldst_regoff(1, 1, 0, sa_xm, sa_extend_1, sa_amount_2, sa_xn_sp, sa_ht))
    }
    // STR  <Qt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = DomainFpSimd
        var sa_amount_3 uint32
        sa_extend_1 := uint32(0b011)
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_3 = 0b0
            case 4: sa_amount_3 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend_1 & 1 != 0 || isXr(sa_xm) && sa_extend_1 & 1 != 1 {
            panic("aarch64: invalid combination of operands for STR")
        }
        return p.setins(ldst_regoff(0, 1, 2, sa_xm, sa_extend_1, sa_amount_3, sa_xn_sp, sa_qt))
    }
    // STR  <St>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = DomainFpSimd
        var sa_amount_4 uint32
        sa_extend_1 := uint32(0b011)
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_4 = 0b0
            case 2: sa_amount_4 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend_1 & 1 != 0 || isXr(sa_xm) && sa_extend_1 & 1 != 1 {
            panic("aarch64: invalid combination of operands for STR")
        }
        return p.setins(ldst_regoff(2, 1, 0, sa_xm, sa_extend_1, sa_amount_4, sa_xn_sp, sa_st))
    }
    // STR  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_extend := uint32(0b011)
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 2: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for STR")
        }
        return p.setins(ldst_regoff(2, 0, 0, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_wt))
    }
    // STR  <Xt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount_1 uint32
        sa_extend := uint32(0b011)
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount_1 = 0b0
            case 3: sa_amount_1 = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for STR")
        }
        return p.setins(ldst_regoff(3, 0, 0, sa_xm, sa_extend, sa_amount_1, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STR")
}

// STRB instruction have 5 forms across 2 categories:
//
// 1. Store Register Byte (immediate)
//
//    STRB  <Wt>, [<Xn|SP>], #<simm>
//    STRB  <Wt>, [<Xn|SP>, #<simm>]!
//    STRB  <Wt>, [<Xn|SP>{, #<pimm>}]
//
// Store Register Byte (immediate) stores the least significant byte of a 32-bit
// register to memory. The address that is used for the store is calculated from a
// base register and an immediate offset. For information about memory accesses,
// see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STRB (immediate) .
//
// 2. Store Register Byte (register)
//
//    STRB  <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
//    STRB  <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
//
// Store Register Byte (register) calculates an address from a base register value
// and an offset register value, and stores a byte from a 32-bit register to the
// calculated address. For information about memory accesses, see Load/Store
// addressing modes .
//
// The instruction uses an offset addressing mode, that calculates the address used
// for the memory access from a base register value and an offset register value.
// The offset can be optionally shifted and extended.
//
func (self *Program) STRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STRB", 2, asm.Operands { v0, v1 })
    // STRB  <Wt>, [<Xn|SP>], #<simm>
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(0, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    // STRB  <Wt>, [<Xn|SP>, #<simm>]!
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(0, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    // STRB  <Wt>, [<Xn|SP>{, #<pimm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 4095) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1))
        return p.setins(ldst_pos(0, 0, 0, sa_pimm, sa_xn_sp, sa_wt))
    }
    // STRB  <Wt>, [<Xn|SP>, <Xm>{, LSL <amount>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isXr(midx(v1)) &&
       (mext(v1) == Basic || modt(mext(v1)) == ModLSL) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            sa_amount = uint32(mext(v1).(Modifier).Amount())
        }
        return p.setins(ldst_regoff(0, 0, 0, sa_xm, 3, sa_amount, sa_xn_sp, sa_wt))
    }
    // STRB  <Wt>, [<Xn|SP>, (<Wm>|<Xm>), <extend> {<amount>}]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && moffs(v1) == 0 && isWrOrXr(midx(v1)) && isMod(mext(v1)) {
        p.Domain = asm.DomainGeneric
        var sa_extend uint32
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        switch mext(v1).(Modifier).Type() {
            case ModUXTW: sa_extend = 0b010
            case ModSXTW: sa_extend = 0b110
            case ModSXTX: sa_extend = 0b111
            default: panic("aarch64: invalid modifier flags")
        }
        sa_amount := uint32(mext(v1).(Modifier).Amount())
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for STRB")
        }
        return p.setins(ldst_regoff(0, 0, 0, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_wt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STRB")
}

// STRH instruction have 4 forms across 2 categories:
//
// 1. Store Register Halfword (immediate)
//
//    STRH  <Wt>, [<Xn|SP>], #<simm>
//    STRH  <Wt>, [<Xn|SP>, #<simm>]!
//    STRH  <Wt>, [<Xn|SP>{, #<pimm>}]
//
// Store Register Halfword (immediate) stores the least significant halfword of a
// 32-bit register to memory. The address that is used for the store is calculated
// from a base register and an immediate offset. For information about memory
// accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STRH (immediate) .
//
// 2. Store Register Halfword (register)
//
//    STRH  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
//
// Store Register Halfword (register) calculates an address from a base register
// value and an offset register value, and stores a halfword from a 32-bit register
// to the calculated address. For information about memory accesses, see Load/Store
// addressing modes .
//
// The instruction uses an offset addressing mode, that calculates the address used
// for the memory access from a base register value and an offset register value.
// The offset can be optionally shifted and extended.
//
func (self *Program) STRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STRH", 2, asm.Operands { v0, v1 })
    // STRH  <Wt>, [<Xn|SP>], #<simm>
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PostIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpost(1, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    // STRH  <Wt>, [<Xn|SP>, #<simm>]!
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == PreIndex {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_immpre(1, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    // STRH  <Wt>, [<Xn|SP>{, #<pimm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), 0, 8190) &&
       isMultipleOf(moffs(v1), 2) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_pimm := uint32(moffs(v1) / 2)
        return p.setins(ldst_pos(1, 0, 0, sa_pimm, sa_xn_sp, sa_wt))
    }
    // STRH  <Wt>, [<Xn|SP>, (<Wm>|<Xm>){, <extend> {<amount>}}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       moffs(v1) == 0 &&
       isWrOrXr(midx(v1)) &&
       (mext(v1) == Basic || isMods(mext(v1), ModLSL, ModSXTW, ModSXTX, ModUXTW)) {
        p.Domain = asm.DomainGeneric
        var sa_amount uint32
        sa_extend := uint32(0b011)
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_xm := uint32(midx(v1).ID())
        if isMod(mext(v1)) {
            switch mext(v1).(Modifier).Type() {
                case ModUXTW: sa_extend = 0b010
                case ModLSL: sa_extend = 0b011
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
        }
        switch uint32(mext(v1).(Modifier).Amount()) {
            case 0: sa_amount = 0b0
            case 1: sa_amount = 0b1
            default: panic("aarch64: invalid modifier amount")
        }
        if isWr(sa_xm) && sa_extend & 1 != 0 || isXr(sa_xm) && sa_extend & 1 != 1 {
            panic("aarch64: invalid combination of operands for STRH")
        }
        return p.setins(ldst_regoff(1, 0, 0, sa_xm, sa_extend, sa_amount, sa_xn_sp, sa_wt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STRH")
}

// STSET instruction have 2 forms across one single category:
//
// 1. Atomic bit set on word or doubleword in memory, without return
//
//    STSET  <Ws>, [<Xn|SP>]
//    STSET  <Xs>, [<Xn|SP>]
//
// Atomic bit set on word or doubleword in memory, without return, atomically loads
// a 32-bit word or 64-bit doubleword from memory, performs a bitwise OR with the
// value held in a register on it, and stores the result back to memory.
//
//     * STSET does not have release semantics.
//     * STSETL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSET(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSET", 2, asm.Operands { v0, v1 })
    // STSET  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 3, sa_xn_sp, 31))
    }
    // STSET  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 3, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STSET")
}

// STSETB instruction have one single form across one single category:
//
// 1. Atomic bit set on byte in memory, without return
//
//    STSETB  <Ws>, [<Xn|SP>]
//
// Atomic bit set on byte in memory, without return, atomically loads an 8-bit byte
// from memory, performs a bitwise OR with the value held in a register on it, and
// stores the result back to memory.
//
//     * STSETB does not have release semantics.
//     * STSETLB stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSETB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSETB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 3, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSETB")
}

// STSETH instruction have one single form across one single category:
//
// 1. Atomic bit set on halfword in memory, without return
//
//    STSETH  <Ws>, [<Xn|SP>]
//
// Atomic bit set on halfword in memory, without return, atomically loads a 16-bit
// halfword from memory, performs a bitwise OR with the value held in a register on
// it, and stores the result back to memory.
//
//     * STSETH does not have release semantics.
//     * STSETLH stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSETH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSETH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 3, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSETH")
}

// STSETL instruction have 2 forms across one single category:
//
// 1. Atomic bit set on word or doubleword in memory, without return
//
//    STSETL  <Ws>, [<Xn|SP>]
//    STSETL  <Xs>, [<Xn|SP>]
//
// Atomic bit set on word or doubleword in memory, without return, atomically loads
// a 32-bit word or 64-bit doubleword from memory, performs a bitwise OR with the
// value held in a register on it, and stores the result back to memory.
//
//     * STSET does not have release semantics.
//     * STSETL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSETL(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSETL", 2, asm.Operands { v0, v1 })
    // STSETL  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 3, sa_xn_sp, 31))
    }
    // STSETL  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 3, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STSETL")
}

// STSETLB instruction have one single form across one single category:
//
// 1. Atomic bit set on byte in memory, without return
//
//    STSETLB  <Ws>, [<Xn|SP>]
//
// Atomic bit set on byte in memory, without return, atomically loads an 8-bit byte
// from memory, performs a bitwise OR with the value held in a register on it, and
// stores the result back to memory.
//
//     * STSETB does not have release semantics.
//     * STSETLB stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSETLB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSETLB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 3, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSETLB")
}

// STSETLH instruction have one single form across one single category:
//
// 1. Atomic bit set on halfword in memory, without return
//
//    STSETLH  <Ws>, [<Xn|SP>]
//
// Atomic bit set on halfword in memory, without return, atomically loads a 16-bit
// halfword from memory, performs a bitwise OR with the value held in a register on
// it, and stores the result back to memory.
//
//     * STSETH does not have release semantics.
//     * STSETLH stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSETLH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSETLH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 3, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSETLH")
}

// STSMAX instruction have 2 forms across one single category:
//
// 1. Atomic signed maximum on word or doubleword in memory, without return
//
//    STSMAX  <Ws>, [<Xn|SP>]
//    STSMAX  <Xs>, [<Xn|SP>]
//
// Atomic signed maximum on word or doubleword in memory, without return,
// atomically loads a 32-bit word or 64-bit doubleword from memory, compares it
// against the value held in a register, and stores the larger value back to
// memory, treating the values as signed numbers.
//
//     * STSMAX does not have release semantics.
//     * STSMAXL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMAX(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMAX", 2, asm.Operands { v0, v1 })
    // STSMAX  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 4, sa_xn_sp, 31))
    }
    // STSMAX  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 4, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STSMAX")
}

// STSMAXB instruction have one single form across one single category:
//
// 1. Atomic signed maximum on byte in memory, without return
//
//    STSMAXB  <Ws>, [<Xn|SP>]
//
// Atomic signed maximum on byte in memory, without return, atomically loads an
// 8-bit byte from memory, compares it against the value held in a register, and
// stores the larger value back to memory, treating the values as signed numbers.
//
//     * STSMAXB does not have release semantics.
//     * STSMAXLB stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMAXB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMAXB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 4, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSMAXB")
}

// STSMAXH instruction have one single form across one single category:
//
// 1. Atomic signed maximum on halfword in memory, without return
//
//    STSMAXH  <Ws>, [<Xn|SP>]
//
// Atomic signed maximum on halfword in memory, without return, atomically loads a
// 16-bit halfword from memory, compares it against the value held in a register,
// and stores the larger value back to memory, treating the values as signed
// numbers.
//
//     * STSMAXH does not have release semantics.
//     * STSMAXLH stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMAXH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMAXH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 4, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSMAXH")
}

// STSMAXL instruction have 2 forms across one single category:
//
// 1. Atomic signed maximum on word or doubleword in memory, without return
//
//    STSMAXL  <Ws>, [<Xn|SP>]
//    STSMAXL  <Xs>, [<Xn|SP>]
//
// Atomic signed maximum on word or doubleword in memory, without return,
// atomically loads a 32-bit word or 64-bit doubleword from memory, compares it
// against the value held in a register, and stores the larger value back to
// memory, treating the values as signed numbers.
//
//     * STSMAX does not have release semantics.
//     * STSMAXL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMAXL(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMAXL", 2, asm.Operands { v0, v1 })
    // STSMAXL  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 4, sa_xn_sp, 31))
    }
    // STSMAXL  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 4, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STSMAXL")
}

// STSMAXLB instruction have one single form across one single category:
//
// 1. Atomic signed maximum on byte in memory, without return
//
//    STSMAXLB  <Ws>, [<Xn|SP>]
//
// Atomic signed maximum on byte in memory, without return, atomically loads an
// 8-bit byte from memory, compares it against the value held in a register, and
// stores the larger value back to memory, treating the values as signed numbers.
//
//     * STSMAXB does not have release semantics.
//     * STSMAXLB stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMAXLB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMAXLB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 4, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSMAXLB")
}

// STSMAXLH instruction have one single form across one single category:
//
// 1. Atomic signed maximum on halfword in memory, without return
//
//    STSMAXLH  <Ws>, [<Xn|SP>]
//
// Atomic signed maximum on halfword in memory, without return, atomically loads a
// 16-bit halfword from memory, compares it against the value held in a register,
// and stores the larger value back to memory, treating the values as signed
// numbers.
//
//     * STSMAXH does not have release semantics.
//     * STSMAXLH stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMAXLH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMAXLH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 4, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSMAXLH")
}

// STSMIN instruction have 2 forms across one single category:
//
// 1. Atomic signed minimum on word or doubleword in memory, without return
//
//    STSMIN  <Ws>, [<Xn|SP>]
//    STSMIN  <Xs>, [<Xn|SP>]
//
// Atomic signed minimum on word or doubleword in memory, without return,
// atomically loads a 32-bit word or 64-bit doubleword from memory, compares it
// against the value held in a register, and stores the smaller value back to
// memory, treating the values as signed numbers.
//
//     * STSMIN does not have release semantics.
//     * STSMINL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMIN(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMIN", 2, asm.Operands { v0, v1 })
    // STSMIN  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 5, sa_xn_sp, 31))
    }
    // STSMIN  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 5, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STSMIN")
}

// STSMINB instruction have one single form across one single category:
//
// 1. Atomic signed minimum on byte in memory, without return
//
//    STSMINB  <Ws>, [<Xn|SP>]
//
// Atomic signed minimum on byte in memory, without return, atomically loads an
// 8-bit byte from memory, compares it against the value held in a register, and
// stores the smaller value back to memory, treating the values as signed numbers.
//
//     * STSMINB does not have release semantics.
//     * STSMINLB stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMINB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMINB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 5, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSMINB")
}

// STSMINH instruction have one single form across one single category:
//
// 1. Atomic signed minimum on halfword in memory, without return
//
//    STSMINH  <Ws>, [<Xn|SP>]
//
// Atomic signed minimum on halfword in memory, without return, atomically loads a
// 16-bit halfword from memory, compares it against the value held in a register,
// and stores the smaller value back to memory, treating the values as signed
// numbers.
//
//     * STSMINH does not have release semantics.
//     * STSMINLH stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMINH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMINH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 5, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSMINH")
}

// STSMINL instruction have 2 forms across one single category:
//
// 1. Atomic signed minimum on word or doubleword in memory, without return
//
//    STSMINL  <Ws>, [<Xn|SP>]
//    STSMINL  <Xs>, [<Xn|SP>]
//
// Atomic signed minimum on word or doubleword in memory, without return,
// atomically loads a 32-bit word or 64-bit doubleword from memory, compares it
// against the value held in a register, and stores the smaller value back to
// memory, treating the values as signed numbers.
//
//     * STSMIN does not have release semantics.
//     * STSMINL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMINL(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMINL", 2, asm.Operands { v0, v1 })
    // STSMINL  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 5, sa_xn_sp, 31))
    }
    // STSMINL  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 5, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STSMINL")
}

// STSMINLB instruction have one single form across one single category:
//
// 1. Atomic signed minimum on byte in memory, without return
//
//    STSMINLB  <Ws>, [<Xn|SP>]
//
// Atomic signed minimum on byte in memory, without return, atomically loads an
// 8-bit byte from memory, compares it against the value held in a register, and
// stores the smaller value back to memory, treating the values as signed numbers.
//
//     * STSMINB does not have release semantics.
//     * STSMINLB stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMINLB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMINLB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 5, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSMINLB")
}

// STSMINLH instruction have one single form across one single category:
//
// 1. Atomic signed minimum on halfword in memory, without return
//
//    STSMINLH  <Ws>, [<Xn|SP>]
//
// Atomic signed minimum on halfword in memory, without return, atomically loads a
// 16-bit halfword from memory, compares it against the value held in a register,
// and stores the smaller value back to memory, treating the values as signed
// numbers.
//
//     * STSMINH does not have release semantics.
//     * STSMINLH stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STSMINLH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STSMINLH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 5, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STSMINLH")
}

// STTR instruction have 2 forms across one single category:
//
// 1. Store Register (unprivileged)
//
//    STTR  <Wt>, [<Xn|SP>{, #<simm>}]
//    STTR  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Store Register (unprivileged) stores a word or doubleword from a register to
// memory. The address that is used for the store is calculated from a base
// register and an immediate offset.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed. For information about
// memory accesses, see Load/Store addressing modes .
//
func (self *Program) STTR(v0, v1 interface{}) *Instruction {
    p := self.alloc("STTR", 2, asm.Operands { v0, v1 })
    // STTR  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(2, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    // STTR  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(3, 0, 0, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STTR")
}

// STTRB instruction have one single form across one single category:
//
// 1. Store Register Byte (unprivileged)
//
//    STTRB  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Store Register Byte (unprivileged) stores a byte from a 32-bit register to
// memory. The address that is used for the store is calculated from a base
// register and an immediate offset.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed. For information about
// memory accesses, see Load/Store addressing modes .
//
func (self *Program) STTRB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STTRB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(0, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STTRB")
}

// STTRH instruction have one single form across one single category:
//
// 1. Store Register Halfword (unprivileged)
//
//    STTRH  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Store Register Halfword (unprivileged) stores a halfword from a 32-bit register
// to memory. The address that is used for the store is calculated from a base
// register and an immediate offset.
//
// Memory accesses made by the instruction behave as if the instruction was
// executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
//
//     * The instruction is executed at EL1.
//     * The instruction is executed at EL2 when the Effective value of HCR_EL2
//       .{E2H, TGE} is {1, 1}.
//
// Otherwise, the memory access operates with the restrictions determined by the
// Exception level at which the instruction is executed. For information about
// memory accesses, see Load/Store addressing modes .
//
func (self *Program) STTRH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STTRH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unpriv(1, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STTRH")
}

// STUMAX instruction have 2 forms across one single category:
//
// 1. Atomic unsigned maximum on word or doubleword in memory, without return
//
//    STUMAX  <Ws>, [<Xn|SP>]
//    STUMAX  <Xs>, [<Xn|SP>]
//
// Atomic unsigned maximum on word or doubleword in memory, without return,
// atomically loads a 32-bit word or 64-bit doubleword from memory, compares it
// against the value held in a register, and stores the larger value back to
// memory, treating the values as unsigned numbers.
//
//     * STUMAX does not have release semantics.
//     * STUMAXL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMAX(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMAX", 2, asm.Operands { v0, v1 })
    // STUMAX  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 6, sa_xn_sp, 31))
    }
    // STUMAX  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 6, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STUMAX")
}

// STUMAXB instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on byte in memory, without return
//
//    STUMAXB  <Ws>, [<Xn|SP>]
//
// Atomic unsigned maximum on byte in memory, without return, atomically loads an
// 8-bit byte from memory, compares it against the value held in a register, and
// stores the larger value back to memory, treating the values as unsigned numbers.
//
//     * STUMAXB does not have release semantics.
//     * STUMAXLB stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMAXB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMAXB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 6, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STUMAXB")
}

// STUMAXH instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on halfword in memory, without return
//
//    STUMAXH  <Ws>, [<Xn|SP>]
//
// Atomic unsigned maximum on halfword in memory, without return, atomically loads
// a 16-bit halfword from memory, compares it against the value held in a register,
// and stores the larger value back to memory, treating the values as unsigned
// numbers.
//
//     * STUMAXH does not have release semantics.
//     * STUMAXLH stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses see Load/Store addressing modes .
//
func (self *Program) STUMAXH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMAXH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 6, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STUMAXH")
}

// STUMAXL instruction have 2 forms across one single category:
//
// 1. Atomic unsigned maximum on word or doubleword in memory, without return
//
//    STUMAXL  <Ws>, [<Xn|SP>]
//    STUMAXL  <Xs>, [<Xn|SP>]
//
// Atomic unsigned maximum on word or doubleword in memory, without return,
// atomically loads a 32-bit word or 64-bit doubleword from memory, compares it
// against the value held in a register, and stores the larger value back to
// memory, treating the values as unsigned numbers.
//
//     * STUMAX does not have release semantics.
//     * STUMAXL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMAXL(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMAXL", 2, asm.Operands { v0, v1 })
    // STUMAXL  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 6, sa_xn_sp, 31))
    }
    // STUMAXL  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 6, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STUMAXL")
}

// STUMAXLB instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on byte in memory, without return
//
//    STUMAXLB  <Ws>, [<Xn|SP>]
//
// Atomic unsigned maximum on byte in memory, without return, atomically loads an
// 8-bit byte from memory, compares it against the value held in a register, and
// stores the larger value back to memory, treating the values as unsigned numbers.
//
//     * STUMAXB does not have release semantics.
//     * STUMAXLB stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMAXLB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMAXLB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 6, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STUMAXLB")
}

// STUMAXLH instruction have one single form across one single category:
//
// 1. Atomic unsigned maximum on halfword in memory, without return
//
//    STUMAXLH  <Ws>, [<Xn|SP>]
//
// Atomic unsigned maximum on halfword in memory, without return, atomically loads
// a 16-bit halfword from memory, compares it against the value held in a register,
// and stores the larger value back to memory, treating the values as unsigned
// numbers.
//
//     * STUMAXH does not have release semantics.
//     * STUMAXLH stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses see Load/Store addressing modes .
//
func (self *Program) STUMAXLH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMAXLH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 6, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STUMAXLH")
}

// STUMIN instruction have 2 forms across one single category:
//
// 1. Atomic unsigned minimum on word or doubleword in memory, without return
//
//    STUMIN  <Ws>, [<Xn|SP>]
//    STUMIN  <Xs>, [<Xn|SP>]
//
// Atomic unsigned minimum on word or doubleword in memory, without return,
// atomically loads a 32-bit word or 64-bit doubleword from memory, compares it
// against the value held in a register, and stores the smaller value back to
// memory, treating the values as unsigned numbers.
//
//     * STUMIN does not have release semantics.
//     * STUMINL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMIN(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMIN", 2, asm.Operands { v0, v1 })
    // STUMIN  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 0, 7, sa_xn_sp, 31))
    }
    // STUMIN  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 0, 7, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STUMIN")
}

// STUMINB instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on byte in memory, without return
//
//    STUMINB  <Ws>, [<Xn|SP>]
//
// Atomic unsigned minimum on byte in memory, without return, atomically loads an
// 8-bit byte from memory, compares it against the value held in a register, and
// stores the smaller value back to memory, treating the values as unsigned
// numbers.
//
//     * STUMINB does not have release semantics.
//     * STUMINLB stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMINB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMINB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 0, 7, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STUMINB")
}

// STUMINH instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on halfword in memory, without return
//
//    STUMINH  <Ws>, [<Xn|SP>]
//
// Atomic unsigned minimum on halfword in memory, without return, atomically loads
// a 16-bit halfword from memory, compares it against the value held in a register,
// and stores the smaller value back to memory, treating the values as unsigned
// numbers.
//
//     * STUMINH does not have release semantics.
//     * STUMINLH stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMINH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMINH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 0, 7, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STUMINH")
}

// STUMINL instruction have 2 forms across one single category:
//
// 1. Atomic unsigned minimum on word or doubleword in memory, without return
//
//    STUMINL  <Ws>, [<Xn|SP>]
//    STUMINL  <Xs>, [<Xn|SP>]
//
// Atomic unsigned minimum on word or doubleword in memory, without return,
// atomically loads a 32-bit word or 64-bit doubleword from memory, compares it
// against the value held in a register, and stores the smaller value back to
// memory, treating the values as unsigned numbers.
//
//     * STUMIN does not have release semantics.
//     * STUMINL stores to memory with release semantics, as described in Load-
//       Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMINL(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMINL", 2, asm.Operands { v0, v1 })
    // STUMINL  <Ws>, [<Xn|SP>]
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 0, 7, sa_xn_sp, 31))
    }
    // STUMINL  <Xs>, [<Xn|SP>]
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 0, 7, sa_xn_sp, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STUMINL")
}

// STUMINLB instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on byte in memory, without return
//
//    STUMINLB  <Ws>, [<Xn|SP>]
//
// Atomic unsigned minimum on byte in memory, without return, atomically loads an
// 8-bit byte from memory, compares it against the value held in a register, and
// stores the smaller value back to memory, treating the values as unsigned
// numbers.
//
//     * STUMINB does not have release semantics.
//     * STUMINLB stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMINLB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMINLB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 0, 7, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STUMINLB")
}

// STUMINLH instruction have one single form across one single category:
//
// 1. Atomic unsigned minimum on halfword in memory, without return
//
//    STUMINLH  <Ws>, [<Xn|SP>]
//
// Atomic unsigned minimum on halfword in memory, without return, atomically loads
// a 16-bit halfword from memory, compares it against the value held in a register,
// and stores the smaller value back to memory, treating the values as unsigned
// numbers.
//
//     * STUMINH does not have release semantics.
//     * STUMINLH stores to memory with release semantics, as described in
//       Load-Acquire, Store-Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STUMINLH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUMINLH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 0, 7, sa_xn_sp, 31))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STUMINLH")
}

// STUR instruction have 7 forms across 2 categories:
//
// 1. Store SIMD&FP register (unscaled offset)
//
//    STUR  <Bt>, [<Xn|SP>{, #<simm>}]
//    STUR  <Dt>, [<Xn|SP>{, #<simm>}]
//    STUR  <Ht>, [<Xn|SP>{, #<simm>}]
//    STUR  <Qt>, [<Xn|SP>{, #<simm>}]
//    STUR  <St>, [<Xn|SP>{, #<simm>}]
//
// Store SIMD&FP register (unscaled offset). This instruction stores a single
// SIMD&FP register to memory. The address that is used for the store is calculated
// from a base register value and an optional immediate offset.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Store Register (unscaled)
//
//    STUR  <Wt>, [<Xn|SP>{, #<simm>}]
//    STUR  <Xt>, [<Xn|SP>{, #<simm>}]
//
// Store Register (unscaled) calculates an address from a base register value and
// an immediate offset, and stores a 32-bit word or a 64-bit doubleword to the
// calculated address, from a register. For information about memory accesses, see
// Load/Store addressing modes .
//
func (self *Program) STUR(v0, v1 interface{}) *Instruction {
    p := self.alloc("STUR", 2, asm.Operands { v0, v1 })
    // STUR  <Bt>, [<Xn|SP>{, #<simm>}]
    if isBr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_bt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(0, 1, 0, sa_simm, sa_xn_sp, sa_bt))
    }
    // STUR  <Dt>, [<Xn|SP>{, #<simm>}]
    if isDr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_dt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(3, 1, 0, sa_simm, sa_xn_sp, sa_dt))
    }
    // STUR  <Ht>, [<Xn|SP>{, #<simm>}]
    if isHr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_ht := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(1, 1, 0, sa_simm, sa_xn_sp, sa_ht))
    }
    // STUR  <Qt>, [<Xn|SP>{, #<simm>}]
    if isQr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_qt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(0, 1, 2, sa_simm, sa_xn_sp, sa_qt))
    }
    // STUR  <St>, [<Xn|SP>{, #<simm>}]
    if isSr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = DomainFpSimd
        sa_st := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(2, 1, 0, sa_simm, sa_xn_sp, sa_st))
    }
    // STUR  <Wt>, [<Xn|SP>{, #<simm>}]
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(2, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    // STUR  <Xt>, [<Xn|SP>{, #<simm>}]
    if isXr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(3, 0, 0, sa_simm, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STUR")
}

// STURB instruction have one single form across one single category:
//
// 1. Store Register Byte (unscaled)
//
//    STURB  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Store Register Byte (unscaled) calculates an address from a base register value
// and an immediate offset, and stores a byte to the calculated address, from a
// 32-bit register. For information about memory accesses, see Load/Store
// addressing modes .
//
func (self *Program) STURB(v0, v1 interface{}) *Instruction {
    p := self.alloc("STURB", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(0, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STURB")
}

// STURH instruction have one single form across one single category:
//
// 1. Store Register Halfword (unscaled)
//
//    STURH  <Wt>, [<Xn|SP>{, #<simm>}]
//
// Store Register Halfword (unscaled) calculates an address from a base register
// value and an immediate offset, and stores a halfword to the calculated address,
// from a 32-bit register. For information about memory accesses, see Load/Store
// addressing modes .
//
func (self *Program) STURH(v0, v1 interface{}) *Instruction {
    p := self.alloc("STURH", 2, asm.Operands { v0, v1 })
    if isWr(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -256, 255) &&
       mext(v1) == Basic {
        p.Domain = asm.DomainGeneric
        sa_wt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        return p.setins(ldst_unscaled(1, 0, 0, sa_simm, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STURH")
}

// STXP instruction have 2 forms across one single category:
//
// 1. Store Exclusive Pair of registers
//
//    STXP  <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]
//    STXP  <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]
//
// Store Exclusive Pair of registers stores two 32-bit words or two 64-bit
// doublewords from two registers to a memory location if the PE has exclusive
// access to the memory address, and returns a status value of 0 if the store was
// successful, or of 1 if no store was performed. See Synchronization and
// semaphores . For information on single-copy atomicity and alignment
// requirements, see Requirements for single-copy atomicity and Alignment of data
// accesses . If a 64-bit pair Store-Exclusive succeeds, it causes a single-copy
// atomic update of the 128-bit memory location being updated. For information
// about memory accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STXP .
//
func (self *Program) STXP(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("STXP", 4, asm.Operands { v0, v1, v2, v3 })
    // STXP  <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       isMem(v3) &&
       isXrOrSP(mbase(v3)) &&
       midx(v3) == nil &&
       (moffs(v3) == 0 || moffs(v3) == 0) &&
       mext(v3) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt1 := uint32(v1.(asm.Register).ID())
        sa_wt2 := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v3).ID())
        return p.setins(ldstexclp(0, 0, sa_ws, 0, sa_wt2, sa_xn_sp, sa_wt1))
    }
    // STXP  <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       isMem(v3) &&
       isXrOrSP(mbase(v3)) &&
       midx(v3) == nil &&
       (moffs(v3) == 0 || moffs(v3) == 0) &&
       mext(v3) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xt1 := uint32(v1.(asm.Register).ID())
        sa_xt2 := uint32(v2.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v3).ID())
        return p.setins(ldstexclp(1, 0, sa_ws, 0, sa_xt2, sa_xn_sp, sa_xt1))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STXP")
}

// STXR instruction have 2 forms across one single category:
//
// 1. Store Exclusive Register
//
//    STXR  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//    STXR  <Ws>, <Xt>, [<Xn|SP>{,#0}]
//
// Store Exclusive Register stores a 32-bit word or a 64-bit doubleword from a
// register to memory if the PE has exclusive access to the memory address, and
// returns a status value of 0 if the store was successful, or of 1 if no store was
// performed. See Synchronization and semaphores . For information about memory
// accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STXR .
//
func (self *Program) STXR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STXR", 3, asm.Operands { v0, v1, v2 })
    // STXR  <Ws>, <Wt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclr(2, 0, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    // STXR  <Ws>, <Xt>, [<Xn|SP>{,#0}]
    if isWr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclr(3, 0, sa_ws, 0, 31, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STXR")
}

// STXRB instruction have one single form across one single category:
//
// 1. Store Exclusive Register Byte
//
//    STXRB  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Store Exclusive Register Byte stores a byte from a register to memory if the PE
// has exclusive access to the memory address, and returns a status value of 0 if
// the store was successful, or of 1 if no store was performed. See Synchronization
// and semaphores . The memory access is atomic.
//
// For information about memory accesses, see Load/Store addressing modes .
//
// For information about the constrained unpredictable behavior of this
// instruction, see Architectural Constraints on UNPREDICTABLE behaviors , and
// particularly STXRB .
//
func (self *Program) STXRB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STXRB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclr(0, 0, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STXRB")
}

// STXRH instruction have one single form across one single category:
//
// 1. Store Exclusive Register Halfword
//
//    STXRH  <Ws>, <Wt>, [<Xn|SP>{,#0}]
//
// Store Exclusive Register Halfword stores a halfword from a register to memory if
// the PE has exclusive access to the memory address, and returns a status value of
// 0 if the store was successful, or of 1 if no store was performed. See
// Synchronization and semaphores . The memory access is atomic.
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) STXRH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("STXRH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       (moffs(v2) == 0 || moffs(v2) == 0) &&
       mext(v2) == Basic {
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(ldstexclr(1, 0, sa_ws, 0, 31, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STXRH")
}

// STZ2G instruction have 3 forms across one single category:
//
// 1. Store Allocation Tags, Zeroing
//
//    STZ2G  <Xt|SP>, [<Xn|SP>{, #<simm>}]
//    STZ2G  <Xt|SP>, [<Xn|SP>], #<simm>
//    STZ2G  <Xt|SP>, [<Xn|SP>, #<simm>]!
//
// Store Allocation Tags, Zeroing stores an Allocation Tag to two Tag granules of
// memory, zeroing the associated data locations. The address used for the store is
// calculated from the base register and an immediate signed offset scaled by the
// Tag granule. The Allocation Tag is calculated from the Logical Address Tag in
// the source register.
//
// This instruction generates an Unchecked access.
//
func (self *Program) STZ2G(v0, v1 interface{}) *Instruction {
    p := self.alloc("STZ2G", 2, asm.Operands { v0, v1 })
    // STZ2G  <Xt|SP>, [<Xn|SP>{, #<simm>}]
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(3, sa_simm, 2, Rn, Rt))
    }
    // STZ2G  <Xt|SP>, [<Xn|SP>], #<simm>
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == PostIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(3, sa_simm, 1, Rn, Rt))
    }
    // STZ2G  <Xt|SP>, [<Xn|SP>, #<simm>]!
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == PreIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(3, sa_simm, 3, Rn, Rt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STZ2G")
}

// STZG instruction have 3 forms across one single category:
//
// 1. Store Allocation Tag, Zeroing
//
//    STZG  <Xt|SP>, [<Xn|SP>{, #<simm>}]
//    STZG  <Xt|SP>, [<Xn|SP>], #<simm>
//    STZG  <Xt|SP>, [<Xn|SP>, #<simm>]!
//
// Store Allocation Tag, Zeroing stores an Allocation Tag to memory, zeroing the
// associated data location. The address used for the store is calculated from the
// base register and an immediate signed offset scaled by the Tag granule. The
// Allocation Tag is calculated from the Logical Address Tag in the source
// register.
//
// This instruction generates an Unchecked access.
//
func (self *Program) STZG(v0, v1 interface{}) *Instruction {
    p := self.alloc("STZG", 2, asm.Operands { v0, v1 })
    // STZG  <Xt|SP>, [<Xn|SP>{, #<simm>}]
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == Basic {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(1, sa_simm, 2, Rn, Rt))
    }
    // STZG  <Xt|SP>, [<Xn|SP>], #<simm>
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == PostIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(1, sa_simm, 1, Rn, Rt))
    }
    // STZG  <Xt|SP>, [<Xn|SP>, #<simm>]!
    if isXrOrSP(v0) &&
       isMem(v1) &&
       isXrOrSP(mbase(v1)) &&
       midx(v1) == nil &&
       isInRange(moffs(v1), -4096, 4080) &&
       isMultipleOf(moffs(v1), 16) &&
       mext(v1) == PreIndex {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xt_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        sa_simm := uint32(moffs(v1))
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt_sp
        return p.setins(ldsttags(1, sa_simm, 3, Rn, Rt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for STZG")
}

// STZGM instruction have one single form across one single category:
//
// 1. Store Tag and Zero Multiple
//
//    STZGM  <Xt>, [<Xn|SP>]
//
// Store Tag and Zero Multiple writes a naturally aligned block of N Allocation
// Tags and stores zero to the associated data locations, where the size of N is
// identified in DCZID_EL0.BS, and the Allocation Tag is taken from the source
// register bits<3:0>.
//
// This instruction is undefined at EL0.
//
// This instruction generates an Unchecked access.
//
func (self *Program) STZGM(v0, v1 interface{}) *Instruction {
    p := self.alloc("STZGM", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isMem(v1) && isXrOrSP(mbase(v1)) && midx(v1) == nil && moffs(v1) == 0 && mext(v1) == Basic {
        self.Arch.Require(FEAT_MTE2)
        p.Domain = asm.DomainGeneric
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v1).ID())
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rt := uint32(0b00000)
        Rt |= sa_xt
        return p.setins(ldsttags(0, 0, 0, Rn, Rt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for STZGM")
}

// SUB instruction have 10 forms across 4 categories:
//
// 1. Subtract (extended register)
//
//    SUB  <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
//    SUB  <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}
//
// Subtract (extended register) subtracts a sign or zero-extended register value,
// followed by an optional left shift amount, from a register value, and writes the
// result to the destination register. The argument that is extended from the <Rm>
// register can be a byte, halfword, word, or doubleword.
//
// 2. Subtract (immediate)
//
//    SUB  <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}
//    SUB  <Wd|WSP>, <Wn|WSP>, <label>{, <shift>}
//    SUB  <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}
//    SUB  <Xd|SP>, <Xn|SP>, <label>{, <shift>}
//
// Subtract (immediate) subtracts an optionally-shifted immediate value from a
// register value, and writes the result to the destination register.
//
// 3. Subtract (shifted register)
//
//    SUB  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    SUB  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Subtract (shifted register) subtracts an optionally-shifted register value from
// a register value, and writes the result to the destination register.
//
// 4. Subtract (vector)
//
//    SUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    SUB  <V><d>, <V><n>, <V><m>
//
// Subtract (vector). This instruction subtracts each vector element in the second
// source SIMD&FP register from the corresponding vector element in the first
// source SIMD&FP register, places the result into a vector, and writes the vector
// to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SUB(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("SUB", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("SUB", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction SUB takes 3 or 4 operands")
    }
    // SUB  <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isWrOrWSP(v1) &&
       isWr(v2) &&
       (len(vv) == 0 && (v0 == WSP || v1 == WSP) || len(vv) == 1 && modt(vv[0]) == ModUXTW) &&
       (v0 == WSP || v1 == WSP) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend := uint32(0b010)
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend = 0b000
                case ModUXTH: sa_extend = 0b001
                case ModLSL: sa_extend = 0b010
                case ModUXTW: sa_extend = 0b010
                case ModUXTX: sa_extend = 0b011
                case ModSXTB: sa_extend = 0b100
                case ModSXTH: sa_extend = 0b101
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_ext(0, 1, 0, 0, sa_wm, sa_extend, sa_amount, sa_wn_wsp, sa_wd_wsp))
    }
    // SUB  <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isXrOrSP(v1) &&
       isWrOrXr(v2) &&
       (len(vv) == 0 && (v0 == SP || v1 == SP) || len(vv) == 1 && modt(vv[0]) == ModUXTX) &&
       (v0 == SP || v1 == SP) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend_1 := uint32(0b011)
        var sa_r [4]uint32
        var sa_r__bit_mask [4]uint32
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        switch true {
            case isWr(v2): sa_r = [4]uint32{0b000, 0b010, 0b100, 0b110}
            case isXr(v2): sa_r = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        switch true {
            case isWr(v2): sa_r__bit_mask = [4]uint32{0b110, 0b111, 0b110, 0b111}
            case isXr(v2): sa_r__bit_mask = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend_1 = 0b000
                case ModUXTH: sa_extend_1 = 0b001
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModUXTX: sa_extend_1 = 0b011
                case ModSXTB: sa_extend_1 = 0b100
                case ModSXTH: sa_extend_1 = 0b101
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        if !matchany(sa_extend_1, &sa_r[0], &sa_r__bit_mask[0], 4) {
            panic("aarch64: invalid combination of operands for SUB")
        }
        return p.setins(addsub_ext(1, 1, 0, 0, sa_m, sa_extend_1, sa_amount, sa_xn_sp, sa_xd_sp))
    }
    // SUB  <Wd|WSP>, <Wn|WSP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isWrOrWSP(v1) &&
       isInRange(v2, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) &&
       (v0 == WSP || v1 == WSP) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_imm := asImm12(v2)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(0, 1, 0, sa_shift, sa_imm, sa_wn_wsp, sa_wd_wsp))
    }
    // SUB  <Wd|WSP>, <Wn|WSP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWrOrWSP(v0) &&
       isWrOrWSP(v1) &&
       isLabel(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) &&
       (v0 == WSP || v1 == WSP) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd_wsp := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_label := v2.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(0, 1, 0, sa_shift, abs12(sa_label), sa_wn_wsp, sa_wd_wsp)
        })
    }
    // SUB  <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isXrOrSP(v1) &&
       isInRange(v2, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) &&
       (v0 == SP || v1 == SP) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_imm := asImm12(v2)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(1, 1, 0, sa_shift, sa_imm, sa_xn_sp, sa_xd_sp))
    }
    // SUB  <Xd|SP>, <Xn|SP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXrOrSP(v0) &&
       isXrOrSP(v1) &&
       isLabel(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) &&
       (v0 == SP || v1 == SP) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_label := v2.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(1, 1, 0, sa_shift, abs12(sa_label), sa_xn_sp, sa_xd_sp)
        })
    }
    // SUB  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(0, 1, 0, sa_shift, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // SUB  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(1, 1, 0, sa_shift, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // SUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 16, sa_vn, sa_vd))
    }
    // SUB  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SUB")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 16, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SUB")
}

// SUBG instruction have one single form across one single category:
//
// 1. Subtract with Tag
//
//    SUBG  <Xd|SP>, <Xn|SP>, #<uimm6>, #<uimm4>
//
// Subtract with Tag subtracts an immediate value scaled by the Tag granule from
// the address in the source register, modifies the Logical Address Tag of the
// address using an immediate value, and writes the result to the destination
// register. Tags specified in GCR_EL1.Exclude are excluded from the possible
// outputs when modifying the Logical Address Tag.
//
func (self *Program) SUBG(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("SUBG", 4, asm.Operands { v0, v1, v2, v3 })
    if isXrOrSP(v0) &&
       isXrOrSP(v1) &&
       isInRange(v2, 0, 1008) && isMultipleOf(v2, 16) &&
       isInRange(v3, 0, 15) &&
       (v0 == SP || v1 == SP) {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xd_sp := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_uimm6 := asUimm6(v2)
        sa_uimm4 := asUimm4(v3)
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rd := uint32(0b00000)
        Rd |= sa_xd_sp
        return p.setins(addsub_immtags(1, 1, 0, sa_uimm6, 0, sa_uimm4, Rn, Rd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SUBG")
}

// SUBHN instruction have one single form across one single category:
//
// 1. Subtract returning High Narrow
//
//    SUBHN  <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>
//
// Subtract returning High Narrow. This instruction subtracts each vector element
// in the second source SIMD&FP register from the corresponding vector element in
// the first source SIMD&FP register, places the most significant half of the
// result into a vector, and writes the vector to the lower or upper half of the
// destination SIMD&FP register. All the values in this instruction are signed
// integer values.
//
// The results are truncated. For rounded results, see RSUBHN .
//
// The SUBHN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SUBHN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SUBHN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SUBHN", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8H, Vec4S, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SUBHN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SUBHN")
        }
        return p.setins(asimddiff(0, 0, sa_ta, sa_vm, 6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SUBHN")
}

// SUBHN2 instruction have one single form across one single category:
//
// 1. Subtract returning High Narrow
//
//    SUBHN2  <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>
//
// Subtract returning High Narrow. This instruction subtracts each vector element
// in the second source SIMD&FP register from the corresponding vector element in
// the first source SIMD&FP register, places the most significant half of the
// result into a vector, and writes the vector to the lower or upper half of the
// destination SIMD&FP register. All the values in this instruction are signed
// integer values.
//
// The results are truncated. For rounded results, see RSUBHN .
//
// The SUBHN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the SUBHN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SUBHN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SUBHN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8H, Vec4S, Vec2D) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for SUBHN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SUBHN2")
        }
        return p.setins(asimddiff(1, 0, sa_ta, sa_vm, 6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SUBHN2")
}

// SUBP instruction have one single form across one single category:
//
// 1. Subtract Pointer
//
//    SUBP  <Xd>, <Xn|SP>, <Xm|SP>
//
// Subtract Pointer subtracts the 56-bit address held in the second source register
// from the 56-bit address held in the first source register, sign-extends the
// result to 64-bits, and writes the result to the destination register.
//
func (self *Program) SUBP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SUBP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isXrOrSP(v1) && isXrOrSP(v2) && (v1 == SP || v2 == SP) {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_xm_sp := uint32(v2.(asm.Register).ID())
        Rm := uint32(0b00000)
        Rm |= sa_xm_sp
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rd := uint32(0b00000)
        Rd |= sa_xd
        return p.setins(dp_2src(1, 0, Rm, 0, Rn, Rd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SUBP")
}

// SUBPS instruction have one single form across one single category:
//
// 1. Subtract Pointer, setting Flags
//
//    SUBPS  <Xd>, <Xn|SP>, <Xm|SP>
//
// Subtract Pointer, setting Flags subtracts the 56-bit address held in the second
// source register from the 56-bit address held in the first source register, sign-
// extends the result to 64-bits, and writes the result to the destination
// register. It updates the condition flags based on the result of the subtraction.
//
func (self *Program) SUBPS(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SUBPS", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isXrOrSP(v1) && isXrOrSP(v2) && (v1 == SP || v2 == SP) {
        self.Arch.Require(FEAT_MTE)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_xm_sp := uint32(v2.(asm.Register).ID())
        Rm := uint32(0b00000)
        Rm |= sa_xm_sp
        Rn := uint32(0b00000)
        Rn |= sa_xn_sp
        Rd := uint32(0b00000)
        Rd |= sa_xd
        return p.setins(dp_2src(1, 1, Rm, 0, Rn, Rd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SUBPS")
}

// SUBS instruction have 8 forms across 3 categories:
//
// 1. Subtract (extended register), setting flags
//
//    SUBS  <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
//    SUBS  <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}
//
// Subtract (extended register), setting flags, subtracts a sign or zero-extended
// register value, followed by an optional left shift amount, from a register
// value, and writes the result to the destination register. The argument that is
// extended from the <Rm> register can be a byte, halfword, word, or doubleword. It
// updates the condition flags based on the result.
//
// 2. Subtract (immediate), setting flags
//
//    SUBS  <Wd>, <Wn|WSP>, #<imm>{, <shift>}
//    SUBS  <Wd>, <Wn|WSP>, <label>{, <shift>}
//    SUBS  <Xd>, <Xn|SP>, #<imm>{, <shift>}
//    SUBS  <Xd>, <Xn|SP>, <label>{, <shift>}
//
// Subtract (immediate), setting flags, subtracts an optionally-shifted immediate
// value from a register value, and writes the result to the destination register.
// It updates the condition flags based on the result.
//
// 3. Subtract (shifted register), setting flags
//
//    SUBS  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
//    SUBS  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
//
// Subtract (shifted register), setting flags, subtracts an optionally-shifted
// register value from a register value, and writes the result to the destination
// register. It updates the condition flags based on the result.
//
func (self *Program) SUBS(v0, v1, v2 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("SUBS", 3, asm.Operands { v0, v1, v2 })
        case 1  : p = self.alloc("SUBS", 4, asm.Operands { v0, v1, v2, vv[0] })
        default : panic("aarch64: instruction SUBS takes 3 or 4 operands")
    }
    // SUBS  <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWrOrWSP(v1) &&
       isWr(v2) &&
       (len(vv) == 0 && v1 == WSP || len(vv) == 1 && modt(vv[0]) == ModUXTW) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend := uint32(0b010)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend = 0b000
                case ModUXTH: sa_extend = 0b001
                case ModLSL: sa_extend = 0b010
                case ModUXTW: sa_extend = 0b010
                case ModUXTX: sa_extend = 0b011
                case ModSXTB: sa_extend = 0b100
                case ModSXTH: sa_extend = 0b101
                case ModSXTW: sa_extend = 0b110
                case ModSXTX: sa_extend = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_ext(0, 1, 1, 0, sa_wm, sa_extend, sa_amount, sa_wn_wsp, sa_wd))
    }
    // SUBS  <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXrOrSP(v1) &&
       isWrOrXr(v2) &&
       (len(vv) == 0 && v1 == SP || len(vv) == 1 && modt(vv[0]) == ModUXTX) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_extend_1 := uint32(0b011)
        var sa_r [4]uint32
        var sa_r__bit_mask [4]uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        switch true {
            case isWr(v2): sa_r = [4]uint32{0b000, 0b010, 0b100, 0b110}
            case isXr(v2): sa_r = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        switch true {
            case isWr(v2): sa_r__bit_mask = [4]uint32{0b110, 0b111, 0b110, 0b111}
            case isXr(v2): sa_r__bit_mask = [4]uint32{0b011}
            default: panic("aarch64: unreachable")
        }
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModUXTB: sa_extend_1 = 0b000
                case ModUXTH: sa_extend_1 = 0b001
                case ModUXTW: sa_extend_1 = 0b010
                case ModLSL: sa_extend_1 = 0b011
                case ModUXTX: sa_extend_1 = 0b011
                case ModSXTB: sa_extend_1 = 0b100
                case ModSXTH: sa_extend_1 = 0b101
                case ModSXTW: sa_extend_1 = 0b110
                case ModSXTX: sa_extend_1 = 0b111
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        if !matchany(sa_extend_1, &sa_r[0], &sa_r__bit_mask[0], 4) {
            panic("aarch64: invalid combination of operands for SUBS")
        }
        return p.setins(addsub_ext(1, 1, 1, 0, sa_m, sa_extend_1, sa_amount, sa_xn_sp, sa_xd))
    }
    // SUBS  <Wd>, <Wn|WSP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWrOrWSP(v1) &&
       isInRange(v2, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_imm := asImm12(v2)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(0, 1, 1, sa_shift, sa_imm, sa_wn_wsp, sa_wd))
    }
    // SUBS  <Wd>, <Wn|WSP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWrOrWSP(v1) &&
       isLabel(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn_wsp := uint32(v1.(asm.Register).ID())
        sa_label := v2.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(0, 1, 1, sa_shift, abs12(sa_label), sa_wn_wsp, sa_wd)
        })
    }
    // SUBS  <Xd>, <Xn|SP>, #<imm>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXrOrSP(v1) &&
       isInRange(v2, 0, 4095) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_imm := asImm12(v2)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setins(addsub_imm(1, 1, 1, sa_shift, sa_imm, sa_xn_sp, sa_xd))
    }
    // SUBS  <Xd>, <Xn|SP>, <label>{, <shift>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXrOrSP(v1) &&
       isLabel(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModLSL) && isIntLit(modn(vv[0]), 0, 12)) {
        p.Domain = asm.DomainGeneric
        var sa_shift uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn_sp := uint32(v1.(asm.Register).ID())
        sa_label := v2.(*asm.Label)
        if len(vv) >= 1 {
            switch {
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 0: sa_shift = 0b0
                case modt(vv[0]) == ModLSL && modn(vv[0]) == 12: sa_shift = 0b1
                default: panic("aarch64: invalid modifier flags")
            }
        }
        return p.setenc(func(pc uintptr) uint32 {
            return addsub_imm(1, 1, 1, sa_shift, abs12(sa_label), sa_xn_sp, sa_xd)
        })
    }
    // SUBS  <Wd>, <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       isWr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(0, 1, 1, sa_shift, sa_wm, sa_amount, sa_wn, sa_wd))
    }
    // SUBS  <Xd>, <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       isXr(v2) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(addsub_shift(1, 1, 1, sa_shift, sa_xm, sa_amount_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SUBS")
}

// SUDOT instruction have one single form across one single category:
//
// 1. Dot product with signed and unsigned integers (vector, by element)
//
//    SUDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.4B[<index>]
//
// Dot product index form with signed and unsigned integers. This instruction
// performs the dot product of the four signed 8-bit integer values in each 32-bit
// element of the first source register with the four unsigned 8-bit integer values
// in an indexed 32-bit element of the second source register, accumulating the
// result into the corresponding 32-bit element of the destination vector.
//
// From Armv8.2 to Armv8.5, this is an optional instruction. From Armv8.6 it is
// mandatory for implementations that include Advanced SIMD to support it.
// ID_AA64ISAR1_EL1 .I8MM indicates whether this instruction is supported.
//
func (self *Program) SUDOT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SUDOT", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVri(v2) &&
       vmoder(v2) == Mode4B {
        self.Arch.Require(FEAT_I8MM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b0
            case Vec16B: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for SUDOT")
        }
        return p.setins(asimdelem(
            sa_ta,
            0,
            0,
            mask(sa_index, 1),
            ubfx(sa_vm, 4, 1),
            mask(sa_vm, 4),
            15,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SUDOT")
}

// SUQADD instruction have 2 forms across one single category:
//
// 1. Signed saturating Accumulate of Unsigned value
//
//    SUQADD  <Vd>.<T>, <Vn>.<T>
//    SUQADD  <V><d>, <V><n>
//
// Signed saturating Accumulate of Unsigned value. This instruction adds the
// unsigned integer values of the vector elements in the source SIMD&FP register to
// corresponding signed integer values of the vector elements in the destination
// SIMD&FP register, and writes the resulting signed integer values to the
// destination SIMD&FP register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SUQADD(v0, v1 interface{}) *Instruction {
    p := self.alloc("SUQADD", 2, asm.Operands { v0, v1 })
    // SUQADD  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 0, ubfx(sa_t, 1, 2), 3, sa_vn, sa_vd))
    }
    // SUQADD  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for SUQADD")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(0, sa_v, 3, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SUQADD")
}

// SVC instruction have one single form across one single category:
//
// 1. Supervisor Call
//
//    SVC  #<imm>
//
// Supervisor Call causes an exception to be taken to EL1.
//
// On executing an SVC instruction, the PE records the exception as a Supervisor
// Call exception in ESR_ELx , using the EC value 0x15 , and the value of the
// immediate argument.
//
func (self *Program) SVC(v0 interface{}) *Instruction {
    p := self.alloc("SVC", 1, asm.Operands { v0 })
    if isInRange(v0, 0, 65535) {
        p.Domain = DomainSystem
        sa_imm := asUimm16(v0)
        return p.setins(exception(0, sa_imm, 0, 1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SVC")
}

// SWP instruction have 2 forms across one single category:
//
// 1. Swap word or doubleword in memory
//
//    SWP  <Ws>, <Wt>, [<Xn|SP>]
//    SWP  <Xs>, <Xt>, [<Xn|SP>]
//
// Swap word or doubleword in memory atomically loads a 32-bit word or 64-bit
// doubleword from a memory location, and stores the value held in a register back
// to the same memory location. The value initially loaded from memory is returned
// in the destination register.
//
//     * If the destination register is not one of WZR or XZR , SWPA and SWPAL
//       load from memory with acquire semantics.
//     * SWPL and SWPAL store to memory with release semantics.
//     * SWP has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWP", 3, asm.Operands { v0, v1, v2 })
    // SWP  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 0, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    // SWP  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 0, sa_xs, 1, 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SWP")
}

// SWPA instruction have 2 forms across one single category:
//
// 1. Swap word or doubleword in memory
//
//    SWPA  <Ws>, <Wt>, [<Xn|SP>]
//    SWPA  <Xs>, <Xt>, [<Xn|SP>]
//
// Swap word or doubleword in memory atomically loads a 32-bit word or 64-bit
// doubleword from a memory location, and stores the value held in a register back
// to the same memory location. The value initially loaded from memory is returned
// in the destination register.
//
//     * If the destination register is not one of WZR or XZR , SWPA and SWPAL
//       load from memory with acquire semantics.
//     * SWPL and SWPAL store to memory with release semantics.
//     * SWP has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPA", 3, asm.Operands { v0, v1, v2 })
    // SWPA  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 0, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    // SWPA  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 0, sa_xs, 1, 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SWPA")
}

// SWPAB instruction have one single form across one single category:
//
// 1. Swap byte in memory
//
//    SWPAB  <Ws>, <Wt>, [<Xn|SP>]
//
// Swap byte in memory atomically loads an 8-bit byte from a memory location, and
// stores the value held in a register back to the same memory location. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , SWPAB and SWPALB load from
//       memory with acquire semantics.
//     * SWPLB and SWPALB store to memory with release semantics.
//     * SWPB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPAB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPAB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 0, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPAB")
}

// SWPAH instruction have one single form across one single category:
//
// 1. Swap halfword in memory
//
//    SWPAH  <Ws>, <Wt>, [<Xn|SP>]
//
// Swap halfword in memory atomically loads a 16-bit halfword from a memory
// location, and stores the value held in a register back to the same memory
// location. The value initially loaded from memory is returned in the destination
// register.
//
//     * If the destination register is not WZR , SWPAH and SWPALH load from
//       memory with acquire semantics.
//     * SWPLH and SWPALH store to memory with release semantics.
//     * SWPH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPAH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPAH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 0, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPAH")
}

// SWPAL instruction have 2 forms across one single category:
//
// 1. Swap word or doubleword in memory
//
//    SWPAL  <Ws>, <Wt>, [<Xn|SP>]
//    SWPAL  <Xs>, <Xt>, [<Xn|SP>]
//
// Swap word or doubleword in memory atomically loads a 32-bit word or 64-bit
// doubleword from a memory location, and stores the value held in a register back
// to the same memory location. The value initially loaded from memory is returned
// in the destination register.
//
//     * If the destination register is not one of WZR or XZR , SWPA and SWPAL
//       load from memory with acquire semantics.
//     * SWPL and SWPAL store to memory with release semantics.
//     * SWP has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPAL", 3, asm.Operands { v0, v1, v2 })
    // SWPAL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 1, 1, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    // SWPAL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 1, 1, sa_xs, 1, 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SWPAL")
}

// SWPALB instruction have one single form across one single category:
//
// 1. Swap byte in memory
//
//    SWPALB  <Ws>, <Wt>, [<Xn|SP>]
//
// Swap byte in memory atomically loads an 8-bit byte from a memory location, and
// stores the value held in a register back to the same memory location. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , SWPAB and SWPALB load from
//       memory with acquire semantics.
//     * SWPLB and SWPALB store to memory with release semantics.
//     * SWPB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPALB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPALB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 1, 1, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPALB")
}

// SWPALH instruction have one single form across one single category:
//
// 1. Swap halfword in memory
//
//    SWPALH  <Ws>, <Wt>, [<Xn|SP>]
//
// Swap halfword in memory atomically loads a 16-bit halfword from a memory
// location, and stores the value held in a register back to the same memory
// location. The value initially loaded from memory is returned in the destination
// register.
//
//     * If the destination register is not WZR , SWPAH and SWPALH load from
//       memory with acquire semantics.
//     * SWPLH and SWPALH store to memory with release semantics.
//     * SWPH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPALH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPALH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 1, 1, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPALH")
}

// SWPB instruction have one single form across one single category:
//
// 1. Swap byte in memory
//
//    SWPB  <Ws>, <Wt>, [<Xn|SP>]
//
// Swap byte in memory atomically loads an 8-bit byte from a memory location, and
// stores the value held in a register back to the same memory location. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , SWPAB and SWPALB load from
//       memory with acquire semantics.
//     * SWPLB and SWPALB store to memory with release semantics.
//     * SWPB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 0, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPB")
}

// SWPH instruction have one single form across one single category:
//
// 1. Swap halfword in memory
//
//    SWPH  <Ws>, <Wt>, [<Xn|SP>]
//
// Swap halfword in memory atomically loads a 16-bit halfword from a memory
// location, and stores the value held in a register back to the same memory
// location. The value initially loaded from memory is returned in the destination
// register.
//
//     * If the destination register is not WZR , SWPAH and SWPALH load from
//       memory with acquire semantics.
//     * SWPLH and SWPALH store to memory with release semantics.
//     * SWPH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 0, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPH")
}

// SWPL instruction have 2 forms across one single category:
//
// 1. Swap word or doubleword in memory
//
//    SWPL  <Ws>, <Wt>, [<Xn|SP>]
//    SWPL  <Xs>, <Xt>, [<Xn|SP>]
//
// Swap word or doubleword in memory atomically loads a 32-bit word or 64-bit
// doubleword from a memory location, and stores the value held in a register back
// to the same memory location. The value initially loaded from memory is returned
// in the destination register.
//
//     * If the destination register is not one of WZR or XZR , SWPA and SWPAL
//       load from memory with acquire semantics.
//     * SWPL and SWPAL store to memory with release semantics.
//     * SWP has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPL", 3, asm.Operands { v0, v1, v2 })
    // SWPL  <Ws>, <Wt>, [<Xn|SP>]
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(2, 0, 0, 1, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    // SWPL  <Xs>, <Xt>, [<Xn|SP>]
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_xs := uint32(v0.(asm.Register).ID())
        sa_xt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(3, 0, 0, 1, sa_xs, 1, 0, sa_xn_sp, sa_xt))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SWPL")
}

// SWPLB instruction have one single form across one single category:
//
// 1. Swap byte in memory
//
//    SWPLB  <Ws>, <Wt>, [<Xn|SP>]
//
// Swap byte in memory atomically loads an 8-bit byte from a memory location, and
// stores the value held in a register back to the same memory location. The value
// initially loaded from memory is returned in the destination register.
//
//     * If the destination register is not WZR , SWPAB and SWPALB load from
//       memory with acquire semantics.
//     * SWPLB and SWPALB store to memory with release semantics.
//     * SWPB has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPLB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPLB", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(0, 0, 0, 1, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPLB")
}

// SWPLH instruction have one single form across one single category:
//
// 1. Swap halfword in memory
//
//    SWPLH  <Ws>, <Wt>, [<Xn|SP>]
//
// Swap halfword in memory atomically loads a 16-bit halfword from a memory
// location, and stores the value held in a register back to the same memory
// location. The value initially loaded from memory is returned in the destination
// register.
//
//     * If the destination register is not WZR , SWPAH and SWPALH load from
//       memory with acquire semantics.
//     * SWPLH and SWPALH store to memory with release semantics.
//     * SWPH has neither acquire nor release semantics.
//
// For more information about memory ordering semantics, see Load-Acquire, Store-
// Release .
//
// For information about memory accesses, see Load/Store addressing modes .
//
func (self *Program) SWPLH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPLH", 3, asm.Operands { v0, v1, v2 })
    if isWr(v0) &&
       isWr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE)
        p.Domain = asm.DomainGeneric
        sa_ws := uint32(v0.(asm.Register).ID())
        sa_wt := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop(1, 0, 0, 1, sa_ws, 1, 0, sa_xn_sp, sa_wt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPLH")
}

// SWPP instruction have one single form across one single category:
//
// 1. Swap quadword in memory
//
//    SWPP  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Swap quadword in memory atomically loads a 128-bit quadword from a memory
// location, and stores the value held in a pair of registers back to the same
// memory location. The value initially loaded from memory is returned in the same
// pair of registers.
//
//     * SWPPA and SWPPAL load from memory with acquire semantics.
//     * SWPPL and SWPPAL store to memory with release semantics.
//     * SWPP has neither acquire nor release semantics.
//
func (self *Program) SWPP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPP", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 0, sa_xt2, 1, 0, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPP")
}

// SWPPA instruction have one single form across one single category:
//
// 1. Swap quadword in memory
//
//    SWPPA  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Swap quadword in memory atomically loads a 128-bit quadword from a memory
// location, and stores the value held in a pair of registers back to the same
// memory location. The value initially loaded from memory is returned in the same
// pair of registers.
//
//     * SWPPA and SWPPAL load from memory with acquire semantics.
//     * SWPPL and SWPPAL store to memory with release semantics.
//     * SWPP has neither acquire nor release semantics.
//
func (self *Program) SWPPA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPPA", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 0, sa_xt2, 1, 0, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPPA")
}

// SWPPAL instruction have one single form across one single category:
//
// 1. Swap quadword in memory
//
//    SWPPAL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Swap quadword in memory atomically loads a 128-bit quadword from a memory
// location, and stores the value held in a pair of registers back to the same
// memory location. The value initially loaded from memory is returned in the same
// pair of registers.
//
//     * SWPPA and SWPPAL load from memory with acquire semantics.
//     * SWPPL and SWPPAL store to memory with release semantics.
//     * SWPP has neither acquire nor release semantics.
//
func (self *Program) SWPPAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPPAL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 1, 1, sa_xt2, 1, 0, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPPAL")
}

// SWPPL instruction have one single form across one single category:
//
// 1. Swap quadword in memory
//
//    SWPPL  <Xt1>, <Xt2>, [<Xn|SP>]
//
// Swap quadword in memory atomically loads a 128-bit quadword from a memory
// location, and stores the value held in a pair of registers back to the same
// memory location. The value initially loaded from memory is returned in the same
// pair of registers.
//
//     * SWPPA and SWPPAL load from memory with acquire semantics.
//     * SWPPL and SWPPAL store to memory with release semantics.
//     * SWPP has neither acquire nor release semantics.
//
func (self *Program) SWPPL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("SWPPL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) &&
       isXr(v1) &&
       isMem(v2) &&
       isXrOrSP(mbase(v2)) &&
       midx(v2) == nil &&
       moffs(v2) == 0 &&
       mext(v2) == Basic {
        self.Arch.Require(FEAT_LSE128)
        p.Domain = asm.DomainGeneric
        sa_xt1 := uint32(v0.(asm.Register).ID())
        sa_xt2 := uint32(v1.(asm.Register).ID())
        sa_xn_sp := uint32(mbase(v2).ID())
        return p.setins(memop_128(0, 0, 1, sa_xt2, 1, 0, sa_xn_sp, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SWPPL")
}

// SXTB instruction have 2 forms across one single category:
//
// 1. Signed Extend Byte
//
//    SXTB  <Wd>, <Wn>
//    SXTB  <Xd>, <Wn>
//
// Signed Extend Byte extracts an 8-bit value from a register, sign-extends it to
// the size of the register, and writes the result to the destination register.
//
func (self *Program) SXTB(v0, v1 interface{}) *Instruction {
    p := self.alloc("SXTB", 2, asm.Operands { v0, v1 })
    // SXTB  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(bitfield(0, 0, 0, 0, 7, sa_wn, sa_wd))
    }
    // SXTB  <Xd>, <Wn>
    if isXr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(bitfield(1, 0, 1, 0, 7, sa_wn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SXTB")
}

// SXTH instruction have 2 forms across one single category:
//
// 1. Sign Extend Halfword
//
//    SXTH  <Wd>, <Wn>
//    SXTH  <Xd>, <Wn>
//
// Sign Extend Halfword extracts a 16-bit value, sign-extends it to the size of the
// register, and writes the result to the destination register.
//
func (self *Program) SXTH(v0, v1 interface{}) *Instruction {
    p := self.alloc("SXTH", 2, asm.Operands { v0, v1 })
    // SXTH  <Wd>, <Wn>
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(bitfield(0, 0, 0, 0, 15, sa_wn, sa_wd))
    }
    // SXTH  <Xd>, <Wn>
    if isXr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(bitfield(1, 0, 1, 0, 15, sa_wn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for SXTH")
}

// SXTL instruction have one single form across one single category:
//
// 1. Signed extend Long
//
//    SXTL  <Vd>.<Ta>, <Vn>.<Tb>
//
// Signed extend Long. This instruction duplicates each vector element in the lower
// or upper half of the source SIMD&FP register into a vector, and writes the
// vector to the destination SIMD&FP register. The destination vector elements are
// twice as long as the source vector elements. All the values in this instruction
// are signed integer values.
//
// The SXTL instruction extracts the source vector from the lower half of the
// source register. The SXTL2 instruction extracts the source vector from the upper
// half of the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SXTL(v0, v1 interface{}) *Instruction {
    p := self.alloc("SXTL", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        if sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SXTL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for SXTL")
        }
        return p.setins(asimdshf(0, 0, sa_ta, 0, 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SXTL")
}

// SXTL2 instruction have one single form across one single category:
//
// 1. Signed extend Long
//
//    SXTL2  <Vd>.<Ta>, <Vn>.<Tb>
//
// Signed extend Long. This instruction duplicates each vector element in the lower
// or upper half of the source SIMD&FP register into a vector, and writes the
// vector to the destination SIMD&FP register. The destination vector elements are
// twice as long as the source vector elements. All the values in this instruction
// are signed integer values.
//
// The SXTL instruction extracts the source vector from the lower half of the
// source register. The SXTL2 instruction extracts the source vector from the upper
// half of the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) SXTL2(v0, v1 interface{}) *Instruction {
    p := self.alloc("SXTL2", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        if sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for SXTL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for SXTL2")
        }
        return p.setins(asimdshf(1, 0, sa_ta, 0, 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SXTL2")
}

// SXTW instruction have one single form across one single category:
//
// 1. Sign Extend Word
//
//    SXTW  <Xd>, <Wn>
//
// Sign Extend Word sign-extends a word to the size of the register, and writes the
// result to the destination register.
//
func (self *Program) SXTW(v0, v1 interface{}) *Instruction {
    p := self.alloc("SXTW", 2, asm.Operands { v0, v1 })
    if isXr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(bitfield(1, 0, 1, 0, 31, sa_wn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SXTW")
}

// SYS instruction have one single form across one single category:
//
// 1. System instruction
//
//    SYS  #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>}
//
// System instruction. For more information, see Op0 equals 0b01, cache
// maintenance, TLB maintenance, and address translation instructions for the
// encodings of System instructions.
//
func (self *Program) SYS(v0, v1, v2, v3 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("SYS", 4, asm.Operands { v0, v1, v2, v3 })
        case 1  : p = self.alloc("SYS", 5, asm.Operands { v0, v1, v2, v3, vv[0] })
        default : panic("aarch64: instruction SYS takes 4 or 5 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) &&
       isInRange(v0, 0, 7) &&
       isUimm4(v1) &&
       isUimm4(v2) &&
       isInRange(v3, 0, 7) &&
       (len(vv) == 0 || isXr(vv[0])) {
        p.Domain = DomainSystem
        sa_xt := uint32(0b11111)
        sa_op1 := asUimm3(v0)
        sa_cn := asUimm4(v1)
        sa_cm := asUimm4(v2)
        sa_op2 := asUimm3(v3)
        if len(vv) >= 1 {
            sa_xt = uint32(vv[0].(asm.Register).ID())
        }
        return p.setins(systeminstrs(0, sa_op1, sa_cn, sa_cm, sa_op2, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SYS")
}

// SYSL instruction have one single form across one single category:
//
// 1. System instruction with result
//
//    SYSL  <Xt>, #<op1>, <Cn>, <Cm>, #<op2>
//
// System instruction with result. For more information, see Op0 equals 0b01, cache
// maintenance, TLB maintenance, and address translation instructions for the
// encodings of System instructions.
//
func (self *Program) SYSL(v0, v1, v2, v3, v4 interface{}) *Instruction {
    p := self.alloc("SYSL", 5, asm.Operands { v0, v1, v2, v3, v4 })
    if isXr(v0) && isInRange(v1, 0, 7) && isUimm4(v2) && isUimm4(v3) && isInRange(v4, 0, 7) {
        p.Domain = DomainSystem
        sa_xt := uint32(v0.(asm.Register).ID())
        sa_op1 := asUimm3(v1)
        sa_cn := asUimm4(v2)
        sa_cm := asUimm4(v3)
        sa_op2 := asUimm3(v4)
        return p.setins(systeminstrs(1, sa_op1, sa_cn, sa_cm, sa_op2, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SYSL")
}

// SYSP instruction have one single form across one single category:
//
// 1. 128-bit System instruction
//
//    SYSP  #<op1>, <Cn>, <Cm>, #<op2>{, <Xt1>, <Xt2>}
//
// 128-bit System instruction.
//
func (self *Program) SYSP(v0, v1, v2, v3 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("SYSP", 4, asm.Operands { v0, v1, v2, v3 })
        case 2  : p = self.alloc("SYSP", 6, asm.Operands { v0, v1, v2, v3, vv[0], vv[1] })
        default : panic("aarch64: instruction SYSP takes 4 or 6 operands")
    }
    if (len(vv) == 0 || len(vv) == 2) &&
       isInRange(v0, 0, 6) &&
       isUimm4(v1) &&
       isUimm4(v2) &&
       isInRange(v3, 0, 7) &&
       (len(vv) == 0 || isXr(vv[0])) &&
       (len(vv) < 2 || isXr(vv[1])) {
        self.Arch.Require(FEAT_SYSINSTR128)
        p.Domain = DomainSystem
        sa_xt1 := uint32(0b11111)
        sa_xt2 := uint32(0b11111)
        sa_op1 := asUimm3(v0)
        sa_cn := asUimm4(v1)
        sa_cm := asUimm4(v2)
        sa_op2 := asUimm3(v3)
        if len(vv) >= 2 {
            sa_xt1 = uint32(vv[0].(asm.Register).ID())
            sa_xt2 = uint32(vv[1].(asm.Register).ID())
        }
        if sa_xt1 != sa_xt2 {
            panic("aarch64: invalid combination of operands for SYSP")
        }
        return p.setins(syspairinstrs(0, sa_op1, sa_cn, sa_cm, sa_op2, sa_xt1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for SYSP")
}

// TBL instruction have 4 forms across one single category:
//
// 1. Table vector Lookup
//
//    TBL  <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>
//    TBL  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>
//    TBL  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>
//    TBL  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>
//
// Table vector Lookup. This instruction reads each value from the vector elements
// in the index source SIMD&FP register, uses each result as an index to perform a
// lookup in a table of bytes that is described by one to four source table SIMD&FP
// registers, places the lookup result in a vector, and writes the vector to the
// destination SIMD&FP register. If an index is out of range for the table, the
// result for that lookup is 0. If more than one source register is used to
// describe the table, the first source register describes the lowest bytes of the
// table.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) TBL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("TBL", 3, asm.Operands { v0, v1, v2 })
    // TBL  <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVec1(v1) &&
       velm(v1) == Vec16B &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_ta = 0b0
            case Vec16B: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(Vector).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdtbl(sa_ta, 0, sa_vm, 0, 0, sa_vn, sa_vd))
    }
    // TBL  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVec2(v1) &&
       velm(v1) == Vec16B &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_ta = 0b0
            case Vec16B: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn_1 := uint32(v1.(Vector).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdtbl(sa_ta, 0, sa_vm, 1, 0, sa_vn_1, sa_vd))
    }
    // TBL  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVec3(v1) &&
       velm(v1) == Vec16B &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_ta = 0b0
            case Vec16B: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn_1 := uint32(v1.(Vector).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdtbl(sa_ta, 0, sa_vm, 2, 0, sa_vn_1, sa_vd))
    }
    // TBL  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVec4(v1) &&
       velm(v1) == Vec16B &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_ta = 0b0
            case Vec16B: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn_1 := uint32(v1.(Vector).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdtbl(sa_ta, 0, sa_vm, 3, 0, sa_vn_1, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for TBL")
}

// TBNZ instruction have 2 forms across one single category:
//
// 1. Test bit and Branch if Nonzero
//
//    TBNZ  <R><t>, #<imm>, <label>
//    TBNZ  <R><t>, #<imm>, .±<offs>
//
// Test bit and Branch if Nonzero compares the value of a bit in a general-purpose
// register with zero, and conditionally branches to a label at a PC-relative
// offset if the comparison is not equal. It provides a hint that this is not a
// subroutine call or return. This instruction does not affect condition flags.
//
func (self *Program) TBNZ(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("TBNZ", 3, asm.Operands { v0, v1, v2 })
    // TBNZ  <R><t>, #<imm>, <label>
    if isWrOrXr(v0) && isInRange(v1, 0, 63) && isLabel(v2) {
        p.Domain = asm.DomainGeneric
        var sa_r uint32
        sa_t := uint32(v0.(asm.Register).ID())
        switch true {
            case isWr(v0): sa_r = 0b0
            case isXr(v0): sa_r = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm := asUimm6(v1)
        sa_label := v2.(*asm.Label)
        if mask(sa_imm, 1) != sa_r {
            panic("aarch64: invalid combination of operands for TBNZ")
        }
        return p.setenc(func(pc uintptr) uint32 {
            return testbranch(mask(sa_imm, 1), 1, ubfx(sa_imm, 1, 5), pcrel14(sa_label, pc), sa_t)
        })
    }
    // TBNZ  <R><t>, #<imm>, .±<offs>
    if isWrOrXr(v0) && isInRange(v1, 0, 63) && isPCrel(v2) {
        p.Domain = asm.DomainGeneric
        var sa_r uint32
        sa_t := uint32(v0.(asm.Register).ID())
        switch true {
            case isWr(v0): sa_r = 0b0
            case isXr(v0): sa_r = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm := asUimm6(v1)
        ra_pcrel := v2.(asm.RelativeOffset)
        if mask(sa_imm, 1) != sa_r {
            panic("aarch64: invalid combination of operands for TBNZ")
        }
        return p.setins(testbranch(mask(sa_imm, 1), 1, ubfx(sa_imm, 1, 5), rel14(ra_pcrel), sa_t))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for TBNZ")
}

// TBX instruction have 4 forms across one single category:
//
// 1. Table vector lookup extension
//
//    TBX  <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>
//    TBX  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>
//    TBX  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>
//    TBX  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>
//
// Table vector lookup extension. This instruction reads each value from the vector
// elements in the index source SIMD&FP register, uses each result as an index to
// perform a lookup in a table of bytes that is described by one to four source
// table SIMD&FP registers, places the lookup result in a vector, and writes the
// vector to the destination SIMD&FP register. If an index is out of range for the
// table, the existing value in the vector element of the destination register is
// left unchanged. If more than one source register is used to describe the table,
// the first source register describes the lowest bytes of the table.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) TBX(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("TBX", 3, asm.Operands { v0, v1, v2 })
    // TBX  <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVec1(v1) &&
       velm(v1) == Vec16B &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_ta = 0b0
            case Vec16B: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(Vector).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdtbl(sa_ta, 0, sa_vm, 0, 1, sa_vn, sa_vd))
    }
    // TBX  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVec2(v1) &&
       velm(v1) == Vec16B &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_ta = 0b0
            case Vec16B: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn_1 := uint32(v1.(Vector).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdtbl(sa_ta, 0, sa_vm, 1, 1, sa_vn_1, sa_vd))
    }
    // TBX  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVec3(v1) &&
       velm(v1) == Vec16B &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_ta = 0b0
            case Vec16B: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn_1 := uint32(v1.(Vector).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdtbl(sa_ta, 0, sa_vm, 2, 1, sa_vn_1, sa_vd))
    }
    // TBX  <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B) &&
       isVec4(v1) &&
       velm(v1) == Vec16B &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v0) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_ta = 0b0
            case Vec16B: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn_1 := uint32(v1.(Vector).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdtbl(sa_ta, 0, sa_vm, 3, 1, sa_vn_1, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for TBX")
}

// TBZ instruction have 2 forms across one single category:
//
// 1. Test bit and Branch if Zero
//
//    TBZ  <R><t>, #<imm>, <label>
//    TBZ  <R><t>, #<imm>, .±<offs>
//
// Test bit and Branch if Zero compares the value of a test bit with zero, and
// conditionally branches to a label at a PC-relative offset if the comparison is
// equal. It provides a hint that this is not a subroutine call or return. This
// instruction does not affect condition flags.
//
func (self *Program) TBZ(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("TBZ", 3, asm.Operands { v0, v1, v2 })
    // TBZ  <R><t>, #<imm>, <label>
    if isWrOrXr(v0) && isInRange(v1, 0, 63) && isLabel(v2) {
        p.Domain = asm.DomainGeneric
        var sa_r uint32
        sa_t := uint32(v0.(asm.Register).ID())
        switch true {
            case isWr(v0): sa_r = 0b0
            case isXr(v0): sa_r = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm := asUimm6(v1)
        sa_label := v2.(*asm.Label)
        if mask(sa_imm, 1) != sa_r {
            panic("aarch64: invalid combination of operands for TBZ")
        }
        return p.setenc(func(pc uintptr) uint32 {
            return testbranch(mask(sa_imm, 1), 0, ubfx(sa_imm, 1, 5), pcrel14(sa_label, pc), sa_t)
        })
    }
    // TBZ  <R><t>, #<imm>, .±<offs>
    if isWrOrXr(v0) && isInRange(v1, 0, 63) && isPCrel(v2) {
        p.Domain = asm.DomainGeneric
        var sa_r uint32
        sa_t := uint32(v0.(asm.Register).ID())
        switch true {
            case isWr(v0): sa_r = 0b0
            case isXr(v0): sa_r = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_imm := asUimm6(v1)
        ra_pcrel := v2.(asm.RelativeOffset)
        if mask(sa_imm, 1) != sa_r {
            panic("aarch64: invalid combination of operands for TBZ")
        }
        return p.setins(testbranch(mask(sa_imm, 1), 0, ubfx(sa_imm, 1, 5), rel14(ra_pcrel), sa_t))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for TBZ")
}

// TCANCEL instruction have one single form across one single category:
//
// 1. Cancel current transaction
//
//    TCANCEL  #<imm>
//
// This instruction exits Transactional state and discards all state modifications
// that were performed transactionally. Execution continues at the instruction that
// follows the TSTART instruction of the outer transaction. The destination
// register of the TSTART instruction of the outer transaction is written with the
// immediate operand of TCANCEL.
//
func (self *Program) TCANCEL(v0 interface{}) *Instruction {
    p := self.alloc("TCANCEL", 1, asm.Operands { v0 })
    if isInRange(v0, 0, 65535) {
        self.Arch.Require(FEAT_TME)
        p.Domain = DomainSystem
        sa_imm := asUimm16(v0)
        return p.setins(exception(3, sa_imm, 0, 0))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for TCANCEL")
}

// TCOMMIT instruction have one single form across one single category:
//
// 1. Commit current transaction
//
//    TCOMMIT
//
// This instruction commits the current transaction. If the current transaction is
// an outer transaction, then Transactional state is exited, and all state
// modifications performed transactionally are committed to the architectural
// state. TCOMMIT takes no inputs and returns no value.
//
// Execution of TCOMMIT is UNDEFINED in Non-transactional state.
//
func (self *Program) TCOMMIT() *Instruction {
    p := self.alloc("TCOMMIT", 0, asm.Operands {})
    self.Arch.Require(FEAT_TME)
    p.Domain = DomainSystem
    return p.setins(barriers(0, 3, 31))
}

// TLBI instruction have one single form across one single category:
//
// 1. TLB Invalidate operation
//
//    TLBI  <tlbi_op>{, <Xt>}
//
// TLB Invalidate operation. For more information, see op0==0b01, cache
// maintenance, TLB maintenance, and address translation instructions .
//
func (self *Program) TLBI(v0 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("TLBI", 1, asm.Operands { v0 })
        case 1  : p = self.alloc("TLBI", 2, asm.Operands { v0, vv[0] })
        default : panic("aarch64: instruction TLBI takes 1 or 2 operands")
    }
    if (len(vv) == 0 || len(vv) == 1) && isTLBIOption(v0) && (len(vv) == 0 || isXr(vv[0])) {
        p.Domain = DomainSystem
        sa_xt := uint32(0b11111)
        sa_tlbi_op := uint32(v0.(TLBIOption))
        if len(vv) >= 1 {
            sa_xt = uint32(vv[0].(asm.Register).ID())
        }
        return p.setins(systeminstrs(
            0,
            ubfx(sa_tlbi_op, 11, 3),
            ubfx(sa_tlbi_op, 7, 4),
            ubfx(sa_tlbi_op, 3, 4),
            mask(sa_tlbi_op, 3),
            sa_xt,
        ))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for TLBI")
}

// TLBIP instruction have one single form across one single category:
//
// 1. TLB Invalidate Pair operation
//
//    TLBIP  <tlbip_op>{, <Xt1>, <Xt2>}
//
// TLB Invalidate Pair operation.
//
func (self *Program) TLBIP(v0 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("TLBIP", 1, asm.Operands { v0 })
        case 2  : p = self.alloc("TLBIP", 3, asm.Operands { v0, vv[0], vv[1] })
        default : panic("aarch64: instruction TLBIP takes 1 or 3 operands")
    }
    if (len(vv) == 0 || len(vv) == 2) &&
       isTLBIPOption(v0) &&
       (len(vv) == 0 || isXr(vv[0])) &&
       (len(vv) < 2 || isXr(vv[1])) {
        self.Arch.Require(FEAT_D128)
        p.Domain = DomainSystem
        sa_xt1 := uint32(0b11111)
        sa_xt2 := uint32(0b11111)
        sa_tlbip_op := uint32(v0.(TLBIOption))
        if len(vv) >= 2 {
            sa_xt1 = uint32(vv[0].(asm.Register).ID())
            sa_xt2 = uint32(vv[1].(asm.Register).ID())
        }
        if sa_xt1 != sa_xt2 {
            panic("aarch64: invalid combination of operands for TLBIP")
        }
        return p.setins(syspairinstrs(
            0,
            ubfx(sa_tlbip_op, 11, 3),
            ubfx(sa_tlbip_op, 7, 4),
            ubfx(sa_tlbip_op, 3, 4),
            mask(sa_tlbip_op, 3),
            sa_xt1,
        ))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for TLBIP")
}

// TRCIT instruction have one single form across one single category:
//
// 1. Trace Instrumentation
//
//    TRCIT  <Xt>
//
// Trace Instrumentation generates an instrumentation trace packet that contains
// the value of the provided register.
//
func (self *Program) TRCIT(v0 interface{}) *Instruction {
    p := self.alloc("TRCIT", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_ITE)
        p.Domain = DomainSystem
        sa_xt_1 := uint32(v0.(asm.Register).ID())
        return p.setins(systeminstrs(0, 3, 7, 2, 7, sa_xt_1))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for TRCIT")
}

// TRN1 instruction have one single form across one single category:
//
// 1. Transpose vectors (primary)
//
//    TRN1  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Transpose vectors (primary). This instruction reads corresponding even-numbered
// vector elements from the two source SIMD&FP registers, starting at zero, places
// each result into consecutive elements of a vector, and writes the vector to the
// destination SIMD&FP register. Vector elements from the first source register are
// placed into even-numbered elements of the destination vector, starting at zero,
// while vector elements from the second source register are placed into odd-
// numbered elements of the destination vector.
//
// NOTE: 
//     By using this instruction with TRN2 , a 2 x 2 matrix can be transposed.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.trn1_trn2_doubleword_operation.svg]
// TRN1 and TRN2 halfword operations where Q = 0
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) TRN1(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("TRN1", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdperm(mask(sa_t, 1), ubfx(sa_t, 1, 2), sa_vm, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for TRN1")
}

// TRN2 instruction have one single form across one single category:
//
// 1. Transpose vectors (secondary)
//
//    TRN2  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Transpose vectors (secondary). This instruction reads corresponding odd-numbered
// vector elements from the two source SIMD&FP registers, places each result into
// consecutive elements of a vector, and writes the vector to the destination
// SIMD&FP register. Vector elements from the first source register are placed into
// even-numbered elements of the destination vector, starting at zero, while vector
// elements from the second source register are placed into odd-numbered elements
// of the destination vector.
//
// NOTE: 
//     By using this instruction with TRN1 , a 2 x 2 matrix can be transposed.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.trn1_trn2_doubleword_operation.svg]
// TRN1 and TRN2 halfword operations where Q = 0
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) TRN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("TRN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdperm(mask(sa_t, 1), ubfx(sa_t, 1, 2), sa_vm, 6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for TRN2")
}

// TSB instruction have one single form across one single category:
//
// 1. Trace Synchronization Barrier
//
//    TSB CSYNC
//
// Trace Synchronization Barrier. This instruction is a barrier that synchronizes
// the trace operations of instructions, see Trace Synchronization Buffer (TSB
// CSYNC) .
//
// If FEAT_TRF is not implemented, this instruction executes as a NOP .
//
func (self *Program) TSB(v0 interface{}) *Instruction {
    p := self.alloc("TSB", 1, asm.Operands { v0 })
    if v0 == CSYNC {
        self.Arch.Require(FEAT_TRF)
        p.Domain = DomainSystem
        return p.setins(hints(2, 2))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for TSB")
}

// TST instruction have 4 forms across 2 categories:
//
// 1. Test bits (immediate)
//
//    TST  <Wn>, #<imm>
//    TST  <Xn>, #<imm>
//
// 2. Test (shifted register)
//
//    TST  <Wn>, <Wm>{, <shift> #<amount>}
//    TST  <Xn>, <Xm>{, <shift> #<amount>}
//
// Test (shifted register) performs a bitwise AND operation on a register value and
// an optionally-shifted register value. It updates the condition flags based on
// the result, and discards the result.
//
func (self *Program) TST(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("TST", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("TST", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction TST takes 2 or 3 operands")
    }
    // TST  <Wn>, #<imm>
    if isWr(v0) && isMask32(v1) {
        p.Domain = asm.DomainGeneric
        sa_wn := uint32(v0.(asm.Register).ID())
        sa_imm := asMaskOp(v1)
        return p.setins(log_imm(0, 3, 0, ubfx(sa_imm, 6, 6), mask(sa_imm, 6), sa_wn, 31))
    }
    // TST  <Xn>, #<imm>
    if isXr(v0) && isMask64(v1) {
        p.Domain = asm.DomainGeneric
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_imm_1 := asMaskOp(v1)
        return p.setins(log_imm(1, 3, ubfx(sa_imm_1, 12, 1), ubfx(sa_imm_1, 6, 6), mask(sa_imm_1, 6), sa_xn, 31))
    }
    // TST  <Wn>, <Wm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isWr(v0) &&
       isWr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount := uint32(0)
        sa_shift := uint32(0b00)
        sa_wn := uint32(v0.(asm.Register).ID())
        sa_wm := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(0, 3, sa_shift, 0, sa_wm, sa_amount, sa_wn, 31))
    }
    // TST  <Xn>, <Xm>{, <shift> #<amount>}
    if (len(vv) == 0 || len(vv) == 1) &&
       isXr(v0) &&
       isXr(v1) &&
       (len(vv) == 0 || isMods(vv[0], ModASR, ModLSL, ModLSR, ModROR)) {
        p.Domain = asm.DomainGeneric
        sa_amount_1 := uint32(0)
        sa_shift := uint32(0b00)
        sa_xn := uint32(v0.(asm.Register).ID())
        sa_xm := uint32(v1.(asm.Register).ID())
        if len(vv) >= 1 {
            switch vv[0].(Modifier).Type() {
                case ModLSL: sa_shift = 0b00
                case ModLSR: sa_shift = 0b01
                case ModASR: sa_shift = 0b10
                case ModROR: sa_shift = 0b11
                default: panic("aarch64: invalid modifier flags")
            }
            sa_amount_1 = uint32(vv[0].(Modifier).Amount())
        }
        return p.setins(log_shift(1, 3, sa_shift, 0, sa_xm, sa_amount_1, sa_xn, 31))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for TST")
}

// TSTART instruction have one single form across one single category:
//
// 1. Start transaction
//
//    TSTART  <Xt>
//
// This instruction starts a new transaction. If the transaction started
// successfully, the destination register is set to zero. If the transaction failed
// or was canceled, then all state modifications that were performed
// transactionally are discarded and the destination register is written with a
// nonzero value that encodes the cause of the failure.
//
func (self *Program) TSTART(v0 interface{}) *Instruction {
    p := self.alloc("TSTART", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_TME)
        p.Domain = DomainSystem
        sa_xt := uint32(v0.(asm.Register).ID())
        return p.setins(systemresult(3, 3, 0, 3, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for TSTART")
}

// TTEST instruction have one single form across one single category:
//
// 1. Test transaction state
//
//    TTEST  <Xt>
//
// This instruction writes the depth of the transaction to the destination
// register, or the value 0 otherwise.
//
func (self *Program) TTEST(v0 interface{}) *Instruction {
    p := self.alloc("TTEST", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_TME)
        p.Domain = DomainSystem
        sa_xt := uint32(v0.(asm.Register).ID())
        return p.setins(systemresult(3, 3, 1, 3, sa_xt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for TTEST")
}

// UABA instruction have one single form across one single category:
//
// 1. Unsigned Absolute difference and Accumulate
//
//    UABA  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unsigned Absolute difference and Accumulate. This instruction subtracts the
// elements of the vector of the second source SIMD&FP register from the
// corresponding elements of the first source SIMD&FP register, and accumulates the
// absolute values of the results into the elements of the vector of the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UABA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UABA", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 15, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UABA")
}

// UABAL instruction have one single form across one single category:
//
// 1. Unsigned Absolute difference and Accumulate Long
//
//    UABAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Absolute difference and Accumulate Long. This instruction subtracts the
// vector elements in the lower or upper half of the second source SIMD&FP register
// from the corresponding vector elements of the first source SIMD&FP register, and
// accumulates the absolute values of the results into the vector elements of the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the source vector elements. All the values in this instruction are unsigned
// integer values.
//
// The UABAL instruction extracts each source vector from the lower half of each
// source register. The UABAL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UABAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UABAL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UABAL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UABAL")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 5, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UABAL")
}

// UABAL2 instruction have one single form across one single category:
//
// 1. Unsigned Absolute difference and Accumulate Long
//
//    UABAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Absolute difference and Accumulate Long. This instruction subtracts the
// vector elements in the lower or upper half of the second source SIMD&FP register
// from the corresponding vector elements of the first source SIMD&FP register, and
// accumulates the absolute values of the results into the vector elements of the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the source vector elements. All the values in this instruction are unsigned
// integer values.
//
// The UABAL instruction extracts each source vector from the lower half of each
// source register. The UABAL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UABAL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UABAL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UABAL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UABAL2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 5, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UABAL2")
}

// UABD instruction have one single form across one single category:
//
// 1. Unsigned Absolute Difference (vector)
//
//    UABD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unsigned Absolute Difference (vector). This instruction subtracts the elements
// of the vector of the second source SIMD&FP register from the corresponding
// elements of the first source SIMD&FP register, places the absolute values of the
// results into a vector, and writes the vector to the destination SIMD&FP
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UABD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UABD", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 14, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UABD")
}

// UABDL instruction have one single form across one single category:
//
// 1. Unsigned Absolute Difference Long
//
//    UABDL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Absolute Difference Long. This instruction subtracts the vector
// elements in the lower or upper half of the second source SIMD&FP register from
// the corresponding vector elements of the first source SIMD&FP register, places
// the absolute value of the result into a vector, and writes the vector to the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the source vector elements. All the values in this instruction are unsigned
// integer values.
//
// The UABDL instruction extracts each source vector from the lower half of each
// source register. The UABDL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UABDL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UABDL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UABDL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UABDL")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 7, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UABDL")
}

// UABDL2 instruction have one single form across one single category:
//
// 1. Unsigned Absolute Difference Long
//
//    UABDL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Absolute Difference Long. This instruction subtracts the vector
// elements in the lower or upper half of the second source SIMD&FP register from
// the corresponding vector elements of the first source SIMD&FP register, places
// the absolute value of the result into a vector, and writes the vector to the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the source vector elements. All the values in this instruction are unsigned
// integer values.
//
// The UABDL instruction extracts each source vector from the lower half of each
// source register. The UABDL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UABDL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UABDL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UABDL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UABDL2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 7, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UABDL2")
}

// UADALP instruction have one single form across one single category:
//
// 1. Unsigned Add and Accumulate Long Pairwise
//
//    UADALP  <Vd>.<Ta>, <Vn>.<Tb>
//
// Unsigned Add and Accumulate Long Pairwise. This instruction adds pairs of
// adjacent unsigned integer values from the vector in the source SIMD&FP register
// and accumulates the results with the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the source vector
// elements.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UADALP(v0, v1 interface{}) *Instruction {
    p := self.alloc("UADALP", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec1D, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_ta = 0b000
            case Vec8H: sa_ta = 0b001
            case Vec2S: sa_ta = 0b010
            case Vec4S: sa_ta = 0b011
            case Vec1D: sa_ta = 0b100
            case Vec2D: sa_ta = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_ta, 1, 2) != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UADALP")
        }
        if mask(sa_ta, 1) != mask(sa_tb, 1) {
            panic("aarch64: invalid combination of operands for UADALP")
        }
        return p.setins(asimdmisc(mask(sa_ta, 1), 1, ubfx(sa_ta, 1, 2), 6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UADALP")
}

// UADDL instruction have one single form across one single category:
//
// 1. Unsigned Add Long (vector)
//
//    UADDL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Add Long (vector). This instruction adds each vector element in the
// lower or upper half of the first source SIMD&FP register to the corresponding
// vector element of the second source SIMD&FP register, places the result into a
// vector, and writes the vector to the destination SIMD&FP register. The
// destination vector elements are twice as long as the source vector elements. All
// the values in this instruction are unsigned integer values.
//
// The UADDL instruction extracts each source vector from the lower half of each
// source register. The UADDL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UADDL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UADDL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UADDL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UADDL")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 0, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UADDL")
}

// UADDL2 instruction have one single form across one single category:
//
// 1. Unsigned Add Long (vector)
//
//    UADDL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Add Long (vector). This instruction adds each vector element in the
// lower or upper half of the first source SIMD&FP register to the corresponding
// vector element of the second source SIMD&FP register, places the result into a
// vector, and writes the vector to the destination SIMD&FP register. The
// destination vector elements are twice as long as the source vector elements. All
// the values in this instruction are unsigned integer values.
//
// The UADDL instruction extracts each source vector from the lower half of each
// source register. The UADDL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UADDL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UADDL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UADDL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UADDL2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 0, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UADDL2")
}

// UADDLP instruction have one single form across one single category:
//
// 1. Unsigned Add Long Pairwise
//
//    UADDLP  <Vd>.<Ta>, <Vn>.<Tb>
//
// Unsigned Add Long Pairwise. This instruction adds pairs of adjacent unsigned
// integer values from the vector in the source SIMD&FP register, places the result
// into a vector, and writes the vector to the destination SIMD&FP register. The
// destination vector elements are twice as long as the source vector elements.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UADDLP(v0, v1 interface{}) *Instruction {
    p := self.alloc("UADDLP", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec1D, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_ta = 0b000
            case Vec8H: sa_ta = 0b001
            case Vec2S: sa_ta = 0b010
            case Vec4S: sa_ta = 0b011
            case Vec1D: sa_ta = 0b100
            case Vec2D: sa_ta = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_ta, 1, 2) != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UADDLP")
        }
        if mask(sa_ta, 1) != mask(sa_tb, 1) {
            panic("aarch64: invalid combination of operands for UADDLP")
        }
        return p.setins(asimdmisc(mask(sa_ta, 1), 1, ubfx(sa_ta, 1, 2), 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UADDLP")
}

// UADDLV instruction have one single form across one single category:
//
// 1. Unsigned sum Long across Vector
//
//    UADDLV  <V><d>, <Vn>.<T>
//
// Unsigned sum Long across Vector. This instruction adds every vector element in
// the source SIMD&FP register together, and writes the scalar result to the
// destination SIMD&FP register. The destination scalar is twice as long as the
// source vector elements. All the values in this instruction are unsigned integer
// values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UADDLV(v0, v1 interface{}) *Instruction {
    p := self.alloc("UADDLV", 2, asm.Operands { v0, v1 })
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b00
            case SRegister: sa_v = 0b01
            case DRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for UADDLV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_t, 1, 2) != sa_v {
            panic("aarch64: invalid combination of operands for UADDLV")
        }
        return p.setins(asimdall(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 3, sa_vn, sa_d))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UADDLV")
}

// UADDW instruction have one single form across one single category:
//
// 1. Unsigned Add Wide
//
//    UADDW  <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>
//
// Unsigned Add Wide. This instruction adds the vector elements of the first source
// SIMD&FP register to the corresponding vector elements in the lower or upper half
// of the second source SIMD&FP register, places the result in a vector, and writes
// the vector to the SIMD&FP destination register. The vector elements of the
// destination register and the first source register are twice as long as the
// vector elements of the second source register. All the values in this
// instruction are unsigned integer values.
//
// The UADDW instruction extracts vector elements from the lower half of the second
// source register. The UADDW2 instruction extracts vector elements from the upper
// half of the second source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UADDW(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UADDW", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch vfmt(v2) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UADDW")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UADDW")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 1, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UADDW")
}

// UADDW2 instruction have one single form across one single category:
//
// 1. Unsigned Add Wide
//
//    UADDW2  <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>
//
// Unsigned Add Wide. This instruction adds the vector elements of the first source
// SIMD&FP register to the corresponding vector elements in the lower or upper half
// of the second source SIMD&FP register, places the result in a vector, and writes
// the vector to the SIMD&FP destination register. The vector elements of the
// destination register and the first source register are twice as long as the
// vector elements of the second source register. All the values in this
// instruction are unsigned integer values.
//
// The UADDW instruction extracts vector elements from the lower half of the second
// source register. The UADDW2 instruction extracts vector elements from the upper
// half of the second source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UADDW2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UADDW2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch vfmt(v2) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UADDW2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UADDW2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 1, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UADDW2")
}

// UBFIZ instruction have 2 forms across one single category:
//
// 1. Unsigned Bitfield Insert in Zero
//
//    UBFIZ  <Wd>, <Wn>, #<lsb>, #<width>
//    UBFIZ  <Xd>, <Xn>, #<lsb>, #<width>
//
// Unsigned Bitfield Insert in Zeros copies a bitfield of <width> bits from the
// least significant bits of the source register to bit position <lsb> of the
// destination register, setting the destination bits above and below the bitfield
// to zero.
//
func (self *Program) UBFIZ(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("UBFIZ", 4, asm.Operands { v0, v1, v2, v3 })
    // UBFIZ  <Wd>, <Wn>, #<lsb>, #<width>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) && isBFxWidth(v2, v3, 32) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_lsb := -asUimm5(v2) % 32
        sa_width := asUimm5(v3) - 1
        return p.setins(bitfield(0, 2, 0, sa_lsb, sa_width, sa_wn, sa_wd))
    }
    // UBFIZ  <Xd>, <Xn>, #<lsb>, #<width>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) && isBFxWidth(v2, v3, 64) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_lsb_2 := -asUimm6(v2) % 64
        sa_width_1 := asUimm6(v3) - 1
        return p.setins(bitfield(1, 2, 1, sa_lsb_2, sa_width_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UBFIZ")
}

// UBFM instruction have 2 forms across one single category:
//
// 1. Unsigned Bitfield Move
//
//    UBFM  <Wd>, <Wn>, #<immr>, #<imms>
//    UBFM  <Xd>, <Xn>, #<immr>, #<imms>
//
// Unsigned Bitfield Move is usually accessed via one of its aliases, which are
// always preferred for disassembly.
//
// If <imms> is greater than or equal to <immr> , this copies a bitfield of (
// <imms> - <immr> +1) bits starting from bit position <immr> in the source
// register to the least significant bits of the destination register.
//
// If <imms> is less than <immr> , this copies a bitfield of ( <imms> +1) bits from
// the least significant bits of the source register to bit position (regsize-
// <immr> ) of the destination register, where regsize is the destination register
// size of 32 or 64 bits.
//
// In both cases the destination bits below and above the bitfield are set to zero.
//
func (self *Program) UBFM(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("UBFM", 4, asm.Operands { v0, v1, v2, v3 })
    // UBFM  <Wd>, <Wn>, #<immr>, #<imms>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) && isInRange(v3, 0, 31) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_immr := asUimm6(v2)
        sa_imms := asUimm6(v3)
        return p.setins(bitfield(0, 2, 0, sa_immr, sa_imms, sa_wn, sa_wd))
    }
    // UBFM  <Xd>, <Xn>, #<immr>, #<imms>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) && isInRange(v3, 0, 63) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_immr_1 := asUimm6(v2)
        sa_imms_1 := asUimm6(v3)
        return p.setins(bitfield(1, 2, 1, sa_immr_1, sa_imms_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UBFM")
}

// UBFX instruction have 2 forms across one single category:
//
// 1. Unsigned Bitfield Extract
//
//    UBFX  <Wd>, <Wn>, #<lsb>, #<width>
//    UBFX  <Xd>, <Xn>, #<lsb>, #<width>
//
// Unsigned Bitfield Extract copies a bitfield of <width> bits starting from bit
// position <lsb> in the source register to the least significant bits of the
// destination register, and sets destination bits above the bitfield to zero.
//
func (self *Program) UBFX(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("UBFX", 4, asm.Operands { v0, v1, v2, v3 })
    // UBFX  <Wd>, <Wn>, #<lsb>, #<width>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 31) && isBFxWidth(v2, v3, 32) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_lsb_1 := asUimm5(v2)
        sa_width := sa_lsb_1 + asUimm5(v3) - 1
        return p.setins(bitfield(0, 2, 0, sa_lsb_1, sa_width, sa_wn, sa_wd))
    }
    // UBFX  <Xd>, <Xn>, #<lsb>, #<width>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 63) && isBFxWidth(v2, v3, 64) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_lsb_3 := asUimm6(v2)
        sa_width_1 := sa_lsb_3 + asUimm6(v3) - 1
        return p.setins(bitfield(1, 2, 1, sa_lsb_3, sa_width_1, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UBFX")
}

// UCVTF instruction have 18 forms across 4 categories:
//
// 1. Unsigned fixed-point Convert to Floating-point (vector)
//
//    UCVTF  <Vd>.<T>, <Vn>.<T>, #<fbits>
//    UCVTF  <V><d>, <V><n>, #<fbits>
//
// Unsigned fixed-point Convert to Floating-point (vector). This instruction
// converts each element in a vector from fixed-point to floating-point using the
// rounding mode that is specified by the FPCR , and writes the result to the
// SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 2. Unsigned integer Convert to Floating-point (vector)
//
//    UCVTF  <Vd>.<T>, <Vn>.<T>
//    UCVTF  <Vd>.<T>, <Vn>.<T>
//    UCVTF  <V><d>, <V><n>
//    UCVTF  <Hd>, <Hn>
//
// Unsigned integer Convert to Floating-point (vector). This instruction converts
// each element in a vector from an unsigned integer value to a floating-point
// value using the rounding mode that is specified by the FPCR , and writes the
// result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 3. Unsigned fixed-point Convert to Floating-point (scalar)
//
//    UCVTF  <Dd>, <Wn>, #<fbits>
//    UCVTF  <Dd>, <Xn>, #<fbits>
//    UCVTF  <Hd>, <Wn>, #<fbits>
//    UCVTF  <Hd>, <Xn>, #<fbits>
//    UCVTF  <Sd>, <Wn>, #<fbits>
//    UCVTF  <Sd>, <Xn>, #<fbits>
//
// Unsigned fixed-point Convert to Floating-point (scalar). This instruction
// converts the unsigned value in the 32-bit or 64-bit general-purpose source
// register to a floating-point value using the rounding mode that is specified by
// the FPCR , and writes the result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the Security state and Exception level in which the instruction is executed,
// an attempt to execute the instruction might be trapped.
//
// 4. Unsigned integer Convert to Floating-point (scalar)
//
//    UCVTF  <Dd>, <Wn>
//    UCVTF  <Dd>, <Xn>
//    UCVTF  <Hd>, <Wn>
//    UCVTF  <Hd>, <Xn>
//    UCVTF  <Sd>, <Wn>
//    UCVTF  <Sd>, <Xn>
//
// Unsigned integer Convert to Floating-point (scalar). This instruction converts
// the unsigned integer value in the general-purpose source register to a floating-
// point value using the rounding mode that is specified by the FPCR , and writes
// the result to the SIMD&FP destination register.
//
// A floating-point exception can be generated by this instruction. Depending on
// the settings in FPCR , the exception results in either a flag being set in FPSR
// , or a synchronous exception being generated. For more information, see
// Floating-point exception traps .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UCVTF(v0, v1 interface{}, vv ...interface{}) *Instruction {
    var p *Instruction
    switch len(vv) {
        case 0  : p = self.alloc("UCVTF", 2, asm.Operands { v0, v1 })
        case 1  : p = self.alloc("UCVTF", 3, asm.Operands { v0, v1, vv[0] })
        default : panic("aarch64: instruction UCVTF takes 2 or 3 operands")
    }
    // UCVTF  <Vd>.<T>, <Vn>.<T>, #<fbits>
    if len(vv) == 1 &&
       isVr(v0) &&
       isVfmt(v0, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(vv[0]) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_fbits uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0010: sa_fbits = 32 - uint32(asLit(vv[0]))
            case 0b0100: sa_fbits = 64 - uint32(asLit(vv[0]))
            case 0b1000: sa_fbits = 128 - uint32(asLit(vv[0]))
            default: panic("aarch64: invalid operand 'sa_fbits' for UCVTF")
        }
        if ubfx(sa_fbits, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for UCVTF")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_fbits, 3, 4), mask(sa_fbits, 3), 28, sa_vn, sa_vd))
    }
    // UCVTF  <V><d>, <V><n>, #<fbits>
    if len(vv) == 1 && isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(vv[0]) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_fbits_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case HRegister: sa_v = 0b0010
            case SRegister: sa_v = 0b0100
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for UCVTF")
        }
        switch v0.(type) {
            case HRegister: sa_v__bit_mask = 0b1110
            case SRegister: sa_v__bit_mask = 0b1100
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for UCVTF")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b0010: sa_fbits_1 = 32 - uint32(asLit(vv[0]))
            case 0b0100: sa_fbits_1 = 64 - uint32(asLit(vv[0]))
            case 0b1000: sa_fbits_1 = 128 - uint32(asLit(vv[0]))
            default: panic("aarch64: invalid operand 'sa_fbits_1' for UCVTF")
        }
        if ubfx(sa_fbits_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for UCVTF")
        }
        return p.setins(asisdshf(1, ubfx(sa_fbits_1, 3, 4), mask(sa_fbits_1, 3), 28, sa_n, sa_d))
    }
    // UCVTF  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            case Vec2D: sa_t = 0b11
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 29, sa_vn, sa_vd))
    }
    // UCVTF  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) && isVfmt(v0, Vec4H, Vec8H) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H) && vfmt(v0) == vfmt(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        var sa_t_1 uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4H: sa_t_1 = 0b0
            case Vec8H: sa_t_1 = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmiscfp16(sa_t_1, 1, 0, 29, sa_vn, sa_vd))
    }
    // UCVTF  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case SRegister: sa_v = 0b0
            case DRegister: sa_v = 0b1
            default: panic("aarch64: invalid scalar operand size for UCVTF")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        size := uint32(0b00)
        size |= sa_v
        return p.setins(asisdmisc(1, size, 29, sa_n, sa_d))
    }
    // UCVTF  <Hd>, <Hn>
    if isHr(v0) && isHr(v1) {
        self.Arch.Require(FEAT_FP16)
        p.Domain = DomainAdvSimd
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_hn := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmiscfp16(1, 0, 29, sa_hn, sa_hd))
    }
    // UCVTF  <Dd>, <Wn>, #<fbits>
    if len(vv) == 1 && isDr(v0) && isWr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 1, 0, 3, sa_fbits, sa_wn, sa_dd))
    }
    // UCVTF  <Dd>, <Xn>, #<fbits>
    if len(vv) == 1 && isDr(v0) && isXr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 1, 0, 3, sa_fbits_1, sa_xn, sa_dd))
    }
    // UCVTF  <Hd>, <Wn>, #<fbits>
    if len(vv) == 1 && isHr(v0) && isWr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 3, 0, 3, sa_fbits, sa_wn, sa_hd))
    }
    // UCVTF  <Hd>, <Xn>, #<fbits>
    if len(vv) == 1 && isHr(v0) && isXr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 3, 0, 3, sa_fbits_1, sa_xn, sa_hd))
    }
    // UCVTF  <Sd>, <Wn>, #<fbits>
    if len(vv) == 1 && isSr(v0) && isWr(v1) && isInRange(vv[0], 1, 32) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_fbits := asFpScale(vv[0])
        return p.setins(float2fix(0, 0, 0, 0, 3, sa_fbits, sa_wn, sa_sd))
    }
    // UCVTF  <Sd>, <Xn>, #<fbits>
    if len(vv) == 1 && isSr(v0) && isXr(v1) && isInRange(vv[0], 1, 64) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_fbits_1 := asFpScale(vv[0])
        return p.setins(float2fix(1, 0, 0, 0, 3, sa_fbits_1, sa_xn, sa_sd))
    }
    // UCVTF  <Dd>, <Wn>
    if isDr(v0) && isWr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 1, 0, 3, sa_wn, sa_dd))
    }
    // UCVTF  <Dd>, <Xn>
    if isDr(v0) && isXr(v1) {
        p.Domain = DomainFloat
        sa_dd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 1, 0, 3, sa_xn, sa_dd))
    }
    // UCVTF  <Hd>, <Wn>
    if isHr(v0) && isWr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 3, 0, 3, sa_wn, sa_hd))
    }
    // UCVTF  <Hd>, <Xn>
    if isHr(v0) && isXr(v1) {
        p.Domain = DomainFloat
        sa_hd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 3, 0, 3, sa_xn, sa_hd))
    }
    // UCVTF  <Sd>, <Wn>
    if isSr(v0) && isWr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(0, 0, 0, 0, 3, sa_wn, sa_sd))
    }
    // UCVTF  <Sd>, <Xn>
    if isSr(v0) && isXr(v1) {
        p.Domain = DomainFloat
        sa_sd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        return p.setins(float2int(1, 0, 0, 0, 3, sa_xn, sa_sd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UCVTF")
}

// UDF instruction have one single form across one single category:
//
// 1. Permanently Undefined
//
//    UDF  #<imm>
//
// Permanently Undefined generates an Undefined Instruction exception (ESR_ELx.EC =
// 0b000000). The encodings for UDF used in this section are defined as permanently
// undefined .
//
func (self *Program) UDF(v0 interface{}) *Instruction {
    p := self.alloc("UDF", 1, asm.Operands { v0 })
    if isInRange(v0, 0, 65535) {
        p.Domain = asm.DomainGeneric
        sa_imm := asUimm16(v0)
        return p.setins(perm_undef(sa_imm))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UDF")
}

// UDIV instruction have 2 forms across one single category:
//
// 1. Unsigned Divide
//
//    UDIV  <Wd>, <Wn>, <Wm>
//    UDIV  <Xd>, <Xn>, <Xm>
//
// Unsigned Divide divides an unsigned integer register value by another unsigned
// integer register value, and writes the result to the destination register. The
// condition flags are not affected.
//
func (self *Program) UDIV(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UDIV", 3, asm.Operands { v0, v1, v2 })
    // UDIV  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 2, sa_wn, sa_wd))
    }
    // UDIV  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 2, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UDIV")
}

// UDOT instruction have 2 forms across 2 categories:
//
// 1. Dot Product unsigned arithmetic (vector, by element)
//
//    UDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.4B[<index>]
//
// Dot Product unsigned arithmetic (vector, by element). This instruction performs
// the dot product of the four 8-bit elements in each 32-bit element of the first
// source register with the four 8-bit elements of an indexed 32-bit element in the
// second source register, accumulating the result into the corresponding 32-bit
// element of the destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .DP indicates whether this instruction is supported.
//
// 2. Dot Product unsigned arithmetic (vector)
//
//    UDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Dot Product unsigned arithmetic (vector). This instruction performs the dot
// product of the four unsigned 8-bit elements in each 32-bit element of the first
// source register with the four unsigned 8-bit elements of the corresponding
// 32-bit element in the second source register, accumulating the result into the
// corresponding 32-bit element of the destination register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// In Armv8.2 and Armv8.3, this is an optional instruction. From Armv8.4 it is
// mandatory for all implementations to support it.
//
// NOTE: 
//     ID_AA64ISAR0_EL1 .DP indicates whether this instruction is supported.
//
func (self *Program) UDOT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UDOT", 3, asm.Operands { v0, v1, v2 })
    // UDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.4B[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVri(v2) &&
       vmoder(v2) == Mode4B {
        self.Arch.Require(FEAT_DotProd)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b0
            case Vec16B: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for UDOT")
        }
        return p.setins(asimdelem(
            sa_ta,
            1,
            2,
            mask(sa_index, 1),
            ubfx(sa_vm, 4, 1),
            mask(sa_vm, 4),
            14,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // UDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_DotProd)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b0
            case Vec16B: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for UDOT")
        }
        return p.setins(asimdsame2(sa_ta, 1, 2, sa_vm, 2, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UDOT")
}

// UHADD instruction have one single form across one single category:
//
// 1. Unsigned Halving Add
//
//    UHADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unsigned Halving Add. This instruction adds corresponding unsigned integer
// values from the two source SIMD&FP registers, shifts each result right one bit,
// places the results into a vector, and writes the vector to the destination
// SIMD&FP register.
//
// The results are truncated. For rounded results, see URHADD .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UHADD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UHADD", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 0, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UHADD")
}

// UHSUB instruction have one single form across one single category:
//
// 1. Unsigned Halving Subtract
//
//    UHSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unsigned Halving Subtract. This instruction subtracts the vector elements in the
// second source SIMD&FP register from the corresponding vector elements in the
// first source SIMD&FP register, shifts each result right one bit, places each
// result into a vector, and writes the vector to the destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UHSUB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UHSUB", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 4, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UHSUB")
}

// UMADDL instruction have one single form across one single category:
//
// 1. Unsigned Multiply-Add Long
//
//    UMADDL  <Xd>, <Wn>, <Wm>, <Xa>
//
// Unsigned Multiply-Add Long multiplies two 32-bit register values, adds a 64-bit
// register value, and writes the result to the 64-bit destination register.
//
func (self *Program) UMADDL(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("UMADDL", 4, asm.Operands { v0, v1, v2, v3 })
    if isXr(v0) && isWr(v1) && isWr(v2) && isXr(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_xa := uint32(v3.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 5, sa_wm, 0, sa_xa, sa_wn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UMADDL")
}

// UMAX instruction have 5 forms across 3 categories:
//
// 1. Unsigned Maximum (vector)
//
//    UMAX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unsigned Maximum (vector). This instruction compares corresponding elements in
// the vectors in the two source SIMD&FP registers, places the larger of each pair
// of unsigned integer values into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Unsigned Maximum (immediate)
//
//    UMAX  <Wd>, <Wn>, #<uimm>
//    UMAX  <Xd>, <Xn>, #<uimm>
//
// Unsigned Maximum (immediate) determines the unsigned maximum of the source
// register value and immediate, and writes the result to the destination register.
//
// 3. Unsigned Maximum (register)
//
//    UMAX  <Wd>, <Wn>, <Wm>
//    UMAX  <Xd>, <Xn>, <Xm>
//
// Unsigned Maximum (register) determines the unsigned maximum of the two source
// register values and writes the result to the destination register.
//
func (self *Program) UMAX(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMAX", 3, asm.Operands { v0, v1, v2 })
    // UMAX  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 12, sa_vn, sa_vd))
    }
    // UMAX  <Wd>, <Wn>, #<uimm>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 255) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_uimm := asUimm8(v2)
        return p.setins(minmax_imm(0, 0, 0, 1, sa_uimm, sa_wn, sa_wd))
    }
    // UMAX  <Xd>, <Xn>, #<uimm>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 255) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_uimm := asUimm8(v2)
        return p.setins(minmax_imm(1, 0, 0, 1, sa_uimm, sa_xn, sa_xd))
    }
    // UMAX  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 25, sa_wn, sa_wd))
    }
    // UMAX  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 25, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UMAX")
}

// UMAXP instruction have one single form across one single category:
//
// 1. Unsigned Maximum Pairwise
//
//    UMAXP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unsigned Maximum Pairwise. This instruction creates a vector by concatenating
// the vector elements of the first source SIMD&FP register after the vector
// elements of the second source SIMD&FP register, reads each pair of adjacent
// vector elements in the two source SIMD&FP registers, writes the largest of each
// pair of unsigned integer values into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMAXP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMAXP", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UMAXP")
}

// UMAXV instruction have one single form across one single category:
//
// 1. Unsigned Maximum across Vector
//
//    UMAXV  <V><d>, <Vn>.<T>
//
// Unsigned Maximum across Vector. This instruction compares all the vector
// elements in the source SIMD&FP register, and writes the largest of the values as
// a scalar to the destination SIMD&FP register. All the values in this instruction
// are unsigned integer values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMAXV(v0, v1 interface{}) *Instruction {
    p := self.alloc("UMAXV", 2, asm.Operands { v0, v1 })
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for UMAXV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_t, 1, 2) != sa_v {
            panic("aarch64: invalid combination of operands for UMAXV")
        }
        return p.setins(asimdall(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 10, sa_vn, sa_d))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UMAXV")
}

// UMIN instruction have 5 forms across 3 categories:
//
// 1. Unsigned Minimum (vector)
//
//    UMIN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unsigned Minimum (vector). This instruction compares corresponding vector
// elements in the two source SIMD&FP registers, places the smaller of each of the
// two unsigned integer values into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Unsigned Minimum (immediate)
//
//    UMIN  <Wd>, <Wn>, #<uimm>
//    UMIN  <Xd>, <Xn>, #<uimm>
//
// Unsigned Minimum (immediate) determines the unsigned minimum of the source
// register value and immediate, and writes the result to the destination register.
//
// 3. Unsigned Minimum (register)
//
//    UMIN  <Wd>, <Wn>, <Wm>
//    UMIN  <Xd>, <Xn>, <Xm>
//
// Unsigned Minimum (register) determines the unsigned minimum of the two source
// register values and writes the result to the destination register.
//
func (self *Program) UMIN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMIN", 3, asm.Operands { v0, v1, v2 })
    // UMIN  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 13, sa_vn, sa_vd))
    }
    // UMIN  <Wd>, <Wn>, #<uimm>
    if isWr(v0) && isWr(v1) && isInRange(v2, 0, 255) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_uimm := asUimm8(v2)
        return p.setins(minmax_imm(0, 0, 0, 3, sa_uimm, sa_wn, sa_wd))
    }
    // UMIN  <Xd>, <Xn>, #<uimm>
    if isXr(v0) && isXr(v1) && isInRange(v2, 0, 255) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_uimm := asUimm8(v2)
        return p.setins(minmax_imm(1, 0, 0, 3, sa_uimm, sa_xn, sa_xd))
    }
    // UMIN  <Wd>, <Wn>, <Wm>
    if isWr(v0) && isWr(v1) && isWr(v2) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(0, 0, sa_wm, 27, sa_wn, sa_wd))
    }
    // UMIN  <Xd>, <Xn>, <Xm>
    if isXr(v0) && isXr(v1) && isXr(v2) {
        self.Arch.Require(FEAT_CSSC)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_2src(1, 0, sa_xm, 27, sa_xn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UMIN")
}

// UMINP instruction have one single form across one single category:
//
// 1. Unsigned Minimum Pairwise
//
//    UMINP  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unsigned Minimum Pairwise. This instruction creates a vector by concatenating
// the vector elements of the first source SIMD&FP register after the vector
// elements of the second source SIMD&FP register, reads each pair of adjacent
// vector elements in the two source SIMD&FP registers, writes the smallest of each
// pair of unsigned integer values into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMINP(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMINP", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 21, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UMINP")
}

// UMINV instruction have one single form across one single category:
//
// 1. Unsigned Minimum across Vector
//
//    UMINV  <V><d>, <Vn>.<T>
//
// Unsigned Minimum across Vector. This instruction compares all the vector
// elements in the source SIMD&FP register, and writes the smallest of the values
// as a scalar to the destination SIMD&FP register. All the values in this
// instruction are unsigned integer values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMINV(v0, v1 interface{}) *Instruction {
    p := self.alloc("UMINV", 2, asm.Operands { v0, v1 })
    if isAdvSIMD(v0) && isVr(v1) && isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            default: panic("aarch64: invalid scalar operand size for UMINV")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        if ubfx(sa_t, 1, 2) != sa_v {
            panic("aarch64: invalid combination of operands for UMINV")
        }
        return p.setins(asimdall(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 26, sa_vn, sa_d))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UMINV")
}

// UMLAL instruction have 2 forms across 2 categories:
//
// 1. Unsigned Multiply-Add Long (vector, by element)
//
//    UMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Unsigned Multiply-Add Long (vector, by element). This instruction multiplies
// each vector element in the lower or upper half of the first source SIMD&FP
// register by the specified vector element of the second source SIMD&FP register
// and accumulates the results with the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The UMLAL instruction extracts vector elements from the lower half of the first
// source register. The UMLAL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Unsigned Multiply-Add Long (vector)
//
//    UMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Multiply-Add Long (vector). This instruction multiplies the vector
// elements in the lower or upper half of the first source SIMD&FP register by the
// corresponding vector elements of the second source SIMD&FP register, and
// accumulates the results with the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The UMLAL instruction extracts vector elements from the lower half of the first
// source register. The UMLAL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMLAL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMLAL", 3, asm.Operands { v0, v1, v2 })
    // UMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for UMLAL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for UMLAL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UMLAL")
        }
        return p.setins(asimdelem(
            0,
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            2,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // UMLAL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UMLAL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UMLAL")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 8, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UMLAL")
}

// UMLAL2 instruction have 2 forms across 2 categories:
//
// 1. Unsigned Multiply-Add Long (vector, by element)
//
//    UMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Unsigned Multiply-Add Long (vector, by element). This instruction multiplies
// each vector element in the lower or upper half of the first source SIMD&FP
// register by the specified vector element of the second source SIMD&FP register
// and accumulates the results with the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The UMLAL instruction extracts vector elements from the lower half of the first
// source register. The UMLAL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Unsigned Multiply-Add Long (vector)
//
//    UMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Multiply-Add Long (vector). This instruction multiplies the vector
// elements in the lower or upper half of the first source SIMD&FP register by the
// corresponding vector elements of the second source SIMD&FP register, and
// accumulates the results with the vector elements of the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The UMLAL instruction extracts vector elements from the lower half of the first
// source register. The UMLAL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMLAL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMLAL2", 3, asm.Operands { v0, v1, v2 })
    // UMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for UMLAL2")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for UMLAL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UMLAL2")
        }
        return p.setins(asimdelem(
            1,
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            2,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // UMLAL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UMLAL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UMLAL2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 8, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UMLAL2")
}

// UMLSL instruction have 2 forms across 2 categories:
//
// 1. Unsigned Multiply-Subtract Long (vector, by element)
//
//    UMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Unsigned Multiply-Subtract Long (vector, by element). This instruction
// multiplies each vector element in the lower or upper half of the first source
// SIMD&FP register by the specified vector element of the second source SIMD&FP
// register and subtracts the results from the vector elements of the destination
// SIMD&FP register. The destination vector elements are twice as long as the
// elements that are multiplied.
//
// The UMLSL instruction extracts vector elements from the lower half of the first
// source register. The UMLSL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Unsigned Multiply-Subtract Long (vector)
//
//    UMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Multiply-Subtract Long (vector). This instruction multiplies
// corresponding vector elements in the lower or upper half of the two source
// SIMD&FP registers, and subtracts the results from the vector elements of the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the elements that are multiplied. All the values in this instruction are
// unsigned integer values.
//
// The UMLSL instruction extracts each source vector from the lower half of each
// source register. The UMLSL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMLSL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMLSL", 3, asm.Operands { v0, v1, v2 })
    // UMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for UMLSL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for UMLSL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UMLSL")
        }
        return p.setins(asimdelem(
            0,
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            6,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // UMLSL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UMLSL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UMLSL")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 10, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UMLSL")
}

// UMLSL2 instruction have 2 forms across 2 categories:
//
// 1. Unsigned Multiply-Subtract Long (vector, by element)
//
//    UMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Unsigned Multiply-Subtract Long (vector, by element). This instruction
// multiplies each vector element in the lower or upper half of the first source
// SIMD&FP register by the specified vector element of the second source SIMD&FP
// register and subtracts the results from the vector elements of the destination
// SIMD&FP register. The destination vector elements are twice as long as the
// elements that are multiplied.
//
// The UMLSL instruction extracts vector elements from the lower half of the first
// source register. The UMLSL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Unsigned Multiply-Subtract Long (vector)
//
//    UMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Multiply-Subtract Long (vector). This instruction multiplies
// corresponding vector elements in the lower or upper half of the two source
// SIMD&FP registers, and subtracts the results from the vector elements of the
// destination SIMD&FP register. The destination vector elements are twice as long
// as the elements that are multiplied. All the values in this instruction are
// unsigned integer values.
//
// The UMLSL instruction extracts each source vector from the lower half of each
// source register. The UMLSL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMLSL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMLSL2", 3, asm.Operands { v0, v1, v2 })
    // UMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for UMLSL2")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for UMLSL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UMLSL2")
        }
        return p.setins(asimdelem(
            1,
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            6,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // UMLSL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UMLSL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UMLSL2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 10, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UMLSL2")
}

// UMMLA instruction have one single form across one single category:
//
// 1. Unsigned 8-bit integer matrix multiply-accumulate (vector)
//
//    UMMLA  <Vd>.4S, <Vn>.16B, <Vm>.16B
//
// Unsigned 8-bit integer matrix multiply-accumulate. This instruction multiplies
// the 2x8 matrix of unsigned 8-bit integer values in the first source vector by
// the 8x2 matrix of unsigned 8-bit integer values in the second source vector. The
// resulting 2x2 32-bit integer matrix product is destructively added to the 32-bit
// integer matrix accumulator in the destination vector. This is equivalent to
// performing an 8-way dot product per destination element.
//
// From Armv8.2 to Armv8.5, this is an optional instruction. From Armv8.6 it is
// mandatory for implementations that include Advanced SIMD to support it.
// ID_AA64ISAR1_EL1 .I8MM indicates whether this instruction is supported.
//
func (self *Program) UMMLA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMMLA", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec16B && isVr(v2) && vfmt(v2) == Vec16B {
        self.Arch.Require(FEAT_I8MM)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame2(1, 1, 2, sa_vm, 4, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UMMLA")
}

// UMNEGL instruction have one single form across one single category:
//
// 1. Unsigned Multiply-Negate Long
//
//    UMNEGL  <Xd>, <Wn>, <Wm>
//
// Unsigned Multiply-Negate Long multiplies two 32-bit register values, negates the
// product, and writes the result to the 64-bit destination register.
//
func (self *Program) UMNEGL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMNEGL", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 5, sa_wm, 1, 31, sa_wn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UMNEGL")
}

// UMOV instruction have 2 forms across one single category:
//
// 1. Unsigned Move vector element to general-purpose register
//
//    UMOV  <Wd>, <Vn>.<Ts>[<index>]
//    UMOV  <Xd>, <Vn>.<Ts>[<index>]
//
// Unsigned Move vector element to general-purpose register. This instruction reads
// the unsigned integer from the source SIMD&FP register, zero-extends it to form a
// 32-bit or 64-bit value, and writes the result to the destination general-purpose
// register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMOV(v0, v1 interface{}) *Instruction {
    p := self.alloc("UMOV", 2, asm.Operands { v0, v1 })
    // UMOV  <Wd>, <Vn>.<Ts>[<index>]
    if isWr(v0) && isVri(v1) {
        p.Domain = DomainAdvSimd
        var sa_ts uint32
        var sa_ts__bit_mask uint32
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(VidxRegister).ID())
        switch vmoder(v1) {
            case ModeB: sa_ts = 0b00001
            case ModeH: sa_ts = 0b00010
            case ModeS: sa_ts = 0b00100
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v1) {
            case ModeB: sa_ts__bit_mask = 0b00001
            case ModeH: sa_ts__bit_mask = 0b00011
            case ModeS: sa_ts__bit_mask = 0b00111
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v1))
        if sa_index != sa_ts & sa_ts__bit_mask {
            panic("aarch64: invalid combination of operands for UMOV")
        }
        return p.setins(asimdins(0, 0, sa_index, 7, sa_vn, sa_wd))
    }
    // UMOV  <Xd>, <Vn>.<Ts>[<index>]
    if isXr(v0) && isVri(v1) {
        p.Domain = DomainAdvSimd
        var sa_ts_1 uint32
        var sa_ts_1__bit_mask uint32
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(VidxRegister).ID())
        switch vmoder(v1) {
            case ModeD: sa_ts_1 = 0b01000
            default: panic("aarch64: unreachable")
        }
        switch vmoder(v1) {
            case ModeD: sa_ts_1__bit_mask = 0b01111
            default: panic("aarch64: unreachable")
        }
        sa_index_1 := uint32(vidxr(v1))
        if sa_index_1 != sa_ts_1 & sa_ts_1__bit_mask {
            panic("aarch64: invalid combination of operands for UMOV")
        }
        return p.setins(asimdins(1, 0, sa_index_1, 7, sa_vn, sa_xd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UMOV")
}

// UMSUBL instruction have one single form across one single category:
//
// 1. Unsigned Multiply-Subtract Long
//
//    UMSUBL  <Xd>, <Wn>, <Wm>, <Xa>
//
// Unsigned Multiply-Subtract Long multiplies two 32-bit register values, subtracts
// the product from a 64-bit register value, and writes the result to the 64-bit
// destination register.
//
func (self *Program) UMSUBL(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("UMSUBL", 4, asm.Operands { v0, v1, v2, v3 })
    if isXr(v0) && isWr(v1) && isWr(v2) && isXr(v3) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        sa_xa := uint32(v3.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 5, sa_wm, 1, sa_xa, sa_wn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UMSUBL")
}

// UMULH instruction have one single form across one single category:
//
// 1. Unsigned Multiply High
//
//    UMULH  <Xd>, <Xn>, <Xm>
//
// Unsigned Multiply High multiplies two 64-bit register values, and writes
// bits[127:64] of the 128-bit result to the 64-bit destination register.
//
func (self *Program) UMULH(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMULH", 3, asm.Operands { v0, v1, v2 })
    if isXr(v0) && isXr(v1) && isXr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_xn := uint32(v1.(asm.Register).ID())
        sa_xm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 6, sa_xm, 0, 31, sa_xn, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UMULH")
}

// UMULL instruction have 3 forms across 3 categories:
//
// 1. Unsigned Multiply Long
//
//    UMULL  <Xd>, <Wn>, <Wm>
//
// Unsigned Multiply Long multiplies two 32-bit register values, and writes the
// result to the 64-bit destination register.
//
// 2. Unsigned Multiply Long (vector, by element)
//
//    UMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Unsigned Multiply Long (vector, by element). This instruction multiplies each
// vector element in the lower or upper half of the first source SIMD&FP register
// by the specified vector element of the second source SIMD&FP register, places
// the results in a vector, and writes the vector to the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The UMULL instruction extracts vector elements from the lower half of the first
// source register. The UMULL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 3. Unsigned Multiply long (vector)
//
//    UMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Multiply long (vector). This instruction multiplies corresponding
// vector elements in the lower or upper half of the two source SIMD&FP registers,
// places the result in a vector, and writes the vector to the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied. All the values in this instruction are unsigned integer values.
//
// The UMULL instruction extracts each source vector from the lower half of each
// source register. The UMULL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMULL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMULL", 3, asm.Operands { v0, v1, v2 })
    // UMULL  <Xd>, <Wn>, <Wm>
    if isXr(v0) && isWr(v1) && isWr(v2) {
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        sa_wm := uint32(v2.(asm.Register).ID())
        return p.setins(dp_3src(1, 0, 5, sa_wm, 0, 31, sa_wn, sa_xd))
    }
    // UMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for UMULL")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for UMULL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UMULL")
        }
        return p.setins(asimdelem(
            0,
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            10,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // UMULL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UMULL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UMULL")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 12, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UMULL")
}

// UMULL2 instruction have 2 forms across 2 categories:
//
// 1. Unsigned Multiply Long (vector, by element)
//
//    UMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
//
// Unsigned Multiply Long (vector, by element). This instruction multiplies each
// vector element in the lower or upper half of the first source SIMD&FP register
// by the specified vector element of the second source SIMD&FP register, places
// the results in a vector, and writes the vector to the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied.
//
// The UMULL instruction extracts vector elements from the lower half of the first
// source register. The UMULL2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Unsigned Multiply long (vector)
//
//    UMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Multiply long (vector). This instruction multiplies corresponding
// vector elements in the lower or upper half of the two source SIMD&FP registers,
// places the result in a vector, and writes the vector to the destination SIMD&FP
// register. The destination vector elements are twice as long as the elements that
// are multiplied. All the values in this instruction are unsigned integer values.
//
// The UMULL instruction extracts each source vector from the lower half of each
// source register. The UMULL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UMULL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UMULL2", 3, asm.Operands { v0, v1, v2 })
    // UMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]
    if isVr(v0) && isVfmt(v0, Vec4S, Vec2D) && isVr(v1) && isVfmt(v1, Vec4H, Vec8H, Vec2S, Vec4S) && isVri(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        var sa_ts uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        switch vmoder(v2) {
            case ModeH: sa_ts = 0b01
            case ModeS: sa_ts = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_index := uint32(vidxr(v2))
        if ubfx(sa_index, 3, 2) != sa_ta ||
           sa_ta != ubfx(sa_tb, 1, 2) ||
           ubfx(sa_tb, 1, 2) != sa_ts ||
           sa_ts != ubfx(sa_vm, 5, 2) {
            panic("aarch64: invalid combination of operands for UMULL2")
        }
        if mask(sa_index, 1) != ubfx(sa_vm, 4, 1) {
            panic("aarch64: invalid combination of operands for UMULL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UMULL2")
        }
        return p.setins(asimdelem(
            1,
            1,
            ubfx(sa_index, 3, 2),
            ubfx(sa_index, 2, 1),
            mask(sa_index, 1),
            mask(sa_vm, 4),
            10,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // UMULL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UMULL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UMULL2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 12, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UMULL2")
}

// UQADD instruction have 2 forms across one single category:
//
// 1. Unsigned saturating Add
//
//    UQADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    UQADD  <V><d>, <V><n>, <V><m>
//
// Unsigned saturating Add. This instruction adds the values of corresponding
// elements of the two source SIMD&FP registers, places the results into a vector,
// and writes the vector to the destination SIMD&FP register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQADD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UQADD", 3, asm.Operands { v0, v1, v2 })
    // UQADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 1, sa_vn, sa_vd))
    }
    // UQADD  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for UQADD")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 1, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UQADD")
}

// UQRSHL instruction have 2 forms across one single category:
//
// 1. Unsigned saturating Rounding Shift Left (register)
//
//    UQRSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    UQRSHL  <V><d>, <V><n>, <V><m>
//
// Unsigned saturating Rounding Shift Left (register). This instruction takes each
// vector element of the first source SIMD&FP register, shifts the vector element
// by a value from the least significant byte of the corresponding vector element
// of the second source SIMD&FP register, places the results into a vector, and
// writes the vector to the destination SIMD&FP register.
//
// If the shift value is positive, the operation is a left shift. Otherwise, it is
// a right shift. The results are rounded. For truncated results, see UQSHL .
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQRSHL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UQRSHL", 3, asm.Operands { v0, v1, v2 })
    // UQRSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 11, sa_vn, sa_vd))
    }
    // UQRSHL  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for UQRSHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 11, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UQRSHL")
}

// UQRSHRN instruction have 2 forms across one single category:
//
// 1. Unsigned saturating Rounded Shift Right Narrow (immediate)
//
//    UQRSHRN  <Vb><d>, <Va><n>, #<shift>
//    UQRSHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Unsigned saturating Rounded Shift Right Narrow (immediate). This instruction
// reads each vector element in the source SIMD&FP register, right shifts each
// result by an immediate value, puts the final result into a vector, and writes
// the vector to the lower or upper half of the destination SIMD&FP register. All
// the values in this instruction are unsigned integer values. The results are
// rounded. For truncated results, see UQSHRN .
//
// The UQRSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the UQRSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQRSHRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UQRSHRN", 3, asm.Operands { v0, v1, v2 })
    // UQRSHRN  <Vb><d>, <Va><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_va uint32
        var sa_va__bit_mask uint32
        var sa_vb uint32
        var sa_vb__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_vb = 0b0001
            case HRegister: sa_vb = 0b0010
            case SRegister: sa_vb = 0b0100
            default: panic("aarch64: invalid scalar operand size for UQRSHRN")
        }
        switch v0.(type) {
            case BRegister: sa_vb__bit_mask = 0b1111
            case HRegister: sa_vb__bit_mask = 0b1110
            case SRegister: sa_vb__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for UQRSHRN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_va = 0b0001
            case SRegister: sa_va = 0b0010
            case DRegister: sa_va = 0b0100
            default: panic("aarch64: invalid scalar operand size for UQRSHRN")
        }
        switch v1.(type) {
            case HRegister: sa_va__bit_mask = 0b1111
            case SRegister: sa_va__bit_mask = 0b1110
            case DRegister: sa_va__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for UQRSHRN")
        }
        switch sa_vb {
            case 0b0001: sa_shift_1 = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift_1 = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift_1 = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for UQRSHRN")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_va & sa_va__bit_mask || sa_va & sa_va__bit_mask != sa_vb & sa_vb__bit_mask {
            panic("aarch64: invalid combination of operands for UQRSHRN")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 19, sa_n, sa_d))
    }
    // UQRSHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for UQRSHRN")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for UQRSHRN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UQRSHRN")
        }
        return p.setins(asimdshf(0, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 19, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UQRSHRN")
}

// UQRSHRN2 instruction have one single form across one single category:
//
// 1. Unsigned saturating Rounded Shift Right Narrow (immediate)
//
//    UQRSHRN2  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Unsigned saturating Rounded Shift Right Narrow (immediate). This instruction
// reads each vector element in the source SIMD&FP register, right shifts each
// result by an immediate value, puts the final result into a vector, and writes
// the vector to the lower or upper half of the destination SIMD&FP register. All
// the values in this instruction are unsigned integer values. The results are
// rounded. For truncated results, see UQSHRN .
//
// The UQRSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the UQRSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQRSHRN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UQRSHRN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for UQRSHRN2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for UQRSHRN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UQRSHRN2")
        }
        return p.setins(asimdshf(1, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 19, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UQRSHRN2")
}

// UQSHL instruction have 4 forms across 2 categories:
//
// 1. Unsigned saturating Shift Left (immediate)
//
//    UQSHL  <Vd>.<T>, <Vn>.<T>, #<shift>
//    UQSHL  <V><d>, <V><n>, #<shift>
//
// Unsigned saturating Shift Left (immediate). This instruction takes each vector
// element in the source SIMD&FP register, shifts it by an immediate value, places
// the results in a vector, and writes the vector to the destination SIMD&FP
// register. The results are truncated. For rounded results, see UQRSHL .
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
// 2. Unsigned saturating Shift Left (register)
//
//    UQSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    UQSHL  <V><d>, <V><n>, <V><m>
//
// Unsigned saturating Shift Left (register). This instruction takes each element
// in the vector of the first source SIMD&FP register, shifts the element by a
// value from the least significant byte of the corresponding element of the second
// source SIMD&FP register, places the results in a vector, and writes the vector
// to the destination SIMD&FP register.
//
// If the shift value is positive, the operation is a left shift. Otherwise, it is
// a right shift. The results are truncated. For rounded results, see UQRSHL .
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQSHL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UQSHL", 3, asm.Operands { v0, v1, v2 })
    // UQSHL  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift = uint32(asLit(v2)) + 32
            case 0b1000: sa_shift = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift' for UQSHL")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for UQSHL")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 14, sa_vn, sa_vd))
    }
    // UQSHL  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(v2) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b0001
            case HRegister: sa_v = 0b0010
            case SRegister: sa_v = 0b0100
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for UQSHL")
        }
        switch v0.(type) {
            case BRegister: sa_v__bit_mask = 0b1111
            case HRegister: sa_v__bit_mask = 0b1110
            case SRegister: sa_v__bit_mask = 0b1100
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for UQSHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b0001: sa_shift_1 = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift_1 = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift_1 = uint32(asLit(v2)) + 32
            case 0b1000: sa_shift_1 = uint32(asLit(v2)) + 64
            default: panic("aarch64: invalid operand 'sa_shift_1' for UQSHL")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for UQSHL")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 14, sa_n, sa_d))
    }
    // UQSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 9, sa_vn, sa_vd))
    }
    // UQSHL  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for UQSHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 9, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UQSHL")
}

// UQSHRN instruction have 2 forms across one single category:
//
// 1. Unsigned saturating Shift Right Narrow (immediate)
//
//    UQSHRN  <Vb><d>, <Va><n>, #<shift>
//    UQSHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Unsigned saturating Shift Right Narrow (immediate). This instruction reads each
// vector element in the source SIMD&FP register, right shifts each result by an
// immediate value, saturates each shifted result to a value that is half the
// original width, puts the final result into a vector, and writes the vector to
// the lower or upper half of the destination SIMD&FP register. All the values in
// this instruction are unsigned integer values. The results are truncated. For
// rounded results, see UQRSHRN .
//
// The UQSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the UQSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQSHRN(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UQSHRN", 3, asm.Operands { v0, v1, v2 })
    // UQSHRN  <Vb><d>, <Va><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_va uint32
        var sa_va__bit_mask uint32
        var sa_vb uint32
        var sa_vb__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_vb = 0b0001
            case HRegister: sa_vb = 0b0010
            case SRegister: sa_vb = 0b0100
            default: panic("aarch64: invalid scalar operand size for UQSHRN")
        }
        switch v0.(type) {
            case BRegister: sa_vb__bit_mask = 0b1111
            case HRegister: sa_vb__bit_mask = 0b1110
            case SRegister: sa_vb__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for UQSHRN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_va = 0b0001
            case SRegister: sa_va = 0b0010
            case DRegister: sa_va = 0b0100
            default: panic("aarch64: invalid scalar operand size for UQSHRN")
        }
        switch v1.(type) {
            case HRegister: sa_va__bit_mask = 0b1111
            case SRegister: sa_va__bit_mask = 0b1110
            case DRegister: sa_va__bit_mask = 0b1100
            default: panic("aarch64: invalid scalar operand size for UQSHRN")
        }
        switch sa_vb {
            case 0b0001: sa_shift_1 = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift_1 = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift_1 = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for UQSHRN")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_va & sa_va__bit_mask || sa_va & sa_va__bit_mask != sa_vb & sa_vb__bit_mask {
            panic("aarch64: invalid combination of operands for UQSHRN")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 18, sa_n, sa_d))
    }
    // UQSHRN  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for UQSHRN")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for UQSHRN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UQSHRN")
        }
        return p.setins(asimdshf(0, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 18, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UQSHRN")
}

// UQSHRN2 instruction have one single form across one single category:
//
// 1. Unsigned saturating Shift Right Narrow (immediate)
//
//    UQSHRN2  <Vd>.<Tb>, <Vn>.<Ta>, #<shift>
//
// Unsigned saturating Shift Right Narrow (immediate). This instruction reads each
// vector element in the source SIMD&FP register, right shifts each result by an
// immediate value, saturates each shifted result to a value that is half the
// original width, puts the final result into a vector, and writes the vector to
// the lower or upper half of the destination SIMD&FP register. All the values in
// this instruction are unsigned integer values. The results are truncated. For
// rounded results, see UQRSHRN .
//
// The UQSHRN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the UQSHRN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQSHRN2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UQSHRN2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        switch ubfx(sa_tb, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for UQSHRN2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for UQSHRN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UQSHRN2")
        }
        return p.setins(asimdshf(1, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 18, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UQSHRN2")
}

// UQSUB instruction have 2 forms across one single category:
//
// 1. Unsigned saturating Subtract
//
//    UQSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    UQSUB  <V><d>, <V><n>, <V><m>
//
// Unsigned saturating Subtract. This instruction subtracts the element values of
// the second source SIMD&FP register from the corresponding element values of the
// first source SIMD&FP register, places the results into a vector, and writes the
// vector to the destination SIMD&FP register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQSUB(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UQSUB", 3, asm.Operands { v0, v1, v2 })
    // UQSUB  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 5, sa_vn, sa_vd))
    }
    // UQSUB  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for UQSUB")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 5, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UQSUB")
}

// UQXTN instruction have 2 forms across one single category:
//
// 1. Unsigned saturating extract Narrow
//
//    UQXTN  <Vb><d>, <Va><n>
//    UQXTN  <Vd>.<Tb>, <Vn>.<Ta>
//
// Unsigned saturating extract Narrow. This instruction reads each vector element
// from the source SIMD&FP register, saturates each value to half the original
// width, places the result into a vector, and writes the vector to the destination
// SIMD&FP register. All the values in this instruction are unsigned integer
// values.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The UQXTN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the UQXTN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQXTN(v0, v1 interface{}) *Instruction {
    p := self.alloc("UQXTN", 2, asm.Operands { v0, v1 })
    // UQXTN  <Vb><d>, <Va><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) {
        p.Domain = DomainAdvSimd
        var sa_va uint32
        var sa_vb uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_vb = 0b00
            case HRegister: sa_vb = 0b01
            case SRegister: sa_vb = 0b10
            default: panic("aarch64: invalid scalar operand size for UQXTN")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch v1.(type) {
            case HRegister: sa_va = 0b00
            case SRegister: sa_va = 0b01
            case DRegister: sa_va = 0b10
            default: panic("aarch64: invalid scalar operand size for UQXTN")
        }
        if sa_va != sa_vb {
            panic("aarch64: invalid combination of operands for UQXTN")
        }
        return p.setins(asisdmisc(1, sa_va, 20, sa_n, sa_d))
    }
    // UQXTN  <Vd>.<Tb>, <Vn>.<Ta>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UQXTN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UQXTN")
        }
        return p.setins(asimdmisc(0, 1, sa_ta, 20, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for UQXTN")
}

// UQXTN2 instruction have one single form across one single category:
//
// 1. Unsigned saturating extract Narrow
//
//    UQXTN2  <Vd>.<Tb>, <Vn>.<Ta>
//
// Unsigned saturating extract Narrow. This instruction reads each vector element
// from the source SIMD&FP register, saturates each value to half the original
// width, places the result into a vector, and writes the vector to the destination
// SIMD&FP register. All the values in this instruction are unsigned integer
// values.
//
// If saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// The UQXTN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the UQXTN2 instruction writes the
// vector to the upper half of the destination register without affecting the other
// bits of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UQXTN2(v0, v1 interface{}) *Instruction {
    p := self.alloc("UQXTN2", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for UQXTN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UQXTN2")
        }
        return p.setins(asimdmisc(1, 1, sa_ta, 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UQXTN2")
}

// URECPE instruction have one single form across one single category:
//
// 1. Unsigned Reciprocal Estimate
//
//    URECPE  <Vd>.<T>, <Vn>.<T>
//
// Unsigned Reciprocal Estimate. This instruction reads each vector element from
// the source SIMD&FP register, calculates an approximate inverse for the unsigned
// integer value, places the result into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) URECPE(v0, v1 interface{}) *Instruction {
    p := self.alloc("URECPE", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec2S, Vec4S) && isVr(v1) && isVfmt(v1, Vec2S, Vec4S) && vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 0, size, 28, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for URECPE")
}

// URHADD instruction have one single form across one single category:
//
// 1. Unsigned Rounding Halving Add
//
//    URHADD  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unsigned Rounding Halving Add. This instruction adds corresponding unsigned
// integer values from the two source SIMD&FP registers, shifts each result right
// one bit, places the results into a vector, and writes the vector to the
// destination SIMD&FP register.
//
// The results are rounded. For truncated results, see UHADD .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) URHADD(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("URHADD", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for URHADD")
}

// URSHL instruction have 2 forms across one single category:
//
// 1. Unsigned Rounding Shift Left (register)
//
//    URSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    URSHL  <V><d>, <V><n>, <V><m>
//
// Unsigned Rounding Shift Left (register). This instruction takes each element in
// the vector of the first source SIMD&FP register, shifts the vector element by a
// value from the least significant byte of the corresponding element of the second
// source SIMD&FP register, places the results in a vector, and writes the vector
// to the destination SIMD&FP register.
//
// If the shift value is positive, the operation is a left shift. If the shift
// value is negative, it is a rounding right shift.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) URSHL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("URSHL", 3, asm.Operands { v0, v1, v2 })
    // URSHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 10, sa_vn, sa_vd))
    }
    // URSHL  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for URSHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 10, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for URSHL")
}

// URSHR instruction have 2 forms across one single category:
//
// 1. Unsigned Rounding Shift Right (immediate)
//
//    URSHR  <Vd>.<T>, <Vn>.<T>, #<shift>
//    URSHR  <V><d>, <V><n>, #<shift>
//
// Unsigned Rounding Shift Right (immediate). This instruction reads each vector
// element in the source SIMD&FP register, right shifts each result by an immediate
// value, writes the final result to a vector, and writes the vector to the
// destination SIMD&FP register. All the values in this instruction are unsigned
// integer values. The results are rounded. For truncated results, see USHR .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) URSHR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("URSHR", 3, asm.Operands { v0, v1, v2 })
    // URSHR  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            case 0b1000: sa_shift = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for URSHR")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for URSHR")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 4, sa_vn, sa_vd))
    }
    // URSHR  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 1, 64) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for URSHR")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for URSHR")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for URSHR")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for URSHR")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 4, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for URSHR")
}

// URSQRTE instruction have one single form across one single category:
//
// 1. Unsigned Reciprocal Square Root Estimate
//
//    URSQRTE  <Vd>.<T>, <Vn>.<T>
//
// Unsigned Reciprocal Square Root Estimate. This instruction reads each vector
// element from the source SIMD&FP register, calculates an approximate inverse
// square root for each value, places the result into a vector, and writes the
// vector to the destination SIMD&FP register. All the values in this instruction
// are unsigned integer values.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) URSQRTE(v0, v1 interface{}) *Instruction {
    p := self.alloc("URSQRTE", 2, asm.Operands { v0, v1 })
    if isVr(v0) && isVfmt(v0, Vec2S, Vec4S) && isVr(v1) && isVfmt(v1, Vec2S, Vec4S) && vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_t = 0b00
            case Vec4S: sa_t = 0b01
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        size := uint32(0b10)
        size |= ubfx(sa_t, 1, 1)
        return p.setins(asimdmisc(mask(sa_t, 1), 1, size, 28, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for URSQRTE")
}

// URSRA instruction have 2 forms across one single category:
//
// 1. Unsigned Rounding Shift Right and Accumulate (immediate)
//
//    URSRA  <Vd>.<T>, <Vn>.<T>, #<shift>
//    URSRA  <V><d>, <V><n>, #<shift>
//
// Unsigned Rounding Shift Right and Accumulate (immediate). This instruction reads
// each vector element in the source SIMD&FP register, right shifts each result by
// an immediate value, and accumulates the final results with the vector elements
// of the destination SIMD&FP register. All the values in this instruction are
// unsigned integer values. The results are rounded. For truncated results, see
// USRA .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) URSRA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("URSRA", 3, asm.Operands { v0, v1, v2 })
    // URSRA  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            case 0b1000: sa_shift = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for URSRA")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for URSRA")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 6, sa_vn, sa_vd))
    }
    // URSRA  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 1, 64) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for URSRA")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for URSRA")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for URSRA")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for URSRA")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 6, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for URSRA")
}

// USDOT instruction have 2 forms across 2 categories:
//
// 1. Dot Product with unsigned and signed integers (vector, by element)
//
//    USDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.4B[<index>]
//
// Dot Product index form with unsigned and signed integers. This instruction
// performs the dot product of the four unsigned 8-bit integer values in each
// 32-bit element of the first source register with the four signed 8-bit integer
// values in an indexed 32-bit element of the second source register, accumulating
// the result into the corresponding 32-bit element of the destination register.
//
// From Armv8.2 to Armv8.5, this is an optional instruction. From Armv8.6 it is
// mandatory for implementations that include Advanced SIMD to support it.
// ID_AA64ISAR1_EL1 .I8MM indicates whether this instruction is supported.
//
// 2. Dot Product with unsigned and signed integers (vector)
//
//    USDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Dot Product vector form with unsigned and signed integers. This instruction
// performs the dot product of the four unsigned 8-bit integer values in each
// 32-bit element of the first source register with the four signed 8-bit integer
// values in the corresponding 32-bit element of the second source register,
// accumulating the result into the corresponding 32-bit element of the destination
// register.
//
// From Armv8.2 to Armv8.5, this is an optional instruction. From Armv8.6 it is
// mandatory for implementations that include Advanced SIMD to support it.
// ID_AA64ISAR1_EL1 .I8MM indicates whether this instruction is supported.
//
func (self *Program) USDOT(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USDOT", 3, asm.Operands { v0, v1, v2 })
    // USDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.4B[<index>]
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVri(v2) &&
       vmoder(v2) == Mode4B {
        self.Arch.Require(FEAT_I8MM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b0
            case Vec16B: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(VidxRegister).ID())
        sa_index := uint32(vidxr(v2))
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for USDOT")
        }
        return p.setins(asimdelem(
            sa_ta,
            0,
            2,
            mask(sa_index, 1),
            ubfx(sa_vm, 4, 1),
            mask(sa_vm, 4),
            15,
            ubfx(sa_index, 1, 1),
            sa_vn,
            sa_vd,
        ))
    }
    // USDOT  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
    if isVr(v0) &&
       isVfmt(v0, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B) &&
       vfmt(v1) == vfmt(v2) {
        self.Arch.Require(FEAT_I8MM)
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec2S: sa_ta = 0b0
            case Vec4S: sa_ta = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b0
            case Vec16B: sa_tb = 0b1
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != sa_tb {
            panic("aarch64: invalid combination of operands for USDOT")
        }
        return p.setins(asimdsame2(sa_ta, 0, 2, sa_vm, 3, sa_vn, sa_vd))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for USDOT")
}

// USHL instruction have 2 forms across one single category:
//
// 1. Unsigned Shift Left (register)
//
//    USHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//    USHL  <V><d>, <V><n>, <V><m>
//
// Unsigned Shift Left (register). This instruction takes each element in the
// vector of the first source SIMD&FP register, shifts each element by a value from
// the least significant byte of the corresponding element of the second source
// SIMD&FP register, places the results in a vector, and writes the vector to the
// destination SIMD&FP register.
//
// If the shift value is positive, the operation is a left shift. If the shift
// value is negative, it is a truncating right shift. For a rounding shift, see
// URSHL .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USHL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USHL", 3, asm.Operands { v0, v1, v2 })
    // USHL  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), sa_vm, 8, sa_vn, sa_vd))
    }
    // USHL  <V><d>, <V><n>, <V><m>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isAdvSIMD(v2) && isSameType(v0, v1) && isSameType(v1, v2) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for USHL")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        sa_m := uint32(v2.(asm.Register).ID())
        return p.setins(asisdsame(1, sa_v, sa_m, 8, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for USHL")
}

// USHLL instruction have one single form across one single category:
//
// 1. Unsigned Shift Left Long (immediate)
//
//    USHLL  <Vd>.<Ta>, <Vn>.<Tb>, #<shift>
//
// Unsigned Shift Left Long (immediate). This instruction reads each vector element
// in the lower or upper half of the source SIMD&FP register, shifts the unsigned
// integer value left by the specified number of bits, places the result into a
// vector, and writes the vector to the destination SIMD&FP register. The
// destination vector elements are twice as long as the source vector elements.
//
// The USHLL instruction extracts vector elements from the lower half of the source
// register. The USHLL2 instruction extracts vector elements from the upper half of
// the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USHLL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USHLL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        switch sa_ta {
            case 0b0001: sa_shift = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift = uint32(asLit(v2)) + 32
            default: panic("aarch64: invalid operand 'sa_shift' for USHLL")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for USHLL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for USHLL")
        }
        return p.setins(asimdshf(0, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for USHLL")
}

// USHLL2 instruction have one single form across one single category:
//
// 1. Unsigned Shift Left Long (immediate)
//
//    USHLL2  <Vd>.<Ta>, <Vn>.<Tb>, #<shift>
//
// Unsigned Shift Left Long (immediate). This instruction reads each vector element
// in the lower or upper half of the source SIMD&FP register, shifts the unsigned
// integer value left by the specified number of bits, places the result into a
// vector, and writes the vector to the destination SIMD&FP register. The
// destination vector elements are twice as long as the source vector elements.
//
// The USHLL instruction extracts vector elements from the lower half of the source
// register. The USHLL2 instruction extracts vector elements from the upper half of
// the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USHLL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USHLL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isFpBits(v2) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        switch sa_ta {
            case 0b0001: sa_shift = uint32(asLit(v2)) + 8
            case 0b0010: sa_shift = uint32(asLit(v2)) + 16
            case 0b0100: sa_shift = uint32(asLit(v2)) + 32
            default: panic("aarch64: invalid operand 'sa_shift' for USHLL2")
        }
        if ubfx(sa_shift, 3, 4) != sa_ta & sa_ta__bit_mask ||
           sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for USHLL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for USHLL2")
        }
        return p.setins(asimdshf(1, 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for USHLL2")
}

// USHR instruction have 2 forms across one single category:
//
// 1. Unsigned Shift Right (immediate)
//
//    USHR  <Vd>.<T>, <Vn>.<T>, #<shift>
//    USHR  <V><d>, <V><n>, #<shift>
//
// Unsigned Shift Right (immediate). This instruction reads each vector element in
// the source SIMD&FP register, right shifts each result by an immediate value,
// writes the final result to a vector, and writes the vector to the destination
// SIMD&FP register. All the values in this instruction are unsigned integer
// values. The results are truncated. For rounded results, see URSHR .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USHR(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USHR", 3, asm.Operands { v0, v1, v2 })
    // USHR  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            case 0b1000: sa_shift = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for USHR")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for USHR")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 0, sa_vn, sa_vd))
    }
    // USHR  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 1, 64) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for USHR")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for USHR")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for USHR")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for USHR")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 0, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for USHR")
}

// USMMLA instruction have one single form across one single category:
//
// 1. Unsigned and signed 8-bit integer matrix multiply-accumulate (vector)
//
//    USMMLA  <Vd>.4S, <Vn>.16B, <Vm>.16B
//
// Unsigned and signed 8-bit integer matrix multiply-accumulate. This instruction
// multiplies the 2x8 matrix of unsigned 8-bit integer values in the first source
// vector by the 8x2 matrix of signed 8-bit integer values in the second source
// vector. The resulting 2x2 32-bit integer matrix product is destructively added
// to the 32-bit integer matrix accumulator in the destination vector. This is
// equivalent to performing an 8-way dot product per destination element.
//
// From Armv8.2 to Armv8.5, this is an optional instruction. From Armv8.6 it is
// mandatory for implementations that include Advanced SIMD to support it.
// ID_AA64ISAR1_EL1 .I8MM indicates whether this instruction is supported.
//
func (self *Program) USMMLA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USMMLA", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) && vfmt(v0) == Vec4S && isVr(v1) && vfmt(v1) == Vec16B && isVr(v2) && vfmt(v2) == Vec16B {
        self.Arch.Require(FEAT_I8MM)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdsame2(1, 0, 2, sa_vm, 5, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for USMMLA")
}

// USQADD instruction have 2 forms across one single category:
//
// 1. Unsigned saturating Accumulate of Signed value
//
//    USQADD  <Vd>.<T>, <Vn>.<T>
//    USQADD  <V><d>, <V><n>
//
// Unsigned saturating Accumulate of Signed value. This instruction adds the signed
// integer values of the vector elements in the source SIMD&FP register to
// corresponding unsigned integer values of the vector elements in the destination
// SIMD&FP register, and accumulates the resulting unsigned integer values with the
// vector elements of the destination SIMD&FP register.
//
// If overflow occurs with any of the results, those results are saturated. If
// saturation occurs, the cumulative saturation bit FPSR .QC is set.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USQADD(v0, v1 interface{}) *Instruction {
    p := self.alloc("USQADD", 2, asm.Operands { v0, v1 })
    // USQADD  <Vd>.<T>, <Vn>.<T>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        return p.setins(asimdmisc(mask(sa_t, 1), 1, ubfx(sa_t, 1, 2), 3, sa_vn, sa_vd))
    }
    // USQADD  <V><d>, <V><n>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_v uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case BRegister: sa_v = 0b00
            case HRegister: sa_v = 0b01
            case SRegister: sa_v = 0b10
            case DRegister: sa_v = 0b11
            default: panic("aarch64: invalid scalar operand size for USQADD")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        return p.setins(asisdmisc(1, sa_v, 3, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for USQADD")
}

// USRA instruction have 2 forms across one single category:
//
// 1. Unsigned Shift Right and Accumulate (immediate)
//
//    USRA  <Vd>.<T>, <Vn>.<T>, #<shift>
//    USRA  <V><d>, <V><n>, #<shift>
//
// Unsigned Shift Right and Accumulate (immediate). This instruction reads each
// vector element in the source SIMD&FP register, right shifts each result by an
// immediate value, and accumulates the final results with the vector elements of
// the destination SIMD&FP register. All the values in this instruction are
// unsigned integer values. The results are truncated. For rounded results, see
// URSRA .
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USRA(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USRA", 3, asm.Operands { v0, v1, v2 })
    // USRA  <Vd>.<T>, <Vn>.<T>, #<shift>
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isFpBits(v2) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_shift uint32
        var sa_t uint32
        var sa_t__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b00010
            case Vec16B: sa_t = 0b00011
            case Vec4H: sa_t = 0b00100
            case Vec8H: sa_t = 0b00101
            case Vec2S: sa_t = 0b01000
            case Vec4S: sa_t = 0b01001
            case Vec2D: sa_t = 0b10001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8B: sa_t__bit_mask = 0b11111
            case Vec16B: sa_t__bit_mask = 0b11111
            case Vec4H: sa_t__bit_mask = 0b11101
            case Vec8H: sa_t__bit_mask = 0b11101
            case Vec2S: sa_t__bit_mask = 0b11001
            case Vec4S: sa_t__bit_mask = 0b11001
            case Vec2D: sa_t__bit_mask = 0b10001
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch ubfx(sa_t, 1, 4) {
            case 0b0001: sa_shift = 16 - uint32(asLit(v2))
            case 0b0010: sa_shift = 32 - uint32(asLit(v2))
            case 0b0100: sa_shift = 64 - uint32(asLit(v2))
            case 0b1000: sa_shift = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift' for USRA")
        }
        if ubfx(sa_shift, 3, 4) != ubfx(sa_t, 1, 4) & ubfx(sa_t__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for USRA")
        }
        return p.setins(asimdshf(mask(sa_t, 1), 1, ubfx(sa_shift, 3, 4), mask(sa_shift, 3), 2, sa_vn, sa_vd))
    }
    // USRA  <V><d>, <V><n>, #<shift>
    if isAdvSIMD(v0) && isAdvSIMD(v1) && isInRange(v2, 1, 64) && isSameType(v0, v1) {
        p.Domain = DomainAdvSimd
        var sa_shift_1 uint32
        var sa_v uint32
        var sa_v__bit_mask uint32
        sa_d := uint32(v0.(asm.Register).ID())
        switch v0.(type) {
            case DRegister: sa_v = 0b1000
            default: panic("aarch64: invalid scalar operand size for USRA")
        }
        switch v0.(type) {
            case DRegister: sa_v__bit_mask = 0b1000
            default: panic("aarch64: invalid scalar operand size for USRA")
        }
        sa_n := uint32(v1.(asm.Register).ID())
        switch sa_v {
            case 0b1000: sa_shift_1 = 128 - uint32(asLit(v2))
            default: panic("aarch64: invalid operand 'sa_shift_1' for USRA")
        }
        if ubfx(sa_shift_1, 3, 4) != sa_v & sa_v__bit_mask {
            panic("aarch64: invalid combination of operands for USRA")
        }
        return p.setins(asisdshf(1, ubfx(sa_shift_1, 3, 4), mask(sa_shift_1, 3), 2, sa_n, sa_d))
    }
    // none of above
    p.Free()
    panic("aarch64: invalid combination of operands for USRA")
}

// USUBL instruction have one single form across one single category:
//
// 1. Unsigned Subtract Long
//
//    USUBL  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Subtract Long. This instruction subtracts each vector element in the
// lower or upper half of the second source SIMD&FP register from the corresponding
// vector element of the first source SIMD&FP register, places the result into a
// vector, and writes the vector to the destination SIMD&FP register. All the
// values in this instruction are unsigned integer values. The destination vector
// elements are twice as long as the source vector elements.
//
// The USUBL instruction extracts each source vector from the lower half of each
// source register. The USUBL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USUBL(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USUBL", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for USUBL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for USUBL")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for USUBL")
}

// USUBL2 instruction have one single form across one single category:
//
// 1. Unsigned Subtract Long
//
//    USUBL2  <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>
//
// Unsigned Subtract Long. This instruction subtracts each vector element in the
// lower or upper half of the second source SIMD&FP register from the corresponding
// vector element of the first source SIMD&FP register, places the result into a
// vector, and writes the vector to the destination SIMD&FP register. All the
// values in this instruction are unsigned integer values. The destination vector
// elements are twice as long as the source vector elements.
//
// The USUBL instruction extracts each source vector from the lower half of each
// source register. The USUBL2 instruction extracts each source vector from the
// upper half of each source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USUBL2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USUBL2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vm := uint32(v2.(asm.Register).ID())
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for USUBL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for USUBL2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 2, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for USUBL2")
}

// USUBW instruction have one single form across one single category:
//
// 1. Unsigned Subtract Wide
//
//    USUBW  <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>
//
// Unsigned Subtract Wide. This instruction subtracts each vector element of the
// second source SIMD&FP register from the corresponding vector element in the
// lower or upper half of the first source SIMD&FP register, places the result in a
// vector, and writes the vector to the SIMD&FP destination register. All the
// values in this instruction are unsigned integer values.
//
// The vector elements of the destination register and the first source register
// are twice as long as the vector elements of the second source register.
//
// The USUBW instruction extracts vector elements from the lower half of the first
// source register. The USUBW2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USUBW(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USUBW", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch vfmt(v2) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for USUBW")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for USUBW")
        }
        return p.setins(asimddiff(0, 1, sa_ta, sa_vm, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for USUBW")
}

// USUBW2 instruction have one single form across one single category:
//
// 1. Unsigned Subtract Wide
//
//    USUBW2  <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>
//
// Unsigned Subtract Wide. This instruction subtracts each vector element of the
// second source SIMD&FP register from the corresponding vector element in the
// lower or upper half of the first source SIMD&FP register, places the result in a
// vector, and writes the vector to the SIMD&FP destination register. All the
// values in this instruction are unsigned integer values.
//
// The vector elements of the destination register and the first source register
// are twice as long as the vector elements of the second source register.
//
// The USUBW instruction extracts vector elements from the lower half of the first
// source register. The USUBW2 instruction extracts vector elements from the upper
// half of the first source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) USUBW2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("USUBW2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       vfmt(v0) == vfmt(v1) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        switch vfmt(v2) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for USUBW2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for USUBW2")
        }
        return p.setins(asimddiff(1, 1, sa_ta, sa_vm, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for USUBW2")
}

// UXTB instruction have one single form across one single category:
//
// 1. Unsigned Extend Byte
//
//    UXTB  <Wd>, <Wn>
//
// Unsigned Extend Byte extracts an 8-bit value from a register, zero-extends it to
// the size of the register, and writes the result to the destination register.
//
func (self *Program) UXTB(v0, v1 interface{}) *Instruction {
    p := self.alloc("UXTB", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(bitfield(0, 2, 0, 0, 7, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UXTB")
}

// UXTH instruction have one single form across one single category:
//
// 1. Unsigned Extend Halfword
//
//    UXTH  <Wd>, <Wn>
//
// Unsigned Extend Halfword extracts a 16-bit value from a register, zero-extends
// it to the size of the register, and writes the result to the destination
// register.
//
func (self *Program) UXTH(v0, v1 interface{}) *Instruction {
    p := self.alloc("UXTH", 2, asm.Operands { v0, v1 })
    if isWr(v0) && isWr(v1) {
        p.Domain = asm.DomainGeneric
        sa_wd := uint32(v0.(asm.Register).ID())
        sa_wn := uint32(v1.(asm.Register).ID())
        return p.setins(bitfield(0, 2, 0, 0, 15, sa_wn, sa_wd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UXTH")
}

// UXTL instruction have one single form across one single category:
//
// 1. Unsigned extend Long
//
//    UXTL  <Vd>.<Ta>, <Vn>.<Tb>
//
// Unsigned extend Long. This instruction copies each vector element from the lower
// or upper half of the source SIMD&FP register into a vector, and writes the
// vector to the destination SIMD&FP register. The destination vector elements are
// twice as long as the source vector elements.
//
// The UXTL instruction extracts vector elements from the lower half of the source
// register. The UXTL2 instruction extracts vector elements from the upper half of
// the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UXTL(v0, v1 interface{}) *Instruction {
    p := self.alloc("UXTL", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        if sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for UXTL")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for UXTL")
        }
        return p.setins(asimdshf(0, 1, sa_ta, 0, 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UXTL")
}

// UXTL2 instruction have one single form across one single category:
//
// 1. Unsigned extend Long
//
//    UXTL2  <Vd>.<Ta>, <Vn>.<Tb>
//
// Unsigned extend Long. This instruction copies each vector element from the lower
// or upper half of the source SIMD&FP register into a vector, and writes the
// vector to the destination SIMD&FP register. The destination vector elements are
// twice as long as the source vector elements.
//
// The UXTL instruction extracts vector elements from the lower half of the source
// register. The UXTL2 instruction extracts vector elements from the upper half of
// the source register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UXTL2(v0, v1 interface{}) *Instruction {
    p := self.alloc("UXTL2", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec8H, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_ta__bit_mask uint32
        var sa_tb uint32
        var sa_tb__bit_mask uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8H: sa_ta = 0b0001
            case Vec4S: sa_ta = 0b0010
            case Vec2D: sa_ta = 0b0100
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v0) {
            case Vec8H: sa_ta__bit_mask = 0b1111
            case Vec4S: sa_ta__bit_mask = 0b1110
            case Vec2D: sa_ta__bit_mask = 0b1100
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8B: sa_tb = 0b00010
            case Vec16B: sa_tb = 0b00011
            case Vec4H: sa_tb = 0b00100
            case Vec8H: sa_tb = 0b00101
            case Vec2S: sa_tb = 0b01000
            case Vec4S: sa_tb = 0b01001
            default: panic("aarch64: unreachable")
        }
        switch vfmt(v1) {
            case Vec8B: sa_tb__bit_mask = 0b11111
            case Vec16B: sa_tb__bit_mask = 0b11111
            case Vec4H: sa_tb__bit_mask = 0b11101
            case Vec8H: sa_tb__bit_mask = 0b11101
            case Vec2S: sa_tb__bit_mask = 0b11001
            case Vec4S: sa_tb__bit_mask = 0b11001
            default: panic("aarch64: unreachable")
        }
        if sa_ta & sa_ta__bit_mask != ubfx(sa_tb, 1, 4) & ubfx(sa_tb__bit_mask, 1, 4) {
            panic("aarch64: invalid combination of operands for UXTL2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for UXTL2")
        }
        return p.setins(asimdshf(1, 1, sa_ta, 0, 20, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UXTL2")
}

// UZP1 instruction have one single form across one single category:
//
// 1. Unzip vectors (primary)
//
//    UZP1  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unzip vectors (primary). This instruction reads corresponding even-numbered
// vector elements from the two source SIMD&FP registers, starting at zero, places
// the result from the first source register into consecutive elements in the lower
// half of a vector, and the result from the second source register into
// consecutive elements in the upper half of a vector, and writes the vector to the
// destination SIMD&FP register.
//
// NOTE: 
//     This instruction can be used with UZP2 to de-interleave two vectors.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.uzp1_uzp2_8_operation_doubleword.svg]
// UZP1 and UZP2 with the arrangement specifier 8B
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UZP1(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UZP1", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdperm(mask(sa_t, 1), ubfx(sa_t, 1, 2), sa_vm, 1, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UZP1")
}

// UZP2 instruction have one single form across one single category:
//
// 1. Unzip vectors (secondary)
//
//    UZP2  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Unzip vectors (secondary). This instruction reads corresponding odd-numbered
// vector elements from the two source SIMD&FP registers, places the result from
// the first source register into consecutive elements in the lower half of a
// vector, and the result from the second source register into consecutive elements
// in the upper half of a vector, and writes the vector to the destination SIMD&FP
// register.
//
// NOTE: 
//     This instruction can be used with UZP1 to de-interleave two vectors.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.uzp1_uzp2_8_operation_doubleword.svg]
// UZP1 and UZP2 with the arrangement specifier 8B
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) UZP2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("UZP2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdperm(mask(sa_t, 1), ubfx(sa_t, 1, 2), sa_vm, 5, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for UZP2")
}

// WFE instruction have one single form across one single category:
//
// 1. Wait For Event
//
//    WFE
//
// Wait For Event is a hint instruction that indicates that the PE can enter a low-
// power state and remain there until a wakeup event occurs. Wakeup events include
// the event signaled as a result of executing the SEV instruction on any PE in the
// multiprocessor system. For more information, see Wait For Event mechanism and
// Send event .
//
// As described in Wait For Event mechanism and Send event , the execution of a WFE
// instruction that would otherwise cause entry to a low-power state can be trapped
// to a higher Exception level.
//
func (self *Program) WFE() *Instruction {
    p := self.alloc("WFE", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(hints(0, 2))
}

// WFET instruction have one single form across one single category:
//
// 1. Wait For Event with Timeout
//
//    WFET  <Xt>
//
// Wait For Event with Timeout is a hint instruction that indicates that the PE can
// enter a low-power state and remain there until either a local timeout event or a
// wakeup event occurs. Wakeup events include the event signaled as a result of
// executing the SEV instruction on any PE in the multiprocessor system. For more
// information, see Wait For Event mechanism and Send event .
//
// As described in Wait For Event mechanism and Send event , the execution of a
// WFET instruction that would otherwise cause entry to a low-power state can be
// trapped to a higher Exception level.
//
func (self *Program) WFET(v0 interface{}) *Instruction {
    p := self.alloc("WFET", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_WFxT)
        p.Domain = DomainSystem
        sa_xt := uint32(v0.(asm.Register).ID())
        Rt := uint32(0b00000)
        Rt |= sa_xt
        return p.setins(systeminstrswithreg(0, 0, Rt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for WFET")
}

// WFI instruction have one single form across one single category:
//
// 1. Wait For Interrupt
//
//    WFI
//
// Wait For Interrupt is a hint instruction that indicates that the PE can enter a
// low-power state and remain there until a wakeup event occurs. For more
// information, see Wait For Interrupt .
//
// As described in Wait For Interrupt , the execution of a WFI instruction that
// would otherwise cause entry to a low-power state can be trapped to a higher
// Exception level.
//
func (self *Program) WFI() *Instruction {
    p := self.alloc("WFI", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(hints(0, 3))
}

// WFIT instruction have one single form across one single category:
//
// 1. Wait For Interrupt with Timeout
//
//    WFIT  <Xt>
//
// Wait For Interrupt with Timeout is a hint instruction that indicates that the PE
// can enter a low-power state and remain there until either a local timeout event
// or a wakeup event occurs. For more information, see Wait For Interrupt .
//
// As described in Wait For Interrupt , the execution of a WFIT instruction that
// would otherwise cause entry to a low-power state can be trapped to a higher
// Exception level.
//
func (self *Program) WFIT(v0 interface{}) *Instruction {
    p := self.alloc("WFIT", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_WFxT)
        p.Domain = DomainSystem
        sa_xt := uint32(v0.(asm.Register).ID())
        Rt := uint32(0b00000)
        Rt |= sa_xt
        return p.setins(systeminstrswithreg(0, 1, Rt))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for WFIT")
}

// XAFLAG instruction have one single form across one single category:
//
// 1. Convert floating-point condition flags from external format to Arm format
//
//    XAFLAG
//
// Convert floating-point condition flags from external format to Arm format. This
// instruction converts the state of the PSTATE.{N,Z,C,V} flags from an alternative
// representation required by some software to a form representing the result of an
// Arm floating-point scalar compare instruction.
//
func (self *Program) XAFLAG() *Instruction {
    p := self.alloc("XAFLAG", 0, asm.Operands {})
    self.Arch.Require(FEAT_FlagM2)
    p.Domain = DomainSystem
    return p.setins(pstate(0, 0, 1, 31))
}

// XAR instruction have one single form across one single category:
//
// 1. Exclusive-OR and Rotate
//
//    XAR  <Vd>.2D, <Vn>.2D, <Vm>.2D, #<imm6>
//
// Exclusive-OR and Rotate performs a bitwise exclusive-OR of the 128-bit vectors
// in the two source SIMD&FP registers, rotates each 64-bit element of the
// resulting 128-bit vector right by the value specified by a 6-bit immediate
// value, and writes the result to the destination SIMD&FP register.
//
// This instruction is implemented only when FEAT_SHA3 is implemented.
//
func (self *Program) XAR(v0, v1, v2, v3 interface{}) *Instruction {
    p := self.alloc("XAR", 4, asm.Operands { v0, v1, v2, v3 })
    if isVr(v0) && vfmt(v0) == Vec2D && isVr(v1) && vfmt(v1) == Vec2D && isVr(v2) && vfmt(v2) == Vec2D && isUimm6(v3) {
        self.Arch.Require(FEAT_SHA3)
        p.Domain = DomainAdvSimd
        sa_vd := uint32(v0.(asm.Register).ID())
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        sa_imm6 := asUimm6(v3)
        return p.setins(crypto3_imm6(sa_vm, sa_imm6, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for XAR")
}

// XPACD instruction have one single form across one single category:
//
// 1. Strip Pointer Authentication Code
//
//    XPACD  <Xd>
//
// Strip Pointer Authentication Code. This instruction removes the pointer
// authentication code from an address. The address is in the specified general-
// purpose register for XPACI and XPACD , and is in LR for XPACLRI .
//
// The XPACD instruction is used for data addresses, and XPACI and XPACLRI are used
// for instruction addresses.
//
func (self *Program) XPACD(v0 interface{}) *Instruction {
    p := self.alloc("XPACD", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 17, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for XPACD")
}

// XPACI instruction have one single form across one single category:
//
// 1. Strip Pointer Authentication Code
//
//    XPACI  <Xd>
//
// Strip Pointer Authentication Code. This instruction removes the pointer
// authentication code from an address. The address is in the specified general-
// purpose register for XPACI and XPACD , and is in LR for XPACLRI .
//
// The XPACD instruction is used for data addresses, and XPACI and XPACLRI are used
// for instruction addresses.
//
func (self *Program) XPACI(v0 interface{}) *Instruction {
    p := self.alloc("XPACI", 1, asm.Operands { v0 })
    if isXr(v0) {
        self.Arch.Require(FEAT_PAuth)
        p.Domain = asm.DomainGeneric
        sa_xd := uint32(v0.(asm.Register).ID())
        return p.setins(dp_1src(1, 0, 1, 16, 31, sa_xd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for XPACI")
}

// XPACLRI instruction have one single form across one single category:
//
// 1. Strip Pointer Authentication Code
//
//    XPACLRI
//
// Strip Pointer Authentication Code. This instruction removes the pointer
// authentication code from an address. The address is in the specified general-
// purpose register for XPACI and XPACD , and is in LR for XPACLRI .
//
// The XPACD instruction is used for data addresses, and XPACI and XPACLRI are used
// for instruction addresses.
//
func (self *Program) XPACLRI() *Instruction {
    p := self.alloc("XPACLRI", 0, asm.Operands {})
    self.Arch.Require(FEAT_PAuth)
    p.Domain = DomainSystem
    return p.setins(hints(0, 7))
}

// XTN instruction have one single form across one single category:
//
// 1. Extract Narrow
//
//    XTN  <Vd>.<Tb>, <Vn>.<Ta>
//
// Extract Narrow. This instruction reads each vector element from the source
// SIMD&FP register, narrows each value to half the original width, places the
// result into a vector, and writes the vector to the lower or upper half of the
// destination SIMD&FP register. The destination vector elements are half as long
// as the source vector elements.
//
// The XTN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the XTN2 instruction writes the vector
// to the upper half of the destination register without affecting the other bits
// of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) XTN(v0, v1 interface{}) *Instruction {
    p := self.alloc("XTN", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for XTN")
        }
        if mask(sa_tb, 1) != 0 {
            panic("aarch64: invalid combination of operands for XTN")
        }
        return p.setins(asimdmisc(0, 0, sa_ta, 18, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for XTN")
}

// XTN2 instruction have one single form across one single category:
//
// 1. Extract Narrow
//
//    XTN2  <Vd>.<Tb>, <Vn>.<Ta>
//
// Extract Narrow. This instruction reads each vector element from the source
// SIMD&FP register, narrows each value to half the original width, places the
// result into a vector, and writes the vector to the lower or upper half of the
// destination SIMD&FP register. The destination vector elements are half as long
// as the source vector elements.
//
// The XTN instruction writes the vector to the lower half of the destination
// register and clears the upper half, while the XTN2 instruction writes the vector
// to the upper half of the destination register without affecting the other bits
// of the register.
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) XTN2(v0, v1 interface{}) *Instruction {
    p := self.alloc("XTN2", 2, asm.Operands { v0, v1 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S) &&
       isVr(v1) &&
       isVfmt(v1, Vec8H, Vec4S, Vec2D) {
        p.Domain = DomainAdvSimd
        var sa_ta uint32
        var sa_tb uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_tb = 0b000
            case Vec16B: sa_tb = 0b001
            case Vec4H: sa_tb = 0b010
            case Vec8H: sa_tb = 0b011
            case Vec2S: sa_tb = 0b100
            case Vec4S: sa_tb = 0b101
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        switch vfmt(v1) {
            case Vec8H: sa_ta = 0b00
            case Vec4S: sa_ta = 0b01
            case Vec2D: sa_ta = 0b10
            default: panic("aarch64: unreachable")
        }
        if sa_ta != ubfx(sa_tb, 1, 2) {
            panic("aarch64: invalid combination of operands for XTN2")
        }
        if mask(sa_tb, 1) != 1 {
            panic("aarch64: invalid combination of operands for XTN2")
        }
        return p.setins(asimdmisc(1, 0, sa_ta, 18, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for XTN2")
}

// YIELD instruction have one single form across one single category:
//
// 1. YIELD
//
//    YIELD
//
// YIELD is a hint instruction. Software with a multithreading capability can use a
// YIELD instruction to indicate to the PE that it is performing a task, for
// example a spin-lock, that could be swapped out to improve overall system
// performance. The PE can use this hint to suspend and resume multiple software
// threads if it supports the capability.
//
// For more information about the recommended use of this instruction, see The
// YIELD instruction .
//
func (self *Program) YIELD() *Instruction {
    p := self.alloc("YIELD", 0, asm.Operands {})
    p.Domain = DomainSystem
    return p.setins(hints(0, 1))
}

// ZIP1 instruction have one single form across one single category:
//
// 1. Zip vectors (primary)
//
//    ZIP1  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Zip vectors (primary). This instruction reads adjacent vector elements from the
// lower half of two source SIMD&FP registers as pairs, interleaves the pairs and
// places them into a vector, and writes the vector to the destination SIMD&FP
// register. The first pair from the first source register is placed into the two
// lowest vector elements, with subsequent pairs taken alternately from each source
// register.
//
// NOTE: 
//     This instruction can be used with ZIP2 to interleave two vectors.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.zip1_zip2_8_operation_doubleword.svg]
// ZIP1 and ZIP2 with the arrangement specifier 8B
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ZIP1(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ZIP1", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdperm(mask(sa_t, 1), ubfx(sa_t, 1, 2), sa_vm, 3, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ZIP1")
}

// ZIP2 instruction have one single form across one single category:
//
// 1. Zip vectors (secondary)
//
//    ZIP2  <Vd>.<T>, <Vn>.<T>, <Vm>.<T>
//
// Zip vectors (secondary). This instruction reads adjacent vector elements from
// the upper half of two source SIMD&FP registers as pairs, interleaves the pairs
// and places them into a vector, and writes the vector to the destination SIMD&FP
// register. The first pair from the first source register is placed into the two
// lowest vector elements, with subsequent pairs taken alternately from each source
// register.
//
// NOTE: 
//     This instruction can be used with ZIP1 to interleave two vectors.
//
// [image:isa_docs/ISA_A64_xml_A_profile-2023-03_OPT/A64.zip1_zip2_8_operation_doubleword.svg]
// ZIP1 and ZIP2 with the arrangement specifier 8B
//
// Depending on the settings in the CPACR_EL1 , CPTR_EL2 , and CPTR_EL3 registers,
// and the current Security state and Exception level, an attempt to execute the
// instruction might be trapped.
//
func (self *Program) ZIP2(v0, v1, v2 interface{}) *Instruction {
    p := self.alloc("ZIP2", 3, asm.Operands { v0, v1, v2 })
    if isVr(v0) &&
       isVfmt(v0, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v1) &&
       isVfmt(v1, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       isVr(v2) &&
       isVfmt(v2, Vec8B, Vec16B, Vec4H, Vec8H, Vec2S, Vec4S, Vec2D) &&
       vfmt(v0) == vfmt(v1) &&
       vfmt(v1) == vfmt(v2) {
        p.Domain = DomainAdvSimd
        var sa_t uint32
        sa_vd := uint32(v0.(asm.Register).ID())
        switch vfmt(v0) {
            case Vec8B: sa_t = 0b000
            case Vec16B: sa_t = 0b001
            case Vec4H: sa_t = 0b010
            case Vec8H: sa_t = 0b011
            case Vec2S: sa_t = 0b100
            case Vec4S: sa_t = 0b101
            case Vec2D: sa_t = 0b111
            default: panic("aarch64: unreachable")
        }
        sa_vn := uint32(v1.(asm.Register).ID())
        sa_vm := uint32(v2.(asm.Register).ID())
        return p.setins(asimdperm(mask(sa_t, 1), ubfx(sa_t, 1, 2), sa_vm, 7, sa_vn, sa_vd))
    }
    p.Free()
    panic("aarch64: invalid combination of operands for ZIP2")
}
