// DO NOT EDIT. Generated by code.google.com/p/rsc/cmd/bundle // bundle -p main -x arm_ rsc.io/arm/armasm /* decode.go */ // Copyright 2014 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main import ( "bytes" "encoding/binary" "fmt" "io" "strings" ) // An instFormat describes the format of an instruction encoding. // An instruction with 32-bit value x matches the format if x&mask == value // and the condition matches. // The condition matches if x>>28 == 0xF && value>>28==0xF // or if x>>28 != 0xF and value>>28 == 0. // If x matches the format, then the rest of the fields describe how to interpret x. // The opBits describe bits that should be extracted from x and added to the opcode. // For example opBits = 0x1234 means that the value // (2 bits at offset 1) followed by (4 bits at offset 3) // should be added to op. // Finally the args describe how to decode the instruction arguments. // args is stored as a fixed-size array; if there are fewer than len(args) arguments, // args[i] == 0 marks the end of the argument list. type arm_instFormat struct { mask uint32 value uint32 priority int8 op arm_Op opBits uint64 args arm_instArgs } type arm_instArgs [4]arm_instArg var ( arm_errMode = fmt.Errorf("unsupported execution mode") arm_errShort = fmt.Errorf("truncated instruction") arm_errUnknown = fmt.Errorf("unknown instruction") ) var arm_decoderCover []bool // Decode decodes the leading bytes in src as a single instruction. func arm_Decode(src []byte, mode arm_Mode) (inst arm_Inst, err error) { if mode != arm_ModeARM { return arm_Inst{}, arm_errMode } if len(src) < 4 { return arm_Inst{}, arm_errShort } if arm_decoderCover == nil { arm_decoderCover = make([]bool, len(arm_instFormats)) } x := binary.LittleEndian.Uint32(src) // The instFormat table contains both conditional and unconditional instructions. // Considering only the top 4 bits, the conditional instructions use mask=0, value=0, // while the unconditional instructions use mask=f, value=f. // Prepare a version of x with the condition cleared to 0 in conditional instructions // and then assume mask=f during matching. const condMask = 0xf0000000 xNoCond := x if x&condMask != condMask { xNoCond &^= condMask } var priority int8 Search: for i := range arm_instFormats { f := &arm_instFormats[i] if xNoCond&(f.mask|condMask) != f.value || f.priority <= priority { continue } delta := uint32(0) deltaShift := uint(0) for opBits := f.opBits; opBits != 0; opBits >>= 16 { n := uint(opBits & 0xFF) off := uint((opBits >> 8) & 0xFF) delta |= (x >> off) & (1<> 8) & (1<<4 - 1)) case arm_arg_R_12: return arm_Reg((x >> 12) & (1<<4 - 1)) case arm_arg_R_16: return arm_Reg((x >> 16) & (1<<4 - 1)) case arm_arg_R_12_nzcv: r := arm_Reg((x >> 12) & (1<<4 - 1)) if r == arm_R15 { return arm_APSR_nzcv } return r case arm_arg_R_16_WB: mode := arm_AddrLDM if (x>>21)&1 != 0 { mode = arm_AddrLDM_WB } return arm_Mem{Base: arm_Reg((x >> 16) & (1<<4 - 1)), Mode: mode} case arm_arg_R_rotate: Rm := arm_Reg(x & (1<<4 - 1)) typ, count := arm_decodeShift(x) // ROR #0 here means ROR #0, but decodeShift rewrites to RRX #1. if typ == arm_RotateRightExt { return arm_Reg(Rm) } return arm_RegShift{Rm, typ, uint8(count)} case arm_arg_R_shift_R: Rm := arm_Reg(x & (1<<4 - 1)) Rs := arm_Reg((x >> 8) & (1<<4 - 1)) typ := arm_Shift((x >> 5) & (1<<2 - 1)) return arm_RegShiftReg{Rm, typ, Rs} case arm_arg_R_shift_imm: Rm := arm_Reg(x & (1<<4 - 1)) typ, count := arm_decodeShift(x) if typ == arm_ShiftLeft && count == 0 { return arm_Reg(Rm) } return arm_RegShift{Rm, typ, uint8(count)} case arm_arg_R1_0: return arm_Reg((x & (1<<4 - 1))) case arm_arg_R1_12: return arm_Reg(((x >> 12) & (1<<4 - 1))) case arm_arg_R2_0: return arm_Reg((x & (1<<4 - 1)) | 1) case arm_arg_R2_12: return arm_Reg(((x >> 12) & (1<<4 - 1)) | 1) case arm_arg_SP: return arm_SP case arm_arg_Sd_Dd: v := (x >> 12) & (1<<4 - 1) vx := (x >> 22) & 1 sz := (x >> 8) & 1 if sz != 0 { return arm_D0 + arm_Reg(vx<<4+v) } else { return arm_S0 + arm_Reg(v<<1+vx) } case arm_arg_Dd_Sd: return arm_decodeArg(arm_arg_Sd_Dd, x^(1<<8)) case arm_arg_Sd: v := (x >> 12) & (1<<4 - 1) vx := (x >> 22) & 1 return arm_S0 + arm_Reg(v<<1+vx) case arm_arg_Sm_Dm: v := (x >> 0) & (1<<4 - 1) vx := (x >> 5) & 1 sz := (x >> 8) & 1 if sz != 0 { return arm_D0 + arm_Reg(vx<<4+v) } else { return arm_S0 + arm_Reg(v<<1+vx) } case arm_arg_Sm: v := (x >> 0) & (1<<4 - 1) vx := (x >> 5) & 1 return arm_S0 + arm_Reg(v<<1+vx) case arm_arg_Dn_half: v := (x >> 16) & (1<<4 - 1) vx := (x >> 7) & 1 return arm_RegX{arm_D0 + arm_Reg(vx<<4+v), int((x >> 21) & 1)} case arm_arg_Sn_Dn: v := (x >> 16) & (1<<4 - 1) vx := (x >> 7) & 1 sz := (x >> 8) & 1 if sz != 0 { return arm_D0 + arm_Reg(vx<<4+v) } else { return arm_S0 + arm_Reg(v<<1+vx) } case arm_arg_Sn: v := (x >> 16) & (1<<4 - 1) vx := (x >> 7) & 1 return arm_S0 + arm_Reg(v<<1+vx) case arm_arg_const: v := x & (1<<8 - 1) rot := (x >> 8) & (1<<4 - 1) * 2 if rot > 0 && v&3 == 0 { // could rotate less return arm_ImmAlt{uint8(v), uint8(rot)} } if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v { // could wrap around to rot==0. return arm_ImmAlt{uint8(v), uint8(rot)} } return arm_Imm(v>>rot | v<<(32-rot)) case arm_arg_endian: return arm_Endian((x >> 9) & 1) case arm_arg_fbits: return arm_Imm((16 << ((x >> 7) & 1)) - ((x&(1<<4-1))<<1 | (x>>5)&1)) case arm_arg_fp_0: return arm_Imm(0) case arm_arg_imm24: return arm_Imm(x & (1<<24 - 1)) case arm_arg_imm5: return arm_Imm((x >> 7) & (1<<5 - 1)) case arm_arg_imm5_32: x = (x >> 7) & (1<<5 - 1) if x == 0 { x = 32 } return arm_Imm(x) case arm_arg_imm5_nz: x = (x >> 7) & (1<<5 - 1) if x == 0 { return nil } return arm_Imm(x) case arm_arg_imm_4at16_12at0: return arm_Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1)) case arm_arg_imm_12at8_4at0: return arm_Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1)) case arm_arg_imm_vfp: x = (x>>16)&(1<<4-1)<<4 | x&(1<<4-1) return arm_Imm(x) case arm_arg_label24: imm := (x & (1<<24 - 1)) << 2 return arm_PCRel(int32(imm<<6) >> 6) case arm_arg_label24H: h := (x >> 24) & 1 imm := (x&(1<<24-1))<<2 | h<<1 return arm_PCRel(int32(imm<<6) >> 6) case arm_arg_label_m_12: d := int32(x & (1<<12 - 1)) return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(-d)} case arm_arg_label_p_12: d := int32(x & (1<<12 - 1)) return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(d)} case arm_arg_label_pm_12: d := int32(x & (1<<12 - 1)) u := (x >> 23) & 1 if u == 0 { d = -d } return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(d)} case arm_arg_label_pm_4_4: d := int32((x>>8)&(1<<4-1)<<4 | x&(1<<4-1)) u := (x >> 23) & 1 if u == 0 { d = -d } return arm_PCRel(d) case arm_arg_lsb_width: lsb := (x >> 7) & (1<<5 - 1) msb := (x >> 16) & (1<<5 - 1) if msb < lsb || msb >= 32 { return nil } return arm_Imm(msb + 1 - lsb) case arm_arg_mem_R: Rn := arm_Reg((x >> 16) & (1<<4 - 1)) return arm_Mem{Base: Rn, Mode: arm_AddrOffset} case arm_arg_mem_R_pm_R_postindex: // Treat [],+/- like [,+/-{,}]{!} // by forcing shift bits to <<0 and P=0, W=0 (postindex=true). return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5|1<<24|1<<21)) case arm_arg_mem_R_pm_R_W: // Treat [,+/-]{!} like [,+/-{,}]{!} // by forcing shift bits to <<0. return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5)) case arm_arg_mem_R_pm_R_shift_imm_offset: // Treat [],+/-{,} like [,+/-{,}]{!} // by forcing P=1, W=0 (index=false, wback=false). return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^(1<<21)|1<<24) case arm_arg_mem_R_pm_R_shift_imm_postindex: // Treat [],+/-{,} like [,+/-{,}]{!} // by forcing P=0, W=0 (postindex=true). return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^(1<<24|1<<21)) case arm_arg_mem_R_pm_R_shift_imm_W: Rn := arm_Reg((x >> 16) & (1<<4 - 1)) Rm := arm_Reg(x & (1<<4 - 1)) typ, count := arm_decodeShift(x) u := (x >> 23) & 1 w := (x >> 21) & 1 p := (x >> 24) & 1 if p == 0 && w == 1 { return nil } sign := int8(+1) if u == 0 { sign = -1 } mode := arm_AddrMode(uint8(p<<1) | uint8(w^1)) return arm_Mem{Base: Rn, Mode: mode, Sign: sign, Index: Rm, Shift: typ, Count: count} case arm_arg_mem_R_pm_imm12_offset: // Treat [,#+/-] like [{,#+/-}]{!} // by forcing P=1, W=0 (index=false, wback=false). return arm_decodeArg(arm_arg_mem_R_pm_imm12_W, x&^(1<<21)|1<<24) case arm_arg_mem_R_pm_imm12_postindex: // Treat [],#+/- like [{,#+/-}]{!} // by forcing P=0, W=0 (postindex=true). return arm_decodeArg(arm_arg_mem_R_pm_imm12_W, x&^(1<<24|1<<21)) case arm_arg_mem_R_pm_imm12_W: Rn := arm_Reg((x >> 16) & (1<<4 - 1)) u := (x >> 23) & 1 w := (x >> 21) & 1 p := (x >> 24) & 1 if p == 0 && w == 1 { return nil } sign := int8(+1) if u == 0 { sign = -1 } imm := int16(x & (1<<12 - 1)) mode := arm_AddrMode(uint8(p<<1) | uint8(w^1)) return arm_Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm} case arm_arg_mem_R_pm_imm8_postindex: // Treat [],#+/- like [{,#+/-}]{!} // by forcing P=0, W=0 (postindex=true). return arm_decodeArg(arm_arg_mem_R_pm_imm8_W, x&^(1<<24|1<<21)) case arm_arg_mem_R_pm_imm8_W: Rn := arm_Reg((x >> 16) & (1<<4 - 1)) u := (x >> 23) & 1 w := (x >> 21) & 1 p := (x >> 24) & 1 if p == 0 && w == 1 { return nil } sign := int8(+1) if u == 0 { sign = -1 } imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1)) mode := arm_AddrMode(uint8(p<<1) | uint8(w^1)) return arm_Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm} case arm_arg_mem_R_pm_imm8at0_offset: Rn := arm_Reg((x >> 16) & (1<<4 - 1)) u := (x >> 23) & 1 sign := int8(+1) if u == 0 { sign = -1 } imm := int16(x&(1<<8-1)) << 2 return arm_Mem{Base: Rn, Mode: arm_AddrOffset, Offset: int16(sign) * imm} case arm_arg_option: return arm_Imm(x & (1<<4 - 1)) case arm_arg_registers: return arm_RegList(x & (1<<16 - 1)) case arm_arg_registers2: x &= 1<<16 - 1 n := 0 for i := 0; i < 16; i++ { if x>>uint(i)&1 != 0 { n++ } } if n < 2 { return nil } return arm_RegList(x) case arm_arg_registers1: Rt := (x >> 12) & (1<<4 - 1) return arm_RegList(1 << Rt) case arm_arg_satimm4: return arm_Imm((x >> 16) & (1<<4 - 1)) case arm_arg_satimm5: return arm_Imm((x >> 16) & (1<<5 - 1)) case arm_arg_satimm4m1: return arm_Imm((x>>16)&(1<<4-1) + 1) case arm_arg_satimm5m1: return arm_Imm((x>>16)&(1<<5-1) + 1) case arm_arg_widthm1: return arm_Imm((x>>16)&(1<<5-1) + 1) } } // decodeShift decodes the shift-by-immediate encoded in x. func arm_decodeShift(x uint32) (arm_Shift, uint8) { count := (x >> 7) & (1<<5 - 1) typ := arm_Shift((x >> 5) & (1<<2 - 1)) switch typ { case arm_ShiftRight, arm_ShiftRightSigned: if count == 0 { count = 32 } case arm_RotateRight: if count == 0 { typ = arm_RotateRightExt count = 1 } } return typ, uint8(count) } /* gnu.go */ // Copyright 2014 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. var arm_saveDot = strings.NewReplacer( ".F16", "_dot_F16", ".F32", "_dot_F32", ".F64", "_dot_F64", ".S32", "_dot_S32", ".U32", "_dot_U32", ".FXS", "_dot_S", ".FXU", "_dot_U", ".32", "_dot_32", ) // GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils. // This form typically matches the syntax defined in the ARM Reference Manual. func arm_GNUSyntax(inst arm_Inst) string { var buf bytes.Buffer op := inst.Op.String() op = arm_saveDot.Replace(op) op = strings.Replace(op, ".", "", -1) op = strings.Replace(op, "_dot_", ".", -1) op = strings.ToLower(op) buf.WriteString(op) sep := " " for i, arg := range inst.Args { if arg == nil { break } text := arm_gnuArg(&inst, i, arg) if text == "" { continue } buf.WriteString(sep) sep = ", " buf.WriteString(text) } return buf.String() } func arm_gnuArg(inst *arm_Inst, argIndex int, arg arm_Arg) string { switch inst.Op &^ 15 { case arm_LDRD_EQ, arm_LDREXD_EQ, arm_STRD_EQ: if argIndex == 1 { // second argument in consecutive pair not printed return "" } case arm_STREXD_EQ: if argIndex == 2 { // second argument in consecutive pair not printed return "" } } switch arg := arg.(type) { case arm_Imm: switch inst.Op &^ 15 { case arm_BKPT_EQ: return fmt.Sprintf("%#04x", uint32(arg)) case arm_SVC_EQ: return fmt.Sprintf("%#08x", uint32(arg)) } return fmt.Sprintf("#%d", int32(arg)) case arm_ImmAlt: return fmt.Sprintf("#%d, %d", arg.Val, arg.Rot) case arm_Mem: R := arm_gnuArg(inst, -1, arg.Base) X := "" if arg.Sign != 0 { X = "" if arg.Sign < 0 { X = "-" } X += arm_gnuArg(inst, -1, arg.Index) if arg.Shift == arm_ShiftLeft && arg.Count == 0 { // nothing } else if arg.Shift == arm_RotateRightExt { X += ", rrx" } else { X += fmt.Sprintf(", %s #%d", strings.ToLower(arg.Shift.String()), arg.Count) } } else { X = fmt.Sprintf("#%d", arg.Offset) } switch arg.Mode { case arm_AddrOffset: if X == "#0" { return fmt.Sprintf("[%s]", R) } return fmt.Sprintf("[%s, %s]", R, X) case arm_AddrPreIndex: return fmt.Sprintf("[%s, %s]!", R, X) case arm_AddrPostIndex: return fmt.Sprintf("[%s], %s", R, X) case arm_AddrLDM: if X == "#0" { return R } case arm_AddrLDM_WB: if X == "#0" { return R + "!" } } return fmt.Sprintf("[%s Mode(%d) %s]", R, int(arg.Mode), X) case arm_PCRel: return fmt.Sprintf(".%+#x", int32(arg)+4) case arm_Reg: switch inst.Op &^ 15 { case arm_LDREX_EQ: if argIndex == 0 { return fmt.Sprintf("r%d", int32(arg)) } } switch arg { case arm_R10: return "sl" case arm_R11: return "fp" case arm_R12: return "ip" } case arm_RegList: var buf bytes.Buffer fmt.Fprintf(&buf, "{") sep := "" for i := 0; i < 16; i++ { if arg&(1<= arm_Op(len(arm_opstr)) || arm_opstr[op] == "" { return fmt.Sprintf("Op(%d)", int(op)) } return arm_opstr[op] } // An Inst is a single instruction. type arm_Inst struct { Op arm_Op // Opcode mnemonic Enc uint32 // Raw encoding bits. Len int // Length of encoding in bytes. Args arm_Args // Instruction arguments, in ARM manual order. } func (i arm_Inst) String() string { var buf bytes.Buffer buf.WriteString(i.Op.String()) for j, arg := range i.Args { if arg == nil { break } if j == 0 { buf.WriteString(" ") } else { buf.WriteString(", ") } buf.WriteString(arg.String()) } return buf.String() } // An Args holds the instruction arguments. // If an instruction has fewer than 4 arguments, // the final elements in the array are nil. type arm_Args [4]arm_Arg // An Arg is a single instruction argument, one of these types: // Endian, Imm, Mem, PCRel, Reg, RegList, RegShift, RegShiftReg. type arm_Arg interface { IsArg() String() string } type arm_Float32Imm float32 func (arm_Float32Imm) IsArg() {} func (f arm_Float32Imm) String() string { return fmt.Sprintf("#%v", float32(f)) } type arm_Float64Imm float32 func (arm_Float64Imm) IsArg() {} func (f arm_Float64Imm) String() string { return fmt.Sprintf("#%v", float64(f)) } // An Imm is an integer constant. type arm_Imm uint32 func (arm_Imm) IsArg() {} func (i arm_Imm) String() string { return fmt.Sprintf("#%#x", uint32(i)) } // A ImmAlt is an alternate encoding of an integer constant. type arm_ImmAlt struct { Val uint8 Rot uint8 } func (arm_ImmAlt) IsArg() {} func (i arm_ImmAlt) Imm() arm_Imm { v := uint32(i.Val) r := uint(i.Rot) return arm_Imm(v>>r | v<<(32-r)) } func (i arm_ImmAlt) String() string { return fmt.Sprintf("#%#x, %d", i.Val, i.Rot) } // A Label is a text (code) address. type arm_Label uint32 func (arm_Label) IsArg() {} func (i arm_Label) String() string { return fmt.Sprintf("%#x", uint32(i)) } // A Reg is a single register. // The zero value denotes R0, not the absence of a register. type arm_Reg uint8 const ( arm_R0 arm_Reg = iota arm_R1 arm_R2 arm_R3 arm_R4 arm_R5 arm_R6 arm_R7 arm_R8 arm_R9 arm_R10 arm_R11 arm_R12 arm_R13 arm_R14 arm_R15 arm_S0 arm_S1 arm_S2 arm_S3 arm_S4 arm_S5 arm_S6 arm_S7 arm_S8 arm_S9 arm_S10 arm_S11 arm_S12 arm_S13 arm_S14 arm_S15 arm_S16 arm_S17 arm_S18 arm_S19 arm_S20 arm_S21 arm_S22 arm_S23 arm_S24 arm_S25 arm_S26 arm_S27 arm_S28 arm_S29 arm_S30 arm_S31 arm_D0 arm_D1 arm_D2 arm_D3 arm_D4 arm_D5 arm_D6 arm_D7 arm_D8 arm_D9 arm_D10 arm_D11 arm_D12 arm_D13 arm_D14 arm_D15 arm_D16 arm_D17 arm_D18 arm_D19 arm_D20 arm_D21 arm_D22 arm_D23 arm_D24 arm_D25 arm_D26 arm_D27 arm_D28 arm_D29 arm_D30 arm_D31 arm_APSR arm_APSR_nzcv arm_FPSCR arm_SP = arm_R13 arm_LR = arm_R14 arm_PC = arm_R15 ) func (arm_Reg) IsArg() {} func (r arm_Reg) String() string { switch r { case arm_APSR: return "APSR" case arm_APSR_nzcv: return "APSR_nzcv" case arm_FPSCR: return "FPSCR" case arm_SP: return "SP" case arm_PC: return "PC" case arm_LR: return "LR" } if arm_R0 <= r && r <= arm_R15 { return fmt.Sprintf("R%d", int(r-arm_R0)) } if arm_S0 <= r && r <= arm_S31 { return fmt.Sprintf("S%d", int(r-arm_S0)) } if arm_D0 <= r && r <= arm_D31 { return fmt.Sprintf("D%d", int(r-arm_D0)) } return fmt.Sprintf("Reg(%d)", int(r)) } // A RegX represents a fraction of a multi-value register. // The Index field specifies the index number, // but the size of the fraction is not specified. // It must be inferred from the instruction and the register type. // For example, in a VMOV instruction, RegX{D5, 1} represents // the top 32 bits of the 64-bit D5 register. type arm_RegX struct { Reg arm_Reg Index int } func (arm_RegX) IsArg() {} func (r arm_RegX) String() string { return fmt.Sprintf("%s[%d]", r.Reg, r.Index) } // A RegList is a register list. // Bits at indexes x = 0 through 15 indicate whether the corresponding Rx register is in the list. type arm_RegList uint16 func (arm_RegList) IsArg() {} func (r arm_RegList) String() string { var buf bytes.Buffer fmt.Fprintf(&buf, "{") sep := "" for i := 0; i < 16; i++ { if r&(1< is a lie; the assembler uses @> 0 // instead of @x> 1, but i wanted to be clear that it // was a different operation (rotate right extended, not rotate right). var arm_plan9Shift = []string{"<<", ">>", "->", "@>", "@x>"} func arm_plan9Arg(inst *arm_Inst, pc uint64, symname func(uint64) (string, uint64), arg arm_Arg) string { switch a := arg.(type) { case arm_Endian: case arm_Imm: return fmt.Sprintf("$%d", int(a)) case arm_Mem: case arm_PCRel: addr := uint32(pc) + 8 + uint32(a) if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base { return fmt.Sprintf("%s(SB)", s) } return fmt.Sprintf("%#x", addr) case arm_Reg: if a < 16 { return fmt.Sprintf("R%d", int(a)) } case arm_RegList: var buf bytes.Buffer start := -2 end := -2 fmt.Fprintf(&buf, "[") flush := func() { if start >= 0 { if buf.Len() > 1 { fmt.Fprintf(&buf, ",") } if start == end { fmt.Fprintf(&buf, "R%d", start) } else { fmt.Fprintf(&buf, "R%d-R%d", start, end) } } } for i := 0; i < 16; i++ { if a&(1< ,,# cond:4|0|0|1|0|1|0|1|S|Rn:4|Rd:4|imm12:12 {0x0fe00090, 0x00a00010, 4, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // ADC{S} ,,, cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4 {0x0fe00010, 0x00a00000, 2, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // ADC{S} ,,{,} cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4 {0x0fe00000, 0x02800000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // ADD{S} ,,# cond:4|0|0|1|0|1|0|0|S|Rn:4|Rd:4|imm12:12 {0x0fe00090, 0x00800010, 4, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // ADD{S} ,,, cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4 {0x0fe00010, 0x00800000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // ADD{S} ,,{,} cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4 {0x0fef0000, 0x028d0000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_const}}, // ADD{S} ,SP,# cond:4|0|0|1|0|1|0|0|S|1|1|0|1|Rd:4|imm12:12 {0x0fef0010, 0x008d0000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_R_shift_imm}}, // ADD{S} ,SP,{,} cond:4|0|0|0|0|1|0|0|S|1|1|0|1|Rd:4|imm5:5|type:2|0|Rm:4 {0x0fe00000, 0x02000000, 2, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // AND{S} ,,# cond:4|0|0|1|0|0|0|0|S|Rn:4|Rd:4|imm12:12 {0x0fe00090, 0x00000010, 4, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // AND{S} ,,, cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4 {0x0fe00010, 0x00000000, 2, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // AND{S} ,,{,} cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4 {0x0fef0070, 0x01a00040, 4, arm_ASR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5_32}}, // ASR{S} ,,# cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|1|0|0|Rm:4 {0x0fef00f0, 0x01a00050, 4, arm_ASR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}}, // ASR{S} ,, cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|1|0|1|Rn:4 {0x0f000000, 0x0a000000, 4, arm_B_EQ, 0x1c04, arm_instArgs{arm_arg_label24}}, // B cond:4|1|0|1|0|imm24:24 {0x0fe0007f, 0x07c0001f, 4, arm_BFC_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_imm5, arm_arg_lsb_width}}, // BFC ,#,# cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|1|1|1|1 {0x0fe00070, 0x07c00010, 2, arm_BFI_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5, arm_arg_lsb_width}}, // BFI ,,#,# cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|Rn:4 {0x0fe00000, 0x03c00000, 2, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}}, // BIC{S} ,,# cond:4|0|0|1|1|1|1|0|S|Rn:4|Rd:4|imm12:12 {0x0fe00090, 0x01c00010, 4, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}}, // BIC{S} ,,, cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4 {0x0fe00010, 0x01c00000, 2, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}}, // BIC{S} ,,{,} cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4 {0x0ff000f0, 0x01200070, 4, arm_BKPT_EQ, 0x1c04, arm_instArgs{arm_arg_imm_12at8_4at0}}, // BKPT # cond:4|0|0|0|1|0|0|1|0|imm12:12|0|1|1|1|imm4:4 {0x0f000000, 0x0b000000, 4, arm_BL_EQ, 0x1c04, arm_instArgs{arm_arg_label24}}, // BL cond:4|1|0|1|1|imm24:24 {0xfe000000, 0xfa000000, 4, arm_BLX, 0x0, arm_instArgs{arm_arg_label24H}}, // BLX 1|1|1|1|1|0|1|H|imm24:24 {0x0ffffff0, 0x012fff30, 4, arm_BLX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BLX cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4 {0x0ff000f0, 0x012fff30, 3, arm_BLX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BLX cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4 {0x0ffffff0, 0x012fff10, 4, arm_BX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BX cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4 {0x0ff000f0, 0x012fff10, 3, arm_BX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BX cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4 {0x0ffffff0, 0x012fff20, 4, arm_BXJ_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BXJ cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4 {0x0ff000f0, 0x012fff20, 3, arm_BXJ_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}}, // BXJ cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4 {0xffffffff, 0xf57ff01f, 4, arm_CLREX, 0x0, arm_instArgs{}}, // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1) {0xfff000f0, 0xf57ff01f, 3, arm_CLREX, 0x0, arm_instArgs{}}, // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1) {0x0fff0ff0, 0x016f0f10, 4, arm_CLZ_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // CLZ , cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4 {0x0ff000f0, 0x016f0f10, 3, arm_CLZ_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}}, // CLZ , cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4 {0x0ff0f000, 0x03700000, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMN ,# cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12 {0x0ff00000, 0x03700000, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMN ,# cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12 {0x0ff0f090, 0x01700010, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMN ,, cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4 {0x0ff00090, 0x01700010, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMN ,, cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4 {0x0ff0f010, 0x01700000, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMN ,{,} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4 {0x0ff00010, 0x01700000, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMN ,{,} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4 {0x0ff0f000, 0x03500000, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMP ,# cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12 {0x0ff00000, 0x03500000, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}}, // CMP ,# cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12 {0x0ff0f090, 0x01500010, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMP ,, cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4 {0x0ff00090, 0x01500010, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}}, // CMP ,, cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4 {0x0ff0f010, 0x01500000, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMP ,{,} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4 {0x0ff00010, 0x01500000, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}}, // CMP ,{,} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4 {0x0ffffff0, 0x0320f0f0, 4, arm_DBG_EQ, 0x1c04, arm_instArgs{arm_arg_option}}, // DBG #