///|
fn Instruction::instr_bytes(self : Instruction) -> (Int, Int, Int, Int) {
  match self {
    AddReg(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 139
      (b0, b1, b2, b3)
    }
    AddShifted(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 63
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 139
      (b0, b1, b2, b3)
    }
    AddShifted32(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 31
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 0x0B // ADD (shifted register), 32-bit
      (b0, b1, b2, b3)
    }
    AddExtUxtw(rd, rn, rm, shift) => {
      // ADD (extended register): sf=1 (64-bit), op=0 (add), S=0, option=UXTW (010)
      // Encoding:  sf op S 01011 00 1 Rm option imm3 Rn Rd
      // See ARM ARM "Add/subtract (extended register)".
      let imm3 = shift & 7
      let option_uxtw = 2 // 010 = UXTW
      let inst = (0b1 << 31) |
        (0 << 30) |
        (0 << 29) |
        (0b01011 << 24) |
        (0 << 22) |
        (0b1 << 21) |
        ((rm & 31) << 16) |
        ((option_uxtw & 7) << 13) |
        ((imm3 & 7) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    AddExtSxtw(rd, rn, rm, shift) => {
      // ADD (extended register): sf=1 (64-bit), op=0 (add), S=0, option=SXTW (110)
      let imm3 = shift & 7
      let option_sxtw = 6 // 110 = SXTW
      let inst = (0b1 << 31) |
        (0 << 30) |
        (0 << 29) |
        (0b01011 << 24) |
        (0 << 22) |
        (0b1 << 21) |
        ((rm & 31) << 16) |
        ((option_sxtw & 7) << 13) |
        ((imm3 & 7) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    SubExtUxtw(rd, rn, rm, shift) => {
      // SUB (extended register): sf=1 (64-bit), op=1 (sub), S=0, option=UXTW (010)
      let imm3 = shift & 7
      let option_uxtw = 2 // 010 = UXTW
      let inst = (0b1 << 31) |
        (1 << 30) |
        (0 << 29) |
        (0b01011 << 24) |
        (0 << 22) |
        (0b1 << 21) |
        ((rm & 31) << 16) |
        ((option_uxtw & 7) << 13) |
        ((imm3 & 7) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    SubExtSxtw(rd, rn, rm, shift) => {
      // SUB (extended register): sf=1 (64-bit), op=1 (sub), S=0, option=SXTW (110)
      let imm3 = shift & 7
      let option_sxtw = 6 // 110 = SXTW
      let inst = (0b1 << 31) |
        (1 << 30) |
        (0 << 29) |
        (0b01011 << 24) |
        (0 << 22) |
        (0b1 << 21) |
        ((rm & 31) << 16) |
        ((option_sxtw & 7) << 13) |
        ((imm3 & 7) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    AddImm(rd, rn, imm12) => {
      let imm = imm12 & 0xFFF
      let inst = (0b1 << 31) |
        (0 << 30) |
        (0 << 29) |
        (0b100010 << 23) |
        (0 << 22) |
        (imm << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    AddImmShifted12(rd, rn, imm12) => {
      // Same as AddImm but with sh=1 (bit 22)
      let imm = imm12 & 0xFFF
      let inst = (0b1 << 31) |
        (0 << 30) |
        (0 << 29) |
        (0b100010 << 23) |
        (1 << 22) | // sh=1: shift imm12 left by 12
        (imm << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    SubReg(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 203
      (b0, b1, b2, b3)
    }
    SubShifted(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 63
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 203
      (b0, b1, b2, b3)
    }
    SubShifted32(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 31
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 0x4B // SUB (shifted register), 32-bit
      (b0, b1, b2, b3)
    }
    SubImm(rd, rn, imm12) => {
      let imm = imm12 & 0xFFF
      let inst = (0b1 << 31) |
        (1 << 30) |
        (0 << 29) |
        (0b100010 << 23) |
        (0 << 22) |
        (imm << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    SubImmShifted12(rd, rn, imm12) => {
      // Same as SubImm but with sh=1 (bit 22)
      let imm = imm12 & 0xFFF
      let inst = (0b1 << 31) |
        (1 << 30) |
        (0 << 29) |
        (0b100010 << 23) |
        (1 << 22) | // sh=1: shift imm12 left by 12
        (imm << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    Mul(rd, rn, rm) => {
      let b0 = (rd & 0x1f) | ((rn & 0x7) << 5)
      let b1 = ((rn >> 3) & 0x3) | 0x7C
      let b2 = rm & 0x1f
      let b3 = 0x9B
      (b0, b1, b2, b3)
    }
    Madd(rd, rn, rm, ra) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((ra & 31) << 2)
      let b2 = rm & 31
      let b3 = 155
      (b0, b1, b2, b3)
    }
    Msub(rd, rn, rm, ra) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((ra & 31) << 2) | 128
      let b2 = rm & 31
      let b3 = 155
      (b0, b1, b2, b3)
    }
    Mneg(rd, rn, rm) => Msub(rd, rn, rm, 31).instr_bytes()
    Madd32(rd, rn, rm, ra) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((ra & 31) << 2)
      let b2 = rm & 31
      let b3 = 0x1B
      (b0, b1, b2, b3)
    }
    Msub32(rd, rn, rm, ra) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((ra & 31) << 2) | 128
      let b2 = rm & 31
      let b3 = 0x1B
      (b0, b1, b2, b3)
    }
    Mneg32(rd, rn, rm) => Msub32(rd, rn, rm, 31).instr_bytes()
    Umulh(rd, rn, rm) => {
      // UMULH: sf=1, op31=110, Ra=11111
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x7C // Ra=31, o0=0
      let b2 = 0xC0 | (rm & 31) // op31=110
      let b3 = 0x9B
      (b0, b1, b2, b3)
    }
    Smulh(rd, rn, rm) => {
      // SMULH: sf=1, op31=010, Ra=11111
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x7C // Ra=31, o0=0
      let b2 = 0x40 | (rm & 31) // op31=010
      let b3 = 0x9B
      (b0, b1, b2, b3)
    }
    Umull(rd, rn, rm) => {
      // UMULL = UMADDL with Ra=XZR: sf=1, op31=101, Ra=11111
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x7C // Ra=31, o0=0
      let b2 = 0xA0 | (rm & 31) // op31=101
      let b3 = 0x9B
      (b0, b1, b2, b3)
    }
    Smull(rd, rn, rm) => {
      // SMULL = SMADDL with Ra=XZR: sf=1, op31=001, Ra=11111
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x7C // Ra=31, o0=0
      let b2 = 0x20 | (rm & 31) // op31=001
      let b3 = 0x9B
      (b0, b1, b2, b3)
    }
    Sdiv(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (3 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x9A
      (b0, b1, b2, b3)
    }
    Udiv(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (2 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x9A
      (b0, b1, b2, b3)
    }
    Sdiv32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (3 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x1A // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    Udiv32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (2 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x1A // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    SubReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 0x4B // SUB 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    AddReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 0x0B // ADD 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    AddImm32(rd, rn, imm) => {
      // ADD Wd, Wn, #imm (32-bit)
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm & 0x3F) << 2)
      let b2 = (imm >> 6) & 0x3F
      let b3 = 0x11 // ADD imm 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    AddImm32Shifted12(rd, rn, imm12) => {
      // ADD Wd, Wn, #imm12, lsl #12
      let imm = imm12 & 0xFFF
      let inst = (0b0 << 31) |
        (0 << 30) |
        (0 << 29) |
        (0b100010 << 23) |
        (1 << 22) | // sh=1: shift imm12 left by 12
        (imm << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    SubImm32(rd, rn, imm) => {
      // SUB Wd, Wn, #imm (32-bit)
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm & 0x3F) << 2)
      let b2 = (imm >> 6) & 0x3F
      let b3 = 0x51 // SUB imm 32-bit: sf=0, op=1
      (b0, b1, b2, b3)
    }
    SubImm32Shifted12(rd, rn, imm12) => {
      // SUB Wd, Wn, #imm12, lsl #12
      let imm = imm12 & 0xFFF
      let inst = (0b0 << 31) |
        (1 << 30) |
        (0 << 29) |
        (0b100010 << 23) |
        (1 << 22) | // sh=1: shift imm12 left by 12
        (imm << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    Mul32(rd, rn, rm) => {
      // MUL Wd, Wn, Wm (32-bit) = MADD Wd, Wn, Wm, WZR
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (0x1F << 2) // ra = 31 (WZR)
      let b2 = (rm & 31) | (0 << 5)
      let b3 = 0x1B // MADD 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    AndReg(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 138
      (b0, b1, b2, b3)
    }
    AndReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 0x0A // AND 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    BicReg(rd, rn, rm) => {
      // BIC Xd, Xn, Xm (AND with NOT Rm) = AND shifted-register with N=1.
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = (rm & 31) | 0x20
      let b3 = 138
      (b0, b1, b2, b3)
    }
    BicReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = (rm & 31) | 0x20
      let b3 = 0x0A
      (b0, b1, b2, b3)
    }
    AndImm(rd, rn, imm_bits) => {
      // AND (immediate): bits_31_23 = 000_100100 with sf=1.
      let top9 = 0b000_100100 | (1 << 8)
      let inst = (top9 << 23) |
        ((imm_bits & 0x1FFF) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    AndImm32(rd, rn, imm_bits) => {
      // AND (immediate) 32-bit: bits_31_23 = 000_100100 with sf=0.
      let top9 = 0b000_100100
      let inst = (top9 << 23) |
        ((imm_bits & 0x1FFF) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    AndShifted(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 63
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 138
      (b0, b1, b2, b3)
    }
    AndShifted32(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 31
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 0x0A // AND (shifted register), 32-bit
      (b0, b1, b2, b3)
    }
    OrrReg(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 170
      (b0, b1, b2, b3)
    }
    OrrReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 0x2A // ORR 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    OrnReg(rd, rn, rm) => {
      // ORN Xd, Xn, Xm (OR with NOT Rm) = ORR shifted-register with N=1.
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = (rm & 31) | 0x20
      let b3 = 170
      (b0, b1, b2, b3)
    }
    OrnReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = (rm & 31) | 0x20
      let b3 = 0x2A
      (b0, b1, b2, b3)
    }
    OrrImm(rd, rn, imm_bits) => {
      // ORR (immediate): bits_31_23 = 001_100100 with sf=1.
      let top9 = 0b001_100100 | (1 << 8)
      let inst = (top9 << 23) |
        ((imm_bits & 0x1FFF) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    OrrImm32(rd, rn, imm_bits) => {
      // ORR (immediate) 32-bit: bits_31_23 = 001_100100 with sf=0.
      let top9 = 0b001_100100
      let inst = (top9 << 23) |
        ((imm_bits & 0x1FFF) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    OrrShifted(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 63
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 170
      (b0, b1, b2, b3)
    }
    OrrShifted32(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 31
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 0x2A // ORR (shifted register), 32-bit
      (b0, b1, b2, b3)
    }
    EorReg(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 202
      (b0, b1, b2, b3)
    }
    EorReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 0x4A // EOR 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    EonReg(rd, rn, rm) => {
      // EON Xd, Xn, Xm (XOR with NOT Rm) = EOR shifted-register with N=1.
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = (rm & 31) | 0x20
      let b3 = 202
      (b0, b1, b2, b3)
    }
    EonReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = (rm & 31) | 0x20
      let b3 = 0x4A
      (b0, b1, b2, b3)
    }
    EorImm(rd, rn, imm_bits) => {
      // EOR (immediate): bits_31_23 = 010_100100 with sf=1.
      let top9 = 0b010_100100 | (1 << 8)
      let inst = (top9 << 23) |
        ((imm_bits & 0x1FFF) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    EorImm32(rd, rn, imm_bits) => {
      // EOR (immediate) 32-bit: bits_31_23 = 010_100100 with sf=0.
      let top9 = 0b010_100100
      let inst = (top9 << 23) |
        ((imm_bits & 0x1FFF) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    EorShifted(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 63
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 202
      (b0, b1, b2, b3)
    }
    EorShifted32(rd, rn, rm, shift, amount) => {
      let shift_bits = match shift {
        Lsl => 0
        Lsr => 1
        Asr => 2
      }
      let imm6 = amount & 31
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm6 & 63) << 2)
      let b2 = (rm & 31) | ((shift_bits & 3) << 6)
      let b3 = 0x4A // EOR (shifted register), 32-bit
      (b0, b1, b2, b3)
    }
    Mvn(rd, rm) => {
      let b0 = (rd & 31) | ((31 & 7) << 5)
      let b1 = (31 >> 3) & 3
      let b2 = (rm & 31) | 32
      let b3 = 170 // 0xAA for 64-bit ORN
      (b0, b1, b2, b3)
    }
    Mvn32(rd, rm) => {
      let b0 = (rd & 31) | ((31 & 7) << 5)
      let b1 = (31 >> 3) & 3
      let b2 = (rm & 31) | 32
      let b3 = 42 // 0x2A for 32-bit ORN (sf=0)
      (b0, b1, b2, b3)
    }
    LslReg(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (8 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x9A
      (b0, b1, b2, b3)
    }
    LsrReg(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (9 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x9A
      (b0, b1, b2, b3)
    }
    AsrReg(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (10 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x9A
      (b0, b1, b2, b3)
    }
    RorReg(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (11 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x9A
      (b0, b1, b2, b3)
    }
    LslReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (8 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x1A // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    LsrReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (9 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x1A // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    AsrReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (10 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x1A // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    RorReg32(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (11 << 2)
      let b2 = 0xC0 | (rm & 31)
      let b3 = 0x1A // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    LsrImm(rd, rn, shift) => {
      // LSR Xd, Xn, #shift = UBFM Xd, Xn, #shift, #63
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = 0xFC | ((rn >> 3) & 3) // imms=63
      let b2 = 0x40 | (shift & 63) // N=1, immr=shift
      let b3 = 0xD3 // sf=1, opc=10, 100110
      (b0, b1, b2, b3)
    }
    LslImm(rd, rn, shift) => {
      // LSL Xd, Xn, #shift (alias of UBFM):
      // Use Cranelift encoding (Inst::AluRRImmShift with ALUOp::Lsl).
      let amt = shift & 63
      let bits = 64
      let immr = ((bits - amt) % bits) & 63
      let imms = (bits - 1 - amt) & 63
      let top10 = 0b0101001100 | (1 << 9) | 1
      let inst = (top10 << 22) |
        ((immr & 63) << 16) |
        ((imms & 63) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    AsrImm(rd, rn, shift) => {
      // ASR Xd, Xn, #shift (alias of SBFM).
      // Use Cranelift encoding (Inst::AluRRImmShift with ALUOp::Asr).
      let amt = shift & 63
      let immr = amt & 63
      let imms = (0b011111 | (1 << 5)) & 63 // 63 for 64-bit
      let top10 = 0b0001001100 | (1 << 9) | 1
      let inst = (top10 << 22) |
        ((immr & 63) << 16) |
        ((imms & 63) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    RorImm(rd, rn, shift) => {
      // ROR Xd, Xn, #shift (alias of EXTR Xd, Xn, Xn, #shift).
      // Use Cranelift encoding (Inst::AluRRImmShift with ALUOp::Extr and rm=rn).
      let amt = shift & 63
      let immr = rn & 31 // rm == rn
      let imms = amt & 63
      let top10 = 0b0001001110 | (1 << 9) | 1
      let inst = (top10 << 22) |
        ((immr & 31) << 16) |
        ((imms & 63) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    ExtrImm(rd, rn, rm, shift) => {
      // EXTR Xd, Xn, Xm, #shift.
      // Encodes: (Xn << (64-shift)) | (Xm >> shift).
      let amt = shift & 63
      let top10 = 0b0001001110 | (1 << 9) | 1
      let inst = (top10 << 22) |
        ((rm & 31) << 16) |
        ((amt & 63) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LsrImm32(rd, rn, shift) => {
      // LSR Wd, Wn, #shift = UBFM Wd, Wn, #shift, #31
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = 0x7C | ((rn >> 3) & 3) // imms=31
      let b2 = shift & 31 // N=0, immr=shift
      let b3 = 0x53 // sf=0, opc=10, 100110
      (b0, b1, b2, b3)
    }
    LslImm32(rd, rn, shift) => {
      // LSL Wd, Wn, #shift (alias of UBFM).
      let amt = shift & 31
      let bits = 32
      let immr = ((bits - amt) % bits) & 31
      let imms = (bits - 1 - amt) & 31
      let top10 = 0b0101001100 // sf=0 => no extra bits
      let inst = (top10 << 22) |
        ((immr & 63) << 16) |
        ((imms & 63) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    AsrImm32(rd, rn, shift) => {
      // ASR Wd, Wn, #shift (alias of SBFM).
      let amt = shift & 31
      let immr = amt & 63
      let imms = 0b011111 // 31 for 32-bit
      let top10 = 0b0001001100
      let inst = (top10 << 22) |
        ((immr & 63) << 16) |
        ((imms & 63) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    RorImm32(rd, rn, shift) => {
      // ROR Wd, Wn, #shift (alias of EXTR Wd, Wn, Wn, #shift).
      let amt = shift & 31
      let immr = rn & 31
      let imms = amt & 63
      let top10 = 0b0001001110
      let inst = (top10 << 22) |
        ((immr & 31) << 16) |
        ((imms & 63) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    ExtrImm32(rd, rn, rm, shift) => {
      // EXTR Wd, Wn, Wm, #shift.
      // Encodes: (Wn << (32-shift)) | (Wm >> shift).
      let amt = shift & 31
      let top10 = 0b0001001110
      let inst = (top10 << 22) |
        ((rm & 31) << 16) |
        ((amt & 63) << 10) |
        ((rn & 31) << 5) |
        (rd & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    UbfxWidth(rd, rn, width) => {
      // UBFX Xd, Xn, #0, #width = UBFM Xd, Xn, #0, #(width-1)
      // Extracts bits [0, width-1] (i.e., mask by (1 << width) - 1)
      let imms = width - 1
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (imms << 2) | ((rn >> 3) & 3)
      let b2 = 0x40 // N=1, immr=0
      let b3 = 0xD3 // sf=1, opc=10, 100110
      (b0, b1, b2, b3)
    }
    Clz(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 16
      let b2 = 192
      let b3 = 218
      (b0, b1, b2, b3)
    }
    Rbit(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = 192
      let b3 = 218
      (b0, b1, b2, b3)
    }
    Clz32(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 16
      let b2 = 192
      let b3 = 0x5A // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    Rbit32(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = 192
      let b3 = 0x5A // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    MovReg(rd, rm) => {
      let b0 = (rd & 31) | ((31 & 7) << 5)
      let b1 = (31 >> 3) & 3
      let b2 = rm & 31
      let b3 = 170
      (b0, b1, b2, b3)
    }
    MovReg32(rd, rm) => {
      let b0 = (rd & 31) | ((31 & 7) << 5)
      let b1 = (31 >> 3) & 3
      let b2 = rm & 31
      let b3 = 0x2A
      (b0, b1, b2, b3)
    }
    Movz(rd, imm16, shift) => {
      let hw = shift / 16
      let imm = imm16 & 0xFFFF
      let b0 = (rd & 31) | ((imm & 7) << 5)
      let b1 = (imm >> 3) & 255
      let b2 = ((imm >> 11) & 31) | ((hw & 3) << 5) | 128
      let xd2 = 210
      let b3 = xd2 | ((hw >> 2) & 1)
      (b0, b1, b2, b3)
    }
    Movk(rd, imm16, shift) => {
      let hw = shift / 16
      let imm = imm16 & 0xFFFF
      let b0 = (rd & 31) | ((imm & 7) << 5)
      let b1 = (imm >> 3) & 255
      let b2 = ((imm >> 11) & 31) | ((hw & 3) << 5) | 128
      let xf2 = 242
      let b3 = xf2 | ((hw >> 2) & 1)
      (b0, b1, b2, b3)
    }
    Movn(rd, imm16, shift) => {
      let hw = shift / 16
      let imm = imm16 & 0xFFFF
      let b0 = (rd & 31) | ((imm & 7) << 5)
      let b1 = (imm >> 3) & 255
      let b2 = ((imm >> 11) & 31) | ((hw & 3) << 5) | 128
      let x92 = 0x92
      let b3 = x92 | ((hw >> 2) & 1)
      (b0, b1, b2, b3)
    }
    LoadImm64(_, _) => abort("LoadImm64 does not have single instruction bytes")
    LdrImm(rt, rn, imm12) => {
      let scaled = (imm12 / 8) & 0xFFF
      let inst = (0b11 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b01 << 24) |
        (0b01 << 22) |
        (scaled << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdrImmSigned(rt, rn, simm9) => {
      let imm9 = simm9 & 0x1FF
      let inst = (0b11 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b01 << 22) |
        (0 << 21) |
        (imm9 << 12) |
        (0b00 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdrRegScaled(rt, rn, rm, shift) => {
      let s_bit = if shift == 3 { 1 } else { 0 }
      let inst = (0b11 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b01 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        (0b011 << 13) |
        (s_bit << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdrRegOffset(rt, rn, rm, option, size_bits, shift) => {
      let natural = match size_bits {
        0 => 0
        1 => 1
        2 => 2
        3 => 3
        _ => abort("invalid size_bits in LdrRegOffset: \{size_bits}")
      }
      let s_bit = if shift == 0 {
        0
      } else if shift == natural {
        1
      } else {
        abort(
          "invalid shift in LdrRegOffset: \{shift} for size_bits=\{size_bits}",
        )
      }
      let inst = ((size_bits & 0b11) << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b01 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        ((option & 7) << 13) |
        (s_bit << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdrWRegScaled(rt, rn, rm, shift) => {
      let s_bit = if shift == 2 { 1 } else { 0 }
      let inst = (0b10 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b01 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        (0b011 << 13) |
        (s_bit << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StrWRegScaled(rt, rn, rm, shift) => {
      let s_bit = if shift == 2 { 1 } else { 0 }
      let inst = (0b10 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b00 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        (0b011 << 13) |
        (s_bit << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdrbReg(rt, rn, rm) => {
      let inst = (0b00 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b01 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        (0b011 << 13) |
        (0 << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StrbReg(rt, rn, rm) => {
      let inst = (0b00 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b00 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        (0b011 << 13) |
        (0 << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdrhReg(rt, rn, rm) => {
      let inst = (0b01 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b01 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        (0b011 << 13) |
        (0 << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StrhReg(rt, rn, rm) => {
      let inst = (0b01 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b00 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        (0b011 << 13) |
        (0 << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StrImm(rt, rn, imm12) => {
      let scaled = (imm12 / 8) & 0xFFF
      let inst = (0b11 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b01 << 24) |
        (0b00 << 22) |
        (scaled << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StrRegScaled(rt, rn, rm, shift) => {
      let s_bit = if shift == 3 { 1 } else { 0 }
      let inst = (0b11 << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b00 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        (0b011 << 13) |
        (s_bit << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StrRegOffset(rt, rn, rm, option, size_bits, shift) => {
      let natural = match size_bits {
        0 => 0
        1 => 1
        2 => 2
        3 => 3
        _ => abort("invalid size_bits in StrRegOffset: \{size_bits}")
      }
      let s_bit = if shift == 0 {
        0
      } else if shift == natural {
        1
      } else {
        abort(
          "invalid shift in StrRegOffset: \{shift} for size_bits=\{size_bits}",
        )
      }
      let inst = ((size_bits & 0b11) << 30) |
        (0b111 << 27) |
        (0 << 26) |
        (0b00 << 24) |
        (0b00 << 22) |
        (1 << 21) |
        ((rm & 31) << 16) |
        ((option & 7) << 13) |
        (s_bit << 12) |
        (0b10 << 10) |
        ((rn & 31) << 5) |
        (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdrbImm(rt, rn, imm12) => {
      let imm = imm12 & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm & 63) << 2)
      let b2 = ((imm >> 6) & 63) | 64
      let b3 = 57
      (b0, b1, b2, b3)
    }
    LdrhImm(rt, rn, imm12) => {
      let scaled = (imm12 / 2) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = ((scaled >> 6) & 63) | 64
      let b3 = 121
      (b0, b1, b2, b3)
    }
    LdrWImm(rt, rn, imm12) => {
      let scaled = (imm12 / 4) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = ((scaled >> 6) & 63) | 64
      let b3 = 185
      (b0, b1, b2, b3)
    }
    StrbImm(rt, rn, imm12) => {
      let imm = imm12 & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm & 63) << 2)
      let b2 = (imm >> 6) & 63
      let b3 = 57
      (b0, b1, b2, b3)
    }
    StrhImm(rt, rn, imm12) => {
      let scaled = (imm12 / 2) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = (scaled >> 6) & 63
      let b3 = 121
      (b0, b1, b2, b3)
    }
    StrWImm(rt, rn, imm12) => {
      let scaled = (imm12 / 4) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = (scaled >> 6) & 63
      let b3 = 185
      (b0, b1, b2, b3)
    }
    LdrsbXImm(rt, rn, imm12) => {
      let imm = imm12 & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm & 63) << 2)
      let b2 = ((imm >> 6) & 63) | 128
      let b3 = 57
      (b0, b1, b2, b3)
    }
    LdrsbWImm(rt, rn, imm12) => {
      let imm = imm12 & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm & 63) << 2)
      let b2 = ((imm >> 6) & 63) | 192
      let b3 = 57
      (b0, b1, b2, b3)
    }
    LdrshXImm(rt, rn, imm12) => {
      let scaled = (imm12 / 2) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = ((scaled >> 6) & 63) | 128
      let b3 = 121
      (b0, b1, b2, b3)
    }
    LdrshWImm(rt, rn, imm12) => {
      let scaled = (imm12 / 2) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = ((scaled >> 6) & 63) | 192
      let b3 = 121
      (b0, b1, b2, b3)
    }
    LdrswImm(rt, rn, imm12) => {
      let scaled = (imm12 / 4) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = ((scaled >> 6) & 63) | 128
      let b3 = 185
      (b0, b1, b2, b3)
    }
    StpPre(rt1, rt2, rn, imm) => {
      let imm7 = (imm / 8) & 0x7F
      let inst = (0b10 << 30) |
        (0b101 << 27) |
        (0 << 26) |
        (0b011 << 23) |
        (0 << 22) |
        (imm7 << 15) |
        ((rt2 & 31) << 10) |
        ((rn & 31) << 5) |
        (rt1 & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdpPost(rt1, rt2, rn, imm) => {
      let imm7 = (imm / 8) & 0x7F
      let inst = (0b10 << 30) |
        (0b101 << 27) |
        (0 << 26) |
        (0b001 << 23) |
        (1 << 22) |
        (imm7 << 15) |
        ((rt2 & 31) << 10) |
        ((rn & 31) << 5) |
        (rt1 & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StpOffset(rt1, rt2, rn, offset) => {
      let imm7 = (offset / 8) & 0x7F
      let inst = (0b10 << 30) |
        (0b101 << 27) |
        (0 << 26) |
        (0b010 << 23) |
        (0 << 22) |
        (imm7 << 15) |
        ((rt2 & 31) << 10) |
        ((rn & 31) << 5) |
        (rt1 & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdpOffset(rt1, rt2, rn, offset) => {
      let imm7 = (offset / 8) & 0x7F
      let inst = (0b10 << 30) |
        (0b101 << 27) |
        (0 << 26) |
        (0b010 << 23) |
        (1 << 22) |
        (imm7 << 15) |
        ((rt2 & 31) << 10) |
        ((rn & 31) << 5) |
        (rt1 & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StpDOffset(rt1, rt2, rn, offset) => {
      let imm7 = (offset / 8) & 0x7F
      let inst = (0b01 << 30) |
        (0b101 << 27) |
        (1 << 26) |
        (0b010 << 23) |
        (0 << 22) |
        (imm7 << 15) |
        ((rt2 & 31) << 10) |
        ((rn & 31) << 5) |
        (rt1 & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdpDOffset(rt1, rt2, rn, offset) => {
      let imm7 = (offset / 8) & 0x7F
      let inst = (0b01 << 30) |
        (0b101 << 27) |
        (1 << 26) |
        (0b010 << 23) |
        (1 << 22) |
        (imm7 << 15) |
        ((rt2 & 31) << 10) |
        ((rn & 31) << 5) |
        (rt1 & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StrPre(rt, rn, simm9) => {
      // STR (immediate, pre-indexed): STR Xt, [Xn|SP, #simm9]!
      // Encoding: 11 | 111 | 0 | 00 | 00 | imm9 | 11 | Rn | Rt
      // = 0xF8000C00 | (imm9 << 12) | (Rn << 5) | Rt
      let imm9 = simm9 & 0x1FF
      let inst = 0xF8000C00 | (imm9 << 12) | ((rn & 31) << 5) | (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StpDPre(rt1, rt2, rn, imm) => {
      // STP (SIMD&FP, pre-indexed): STP Dt1, Dt2, [Xn|SP, #imm]!
      // opc=01 for 64-bit, V=1
      // Encoding: 01 | 101 | 1 | 011 | imm7 | Rt2 | Rn | Rt1
      // = 0x6D800000 | (imm7 << 15) | (Rt2 << 10) | (Rn << 5) | Rt1
      let imm7 = (imm / 8) & 0x7F
      let inst = 0x6D800000 |
        (imm7 << 15) |
        ((rt2 & 31) << 10) |
        ((rn & 31) << 5) |
        (rt1 & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    StrDPre(rt, rn, simm9) => {
      // STR (SIMD&FP, immediate, pre-indexed): STR Dt, [Xn|SP, #simm9]!
      // size=11 for 64-bit, V=1
      // Encoding: 11 | 111 | 1 | 00 | 00 | imm9 | 11 | Rn | Rt
      // = 0xFC000C00 | (imm9 << 12) | (Rn << 5) | Rt
      let imm9 = simm9 & 0x1FF
      let inst = 0xFC000C00 | (imm9 << 12) | ((rn & 31) << 5) | (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdrPost(rt, rn, simm9) => {
      // LDR (immediate, post-indexed): LDR Xt, [Xn|SP], #simm9
      // Encoding: 11 | 111 | 0 | 00 | 01 | imm9 | 01 | Rn | Rt
      // = 0xF8400400 | (imm9 << 12) | (Rn << 5) | Rt
      let imm9 = simm9 & 0x1FF
      let inst = 0xF8400400 | (imm9 << 12) | ((rn & 31) << 5) | (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdpDPost(rt1, rt2, rn, imm) => {
      // LDP (SIMD&FP, post-indexed): LDP Dt1, Dt2, [Xn|SP], #imm
      // opc=01 for 64-bit, V=1
      // Encoding: 01 | 101 | 1 | 001 | imm7 | Rt2 | Rn | Rt1
      // = 0x6CC00000 | (imm7 << 15) | (Rt2 << 10) | (Rn << 5) | Rt1
      let imm7 = (imm / 8) & 0x7F
      let inst = 0x6CC00000 |
        (imm7 << 15) |
        ((rt2 & 31) << 10) |
        ((rn & 31) << 5) |
        (rt1 & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    LdrDPost(rt, rn, simm9) => {
      // LDR (SIMD&FP, immediate, post-indexed): LDR Dt, [Xn|SP], #simm9
      // size=11 for 64-bit, V=1
      // Encoding: 11 | 111 | 1 | 00 | 01 | imm9 | 01 | Rn | Rt
      // = 0xFC400400 | (imm9 << 12) | (Rn << 5) | Rt
      let imm9 = simm9 & 0x1FF
      let inst = 0xFC400400 | (imm9 << 12) | ((rn & 31) << 5) | (rt & 31)
      (inst & 255, (inst >> 8) & 255, (inst >> 16) & 255, (inst >> 24) & 255)
    }
    SxtbX(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (7 << 2)
      let b2 = 0x40
      let b3 = 0x93
      (b0, b1, b2, b3)
    }
    SxthX(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (15 << 2)
      let b2 = 0x40
      let b3 = 0x93
      (b0, b1, b2, b3)
    }
    Sxtw(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (31 << 2)
      let b2 = 0x40
      let b3 = 0x93
      (b0, b1, b2, b3)
    }
    SxtbW(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (7 << 2)
      let b2 = 0x00
      let b3 = 0x13
      (b0, b1, b2, b3)
    }
    SxthW(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (15 << 2)
      let b2 = 0x00
      let b3 = 0x13
      (b0, b1, b2, b3)
    }
    UxtbX(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (7 << 2)
      let b2 = 0x00
      let b3 = 0x53
      (b0, b1, b2, b3)
    }
    UxthX(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (15 << 2)
      let b2 = 0x00
      let b3 = 0x53
      (b0, b1, b2, b3)
    }
    UxtbW(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (7 << 2)
      let b2 = 0x00
      let b3 = 0x53
      (b0, b1, b2, b3)
    }
    UxthW(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | (15 << 2)
      let b2 = 0x00
      let b3 = 0x53
      (b0, b1, b2, b3)
    }
    Fcvtzs(rd, rn, int64, double) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = if double { 0x78 } else { 0x38 }
      let b3 = if int64 { 0x9E } else { 0x1E }
      (b0, b1, b2, b3)
    }
    Fcvtzu(rd, rn, int64, double) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = if double { 0x79 } else { 0x39 }
      let b3 = if int64 { 0x9E } else { 0x1E }
      (b0, b1, b2, b3)
    }
    Scvtf(rd, rn, int64, double) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = if double { 0x62 } else { 0x22 }
      let b3 = if int64 { 0x9E } else { 0x1E }
      (b0, b1, b2, b3)
    }
    Ucvtf(rd, rn, int64, double) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = if double { 0x63 } else { 0x23 }
      let b3 = if int64 { 0x9E } else { 0x1E }
      (b0, b1, b2, b3)
    }
    FaddD(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x28
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FaddS(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x28
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FsubD(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x38
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FsubS(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x38
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FmulD(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x08
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FmulS(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x08
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FdivD(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x18
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FdivS(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x18
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FmaxD(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x48
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FmaxS(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x48
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FminD(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x58
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FminS(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x58
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FmaxnmD(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x68
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FmaxnmS(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x68
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FminnmD(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x78
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FminnmS(rd, rn, rm) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x78
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FsqrtD(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 192
      let b2 = 97
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FsqrtS(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 192
      let b2 = 0x21
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FabsD(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 192
      let b2 = 96
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FabsS(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 192
      let b2 = 0x20
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FnegD(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 64
      let b2 = 97
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FnegS(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 64
      let b2 = 0x21
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FrintpD(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 192
      let b2 = 100
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FrintpS(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 192
      let b2 = 0x24
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FrintmD(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 64
      let b2 = 101
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FrintmS(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 64
      let b2 = 0x25
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FrintzD(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 192
      let b2 = 101
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FrintzS(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 192
      let b2 = 0x25
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FrintnD(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 64
      let b2 = 100
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FrintnS(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 64
      let b2 = 0x24
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FmovD(rd, rm) => {
      let b0 = (rd & 31) | ((rm & 7) << 5)
      let b1 = ((rm >> 3) & 3) | 64
      let b2 = 96
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FmovS(rd, rm) => {
      let b0 = (rd & 31) | ((rm & 7) << 5)
      let b1 = ((rm >> 3) & 3) | 64
      let b2 = 0x20
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FmovDToX(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = 102
      let b3 = 158
      (b0, b1, b2, b3)
    }
    FmovSToW(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = 38
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FmovXToD(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = 103
      let b3 = 158
      (b0, b1, b2, b3)
    }
    FmovWToS(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = 39
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FcvtDS(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 192
      let b2 = 34
      let b3 = 30
      (b0, b1, b2, b3)
    }
    FcvtSD(rd, rn) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 64
      let b2 = 98
      let b3 = 30
      (b0, b1, b2, b3)
    }
    LdrSImm(rt, rn, imm12) => {
      let scaled = (imm12 / 4) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = ((scaled >> 6) & 63) | 64
      let b3 = 189
      (b0, b1, b2, b3)
    }
    StrSImm(rt, rn, imm12) => {
      let scaled = (imm12 / 4) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = (scaled >> 6) & 63
      let b3 = 189
      (b0, b1, b2, b3)
    }
    LdrDImm(rt, rn, imm12) => {
      let scaled = (imm12 / 8) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = ((scaled >> 6) & 63) | 64
      let b3 = 253
      (b0, b1, b2, b3)
    }
    StrDImm(rt, rn, imm12) => {
      let scaled = (imm12 / 8) & 0xFFF
      let b0 = (rt & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((scaled & 63) << 2)
      let b2 = (scaled >> 6) & 63
      let b3 = 253
      (b0, b1, b2, b3)
    }
    FcmpD(rn, rm) => {
      let b0 = (rn & 7) << 5
      let b1 = ((rn >> 3) & 3) | 0x20
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FcmpS(rn, rm) => {
      let b0 = (rn & 7) << 5
      let b1 = ((rn >> 3) & 3) | 0x20
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    CmpReg(rn, rm) => {
      let b0 = 31 | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 235
      (b0, b1, b2, b3)
    }
    CmpImm(rn, imm12) => {
      let imm = imm12 & 0xFFF
      let b0 = 31 | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm & 63) << 2)
      let b2 = (imm >> 6) & 63
      let b3 = 241
      (b0, b1, b2, b3)
    }
    CmpImmShifted12(rn, imm12) => {
      // CMP Xn, #imm12, lsl #12 (encoded as SUBS XZR, Xn, #imm12, LSL #12)
      let imm = imm12 & 0xFFF
      let inst = (0b1 << 31) |
        (1 << 30) |
        (1 << 29) | // S=1 (sets flags)
        (0b100010 << 23) |
        (1 << 22) | // sh=1: shift imm12 left by 12
        (imm << 10) |
        ((rn & 31) << 5) |
        31 // Rd = XZR
      (
        inst & 0xFF,
        (inst >> 8) & 0xFF,
        (inst >> 16) & 0xFF,
        (inst >> 24) & 0xFF,
      )
    }
    CmpReg32(rn, rm) => {
      let b0 = 31 | ((rn & 7) << 5)
      let b1 = (rn >> 3) & 3
      let b2 = rm & 31
      let b3 = 0x6B // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    CmpImm32(rn, imm12) => {
      let imm = imm12 & 0xFFF
      let b0 = 31 | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((imm & 63) << 2)
      let b2 = (imm >> 6) & 63
      let b3 = 0x71 // 32-bit: sf=0
      (b0, b1, b2, b3)
    }
    CmpImm32Shifted12(rn, imm12) => {
      // CMP Wn, #imm12, lsl #12 (encoded as SUBS WZR, Wn, #imm12, LSL #12)
      let imm = imm12 & 0xFFF
      let inst = (0b0 << 31) |
        (1 << 30) |
        (1 << 29) | // S=1 (sets flags)
        (0b100010 << 23) |
        (1 << 22) | // sh=1: shift imm12 left by 12
        (imm << 10) |
        ((rn & 31) << 5) |
        31 // Rd = WZR
      (
        inst & 0xFF,
        (inst >> 8) & 0xFF,
        (inst >> 16) & 0xFF,
        (inst >> 24) & 0xFF,
      )
    }
    AddsImmZr(rn, imm12, is_64) => {
      // ADDS XZR/WZR, Xn, #imm - add immediate with flags, result discarded
      // 64-bit: 0xB1000000 | (imm12 << 10) | (Rn << 5) | 31 (XZR)
      // 32-bit: 0x31000000 | (imm12 << 10) | (Rn << 5) | 31 (WZR)
      let imm = imm12 & 0xFFF
      let b0 = 31 | ((rn & 7) << 5) // Rd = 31 (XZR/WZR)
      let b1 = ((rn >> 3) & 3) | ((imm & 63) << 2)
      let b2 = (imm >> 6) & 63
      let b3 = if is_64 { 0xB1 } else { 0x31 }
      (b0, b1, b2, b3)
    }
    CCmpImm(rn, imm5, nzcv, cond, is_64) => {
      // CCMP Xn, #imm5, #nzcv, cond - conditional compare immediate
      // 64-bit: 0xFA400800 | (imm5 << 16) | (cond << 12) | (Rn << 5) | nzcv
      // 32-bit: 0x7A400800 | (imm5 << 16) | (cond << 12) | (Rn << 5) | nzcv
      let base = if is_64 { 0xFA400800 } else { 0x7A400800 }
      let inst = base |
        ((imm5 & 0x1F) << 16) |
        ((cond & 0xF) << 12) |
        ((rn & 0x1F) << 5) |
        (nzcv & 0xF)
      (
        inst & 0xFF,
        (inst >> 8) & 0xFF,
        (inst >> 16) & 0xFF,
        (inst >> 24) & 0xFF,
      )
    }
    Cset(rd, cond) => {
      let inv_cond = cond ^ 1
      let xe0 = 224
      let b0 = (rd & 31) | xe0
      let x07 = 7
      let x04 = 4
      let b1 = x07 | ((inv_cond & 15) << 4) | x04
      let b2 = 159
      let b3 = 154
      (b0, b1, b2, b3)
    }
    Csel(rd, rn, rm, cond) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | ((cond & 15) << 4)
      let b2 = (rm & 31) | 128
      let b3 = 154
      (b0, b1, b2, b3)
    }
    FcselD(rd, rn, rm, cond) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x0C | ((cond & 15) << 4)
      let b2 = 0x60 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    FcselS(rd, rn, rm, cond) => {
      let b0 = (rd & 31) | ((rn & 7) << 5)
      let b1 = ((rn >> 3) & 3) | 0x0C | ((cond & 15) << 4)
      let b2 = 0x20 | (rm & 31)
      let b3 = 0x1E
      (b0, b1, b2, b3)
    }
    B(_) => (0, 0, 0, 20)
    BCond(cond, _) => (cond & 15, 0, 0, 84)
    Cbz(rt, _) => (rt & 31, 0, 0, 180) // 0xB4 - 64-bit
    Cbnz(rt, _) => (rt & 31, 0, 0, 181) // 0xB5 - 64-bit
    Cbz32(rt, _) => (rt & 31, 0, 0, 52) // 0x34 - 32-bit
    Cbnz32(rt, _) => (rt & 31, 0, 0, 53) // 0x35 - 32-bit
    BCondOffset(cond, offset_bytes) => {
      let imm19 = offset_bytes / 4
      let inst = 0x54000000 | ((imm19 & 0x7FFFF) << 5) | (cond & 0xF)
      (
        inst & 0xFF,
        (inst >> 8) & 0xFF,
        (inst >> 16) & 0xFF,
        (inst >> 24) & 0xFF,
      )
    }
    CbnzOffset(rt, is_64, offset_bytes) => {
      // CBNZ Xt: 0xB5000000 | (imm19 << 5) | Rt
      // CBNZ Wt: 0x35000000 | (imm19 << 5) | Rt
      let imm19 = offset_bytes / 4
      let base = if is_64 { 0xB5000000 } else { 0x35000000 }
      let inst = base | ((imm19 & 0x7FFFF) << 5) | (rt & 0x1F)
      (
        inst & 0xFF,
        (inst >> 8) & 0xFF,
        (inst >> 16) & 0xFF,
        (inst >> 24) & 0xFF,
      )
    }
    Brk(imm16) => {
      let inst = 0xD4200000 | ((imm16 & 0xFFFF) << 5)
      (
        inst & 0xFF,
        (inst >> 8) & 0xFF,
        (inst >> 16) & 0xFF,
        (inst >> 24) & 0xFF,
      )
    }
    Ret(rn) => {
      let b0 = (rn & 7) << 5
      let b1 = (rn >> 3) & 3
      (b0, b1, 95, 214)
    }
    Br(rn) => {
      let b0 = (rn & 7) << 5
      let b1 = (rn >> 3) & 3
      (b0, b1, 31, 214)
    }
    Bl(_) => (0, 0, 0, 148)
    Blr(rn) => {
      let b0 = (rn & 7) << 5
      let b1 = (rn >> 3) & 3
      (b0, b1, 63, 214)
    }
    Adr(rd, offset) => {
      let immlo = offset & 3
      let immhi = (offset >> 2) & 0x7FFFF
      let b0 = (rd & 31) | ((immhi & 7) << 5)
      let b1 = (immhi >> 3) & 0xFF
      let b2 = (immhi >> 11) & 0xFF
      let b3 = 16 | (immlo << 5)
      (b0, b1, b2, b3)
    }
    DmbIsh => (0xBF, 0x3B, 0x03, 0xD5)
    Nop => (31, 32, 3, 213)
    AlignTo(_) => abort("AlignTo does not have single instruction bytes")
    Cnt8B(rd, rn) => {
      // CNT Vd.8B, Vn.8B: 0x0E205800 | (Rn << 5) | Rd
      let enc = 0x0E205800 | ((rn & 31) << 5) | (rd & 31)
      let b0 = enc & 0xFF
      let b1 = (enc >> 8) & 0xFF
      let b2 = (enc >> 16) & 0xFF
      let b3 = (enc >> 24) & 0xFF
      (b0, b1, b2, b3)
    }
    AddvB(rd, rn) => {
      // ADDV Bd, Vn.8B: 0x0E31B800 | (Rn << 5) | Rd
      let enc = 0x0E31B800 | ((rn & 31) << 5) | (rd & 31)
      let b0 = enc & 0xFF
      let b1 = (enc >> 8) & 0xFF
      let b2 = (enc >> 16) & 0xFF
      let b3 = (enc >> 24) & 0xFF
      (b0, b1, b2, b3)
    }
    // ============ NEON SIMD Instructions ============
    _ => self.instr_bytes_simd()
  }
}