Last active
June 28, 2018 18:43
-
-
Save Amanieu/6bfc82be37325d22466eeadcd578d54e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use core::hint; | |
pub mod encode { | |
#[inline] | |
pub fn shift_immed(ty: u32, imm5: u32, Rm: u32, Rd: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x0 << 29; | |
out |= (ty as u32 & 0x3) << 27; | |
out |= (imm5 as u32 & 0x1f) << 22; | |
out |= (Rm as u32 & 0x7) << 19; | |
out |= (Rd as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn ADD_SUB_reg(op: bool, Rm: u32, Rn: u32, Rd: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x6 << 26; | |
out |= (op as u32 & 0x1) << 25; | |
out |= (Rm as u32 & 0x7) << 22; | |
out |= (Rn as u32 & 0x7) << 19; | |
out |= (Rd as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn ADD_SUB_immed3(op: bool, imm3: u32, Rn: u32, Rd: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x7 << 26; | |
out |= (op as u32 & 0x1) << 25; | |
out |= (imm3 as u32 & 0x7) << 22; | |
out |= (Rn as u32 & 0x7) << 19; | |
out |= (Rd as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn MOV_immed(Rd: u32, imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x4 << 27; | |
out |= (Rd as u32 & 0x7) << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn CMP_immed(Rn: u32, imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x5 << 27; | |
out |= (Rn as u32 & 0x7) << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn ADD_SUB_immed8(op: bool, Rdn: u32, imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x3 << 28; | |
out |= (op as u32 & 0x1) << 27; | |
out |= (Rdn as u32 & 0x7) << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn data_proc(op: u32, Rm: u32, Rdn: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x10 << 26; | |
out |= (op as u32 & 0xf) << 22; | |
out |= (Rm as u32 & 0x7) << 19; | |
out |= (Rdn as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn ADD_high(DN: bool, Rm: u32, Rdn: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x44 << 24; | |
out |= (DN as u32 & 0x1) << 23; | |
out |= (Rm as u32 & 0xf) << 19; | |
out |= (Rdn as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn CMP_high(N: bool, Rm: u32, Rn: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x45 << 24; | |
out |= (N as u32 & 0x1) << 23; | |
out |= (Rm as u32 & 0xf) << 19; | |
out |= (Rn as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn MOV_high(D: bool, Rm: u32, Rd: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x46 << 24; | |
out |= (D as u32 & 0x1) << 23; | |
out |= (Rm as u32 & 0xf) << 19; | |
out |= (Rd as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn BX_BLX_reg(L: bool, Rm: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x47 << 24; | |
out |= (L as u32 & 0x1) << 23; | |
out |= (Rm as u32 & 0xf) << 19; | |
out |= 0x0 << 16; | |
out | |
} | |
#[inline] | |
pub fn LDR_lit(Rt: u32, imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x9 << 27; | |
out |= (Rt as u32 & 0x7) << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn LDR_STR_reg(op: u32, Rm: u32, Rn: u32, Rt: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x5 << 28; | |
out |= (op as u32 & 0x7) << 25; | |
out |= (Rm as u32 & 0x7) << 22; | |
out |= (Rn as u32 & 0x7) << 19; | |
out |= (Rt as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn LDR_STR_immed(L: bool, imm5: u32, Rn: u32, Rt: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x6 << 28; | |
out |= (L as u32 & 0x1) << 27; | |
out |= (imm5 as u32 & 0x1f) << 22; | |
out |= (Rn as u32 & 0x7) << 19; | |
out |= (Rt as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn LDRB_STRB_immed(L: bool, imm5: u32, Rn: u32, Rt: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x7 << 28; | |
out |= (L as u32 & 0x1) << 27; | |
out |= (imm5 as u32 & 0x1f) << 22; | |
out |= (Rn as u32 & 0x7) << 19; | |
out |= (Rt as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn LDRH_STRH_immed(L: bool, imm5: u32, Rn: u32, Rt: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x8 << 28; | |
out |= (L as u32 & 0x1) << 27; | |
out |= (imm5 as u32 & 0x1f) << 22; | |
out |= (Rn as u32 & 0x7) << 19; | |
out |= (Rt as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn LDR_STR_sp_immed(L: bool, Rt: u32, imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x9 << 28; | |
out |= (L as u32 & 0x1) << 27; | |
out |= (Rt as u32 & 0x7) << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn ADR(Rd: u32, imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x14 << 27; | |
out |= (Rd as u32 & 0x7) << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn ADR_sp(Rd: u32, imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x15 << 27; | |
out |= (Rd as u32 & 0x7) << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn ADD_SUB_sp(op: bool, imm7: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xb0 << 24; | |
out |= (op as u32 & 0x1) << 23; | |
out |= (imm7 as u32 & 0x7f) << 16; | |
out | |
} | |
#[inline] | |
pub fn CBZ_CBNZ(op: bool, i: bool, imm5: u32, Rn: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xb << 28; | |
out |= (op as u32 & 0x1) << 27; | |
out |= 0x0 << 26; | |
out |= (i as u32 & 0x1) << 25; | |
out |= 0x1 << 24; | |
out |= (imm5 as u32 & 0x1f) << 19; | |
out |= (Rn as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn SXT_UXT(op: u32, Rm: u32, Rd: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xb2 << 24; | |
out |= (op as u32 & 0x3) << 22; | |
out |= (Rm as u32 & 0x7) << 19; | |
out |= (Rd as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn PUSH_POP(L: bool, MP: bool, reg_list: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xb << 28; | |
out |= (L as u32 & 0x1) << 27; | |
out |= 0x2 << 25; | |
out |= (MP as u32 & 0x1) << 24; | |
out |= (reg_list as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn SETEND(E: bool) -> u32 { | |
let mut out = 0; | |
out |= 0xb65 << 20; | |
out |= (E as u32 & 0x1) << 19; | |
out |= 0x0 << 16; | |
out | |
} | |
#[inline] | |
pub fn SETPAN(imm: bool) -> u32 { | |
let mut out = 0; | |
out |= 0xb61 << 20; | |
out |= (imm as u32 & 0x1) << 19; | |
out |= 0x0 << 16; | |
out | |
} | |
#[inline] | |
pub fn CPS(im: bool, A: bool, I: bool, F: bool) -> u32 { | |
let mut out = 0; | |
out |= 0x5b3 << 21; | |
out |= (im as u32 & 0x1) << 20; | |
out |= 0x0 << 19; | |
out |= (A as u32 & 0x1) << 18; | |
out |= (I as u32 & 0x1) << 17; | |
out |= (F as u32 & 0x1) << 16; | |
out | |
} | |
#[inline] | |
pub fn REV(op: u32, Rm: u32, Rd: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xba << 24; | |
out |= (op as u32 & 0x3) << 22; | |
out |= (Rm as u32 & 0x7) << 19; | |
out |= (Rd as u32 & 0x7) << 16; | |
out | |
} | |
#[inline] | |
pub fn HLT(imm6: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x2ea << 22; | |
out |= (imm6 as u32 & 0x3f) << 16; | |
out | |
} | |
#[inline] | |
pub fn BKPT(imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xbe << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn IT(firstcond: u32, mask: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xbf << 24; | |
out |= (firstcond as u32 & 0xf) << 20; | |
out |= (mask as u32 & 0xf) << 16; | |
out | |
} | |
#[inline] | |
pub fn HINT(op: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xbf << 24; | |
out |= (op as u32 & 0xf) << 20; | |
out |= 0x0 << 16; | |
out | |
} | |
#[inline] | |
pub fn LDM_STM(L: bool, Rn: u32, reg_list: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xc << 28; | |
out |= (L as u32 & 0x1) << 27; | |
out |= (Rn as u32 & 0x7) << 24; | |
out |= (reg_list as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn B_cond(cond: u32, imm8: i32) -> u32 { | |
let mut out = 0; | |
out |= 0xd << 28; | |
out |= (cond as u32 & 0xf) << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn UDF(imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xde << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn SVC(imm8: u32) -> u32 { | |
let mut out = 0; | |
out |= 0xdf << 24; | |
out |= (imm8 as u32 & 0xff) << 16; | |
out | |
} | |
#[inline] | |
pub fn B(imm11: i32) -> u32 { | |
let mut out = 0; | |
out |= 0x1c << 27; | |
out |= (imm11 as u32 & 0x7ff) << 16; | |
out | |
} | |
#[inline] | |
pub fn thumb32_prefix(x: u32, y: u32) -> u32 { | |
let mut out = 0; | |
out |= 0x7 << 29; | |
out |= (x as u32 & 0x3) << 27; | |
out |= (y as u32 & 0x7ff) << 16; | |
out | |
} | |
} | |
pub mod fields { | |
#[derive(Copy, Clone)] | |
pub struct shift_immed(pub u32); | |
impl shift_immed { | |
#[inline] | |
pub fn ty(&self) -> u32 { (self.0 >> 27) & 0x3 } | |
#[inline] | |
pub fn imm5(&self) -> u32 { (self.0 >> 22) & 0x1f } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rd(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct ADD_SUB_reg(pub u32); | |
impl ADD_SUB_reg { | |
#[inline] | |
pub fn op(&self) -> bool { (self.0 >> 25) & 0x1 != 0 } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 22) & 0x7 } | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rd(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct ADD_SUB_immed3(pub u32); | |
impl ADD_SUB_immed3 { | |
#[inline] | |
pub fn op(&self) -> bool { (self.0 >> 25) & 0x1 != 0 } | |
#[inline] | |
pub fn imm3(&self) -> u32 { (self.0 >> 22) & 0x7 } | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rd(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct MOV_immed(pub u32); | |
impl MOV_immed { | |
#[inline] | |
pub fn Rd(&self) -> u32 { (self.0 >> 24) & 0x7 } | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct CMP_immed(pub u32); | |
impl CMP_immed { | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 24) & 0x7 } | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct ADD_SUB_immed8(pub u32); | |
impl ADD_SUB_immed8 { | |
#[inline] | |
pub fn op(&self) -> bool { (self.0 >> 27) & 0x1 != 0 } | |
#[inline] | |
pub fn Rdn(&self) -> u32 { (self.0 >> 24) & 0x7 } | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct data_proc(pub u32); | |
impl data_proc { | |
#[inline] | |
pub fn op(&self) -> u32 { (self.0 >> 22) & 0xf } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rdn(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct ADD_high(pub u32); | |
impl ADD_high { | |
#[inline] | |
pub fn DN(&self) -> bool { (self.0 >> 23) & 0x1 != 0 } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 19) & 0xf } | |
#[inline] | |
pub fn Rdn(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct CMP_high(pub u32); | |
impl CMP_high { | |
#[inline] | |
pub fn N(&self) -> bool { (self.0 >> 23) & 0x1 != 0 } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 19) & 0xf } | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct MOV_high(pub u32); | |
impl MOV_high { | |
#[inline] | |
pub fn D(&self) -> bool { (self.0 >> 23) & 0x1 != 0 } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 19) & 0xf } | |
#[inline] | |
pub fn Rd(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct BX_BLX_reg(pub u32); | |
impl BX_BLX_reg { | |
#[inline] | |
pub fn L(&self) -> bool { (self.0 >> 23) & 0x1 != 0 } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 19) & 0xf } | |
} | |
#[derive(Copy, Clone)] | |
pub struct LDR_lit(pub u32); | |
impl LDR_lit { | |
#[inline] | |
pub fn Rt(&self) -> u32 { (self.0 >> 24) & 0x7 } | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct LDR_STR_reg(pub u32); | |
impl LDR_STR_reg { | |
#[inline] | |
pub fn op(&self) -> u32 { (self.0 >> 25) & 0x7 } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 22) & 0x7 } | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rt(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct LDR_STR_immed(pub u32); | |
impl LDR_STR_immed { | |
#[inline] | |
pub fn L(&self) -> bool { (self.0 >> 27) & 0x1 != 0 } | |
#[inline] | |
pub fn imm5(&self) -> u32 { (self.0 >> 22) & 0x1f } | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rt(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct LDRB_STRB_immed(pub u32); | |
impl LDRB_STRB_immed { | |
#[inline] | |
pub fn L(&self) -> bool { (self.0 >> 27) & 0x1 != 0 } | |
#[inline] | |
pub fn imm5(&self) -> u32 { (self.0 >> 22) & 0x1f } | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rt(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct LDRH_STRH_immed(pub u32); | |
impl LDRH_STRH_immed { | |
#[inline] | |
pub fn L(&self) -> bool { (self.0 >> 27) & 0x1 != 0 } | |
#[inline] | |
pub fn imm5(&self) -> u32 { (self.0 >> 22) & 0x1f } | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rt(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct LDR_STR_sp_immed(pub u32); | |
impl LDR_STR_sp_immed { | |
#[inline] | |
pub fn L(&self) -> bool { (self.0 >> 27) & 0x1 != 0 } | |
#[inline] | |
pub fn Rt(&self) -> u32 { (self.0 >> 24) & 0x7 } | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct ADR(pub u32); | |
impl ADR { | |
#[inline] | |
pub fn Rd(&self) -> u32 { (self.0 >> 24) & 0x7 } | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct ADR_sp(pub u32); | |
impl ADR_sp { | |
#[inline] | |
pub fn Rd(&self) -> u32 { (self.0 >> 24) & 0x7 } | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct ADD_SUB_sp(pub u32); | |
impl ADD_SUB_sp { | |
#[inline] | |
pub fn op(&self) -> bool { (self.0 >> 23) & 0x1 != 0 } | |
#[inline] | |
pub fn imm7(&self) -> u32 { (self.0 >> 16) & 0x7f } | |
} | |
#[derive(Copy, Clone)] | |
pub struct CBZ_CBNZ(pub u32); | |
impl CBZ_CBNZ { | |
#[inline] | |
pub fn op(&self) -> bool { (self.0 >> 27) & 0x1 != 0 } | |
#[inline] | |
pub fn i(&self) -> bool { (self.0 >> 25) & 0x1 != 0 } | |
#[inline] | |
pub fn imm5(&self) -> u32 { (self.0 >> 19) & 0x1f } | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct SXT_UXT(pub u32); | |
impl SXT_UXT { | |
#[inline] | |
pub fn op(&self) -> u32 { (self.0 >> 22) & 0x3 } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rd(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct PUSH_POP(pub u32); | |
impl PUSH_POP { | |
#[inline] | |
pub fn L(&self) -> bool { (self.0 >> 27) & 0x1 != 0 } | |
#[inline] | |
pub fn MP(&self) -> bool { (self.0 >> 24) & 0x1 != 0 } | |
#[inline] | |
pub fn reg_list(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct SETEND(pub u32); | |
impl SETEND { | |
#[inline] | |
pub fn E(&self) -> bool { (self.0 >> 19) & 0x1 != 0 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct SETPAN(pub u32); | |
impl SETPAN { | |
#[inline] | |
pub fn imm(&self) -> bool { (self.0 >> 19) & 0x1 != 0 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct CPS(pub u32); | |
impl CPS { | |
#[inline] | |
pub fn im(&self) -> bool { (self.0 >> 20) & 0x1 != 0 } | |
#[inline] | |
pub fn A(&self) -> bool { (self.0 >> 18) & 0x1 != 0 } | |
#[inline] | |
pub fn I(&self) -> bool { (self.0 >> 17) & 0x1 != 0 } | |
#[inline] | |
pub fn F(&self) -> bool { (self.0 >> 16) & 0x1 != 0 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct REV(pub u32); | |
impl REV { | |
#[inline] | |
pub fn op(&self) -> u32 { (self.0 >> 22) & 0x3 } | |
#[inline] | |
pub fn Rm(&self) -> u32 { (self.0 >> 19) & 0x7 } | |
#[inline] | |
pub fn Rd(&self) -> u32 { (self.0 >> 16) & 0x7 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct HLT(pub u32); | |
impl HLT { | |
#[inline] | |
pub fn imm6(&self) -> u32 { (self.0 >> 16) & 0x3f } | |
} | |
#[derive(Copy, Clone)] | |
pub struct BKPT(pub u32); | |
impl BKPT { | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct IT(pub u32); | |
impl IT { | |
#[inline] | |
pub fn firstcond(&self) -> u32 { (self.0 >> 20) & 0xf } | |
#[inline] | |
pub fn mask(&self) -> u32 { (self.0 >> 16) & 0xf } | |
} | |
#[derive(Copy, Clone)] | |
pub struct HINT(pub u32); | |
impl HINT { | |
#[inline] | |
pub fn op(&self) -> u32 { (self.0 >> 20) & 0xf } | |
} | |
#[derive(Copy, Clone)] | |
pub struct LDM_STM(pub u32); | |
impl LDM_STM { | |
#[inline] | |
pub fn L(&self) -> bool { (self.0 >> 27) & 0x1 != 0 } | |
#[inline] | |
pub fn Rn(&self) -> u32 { (self.0 >> 24) & 0x7 } | |
#[inline] | |
pub fn reg_list(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct B_cond(pub u32); | |
impl B_cond { | |
#[inline] | |
pub fn cond(&self) -> u32 { (self.0 >> 24) & 0xf } | |
#[inline] | |
pub fn imm8(&self) -> i32 { ((self.0 as i32) << 8) >> 24 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct UDF(pub u32); | |
impl UDF { | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct SVC(pub u32); | |
impl SVC { | |
#[inline] | |
pub fn imm8(&self) -> u32 { (self.0 >> 16) & 0xff } | |
} | |
#[derive(Copy, Clone)] | |
pub struct B(pub u32); | |
impl B { | |
#[inline] | |
pub fn imm11(&self) -> i32 { ((self.0 as i32) << 5) >> 21 } | |
} | |
#[derive(Copy, Clone)] | |
pub struct thumb32_prefix(pub u32); | |
impl thumb32_prefix { | |
#[inline] | |
pub fn x(&self) -> u32 { (self.0 >> 27) & 0x3 } | |
#[inline] | |
pub fn y(&self) -> u32 { (self.0 >> 16) & 0x7ff } | |
} | |
} | |
pub mod decode { | |
#[inline] | |
pub fn shift_immed(instr: u32) -> Option<super::fields::shift_immed> { | |
if instr & 0xe0000000 == 0x0 && instr & 0x18000000 != 0x18000000 { | |
Some(super::fields::shift_immed(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn ADD_SUB_reg(instr: u32) -> Option<super::fields::ADD_SUB_reg> { | |
if instr & 0xfc000000 == 0x18000000 { | |
Some(super::fields::ADD_SUB_reg(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn ADD_SUB_immed3(instr: u32) -> Option<super::fields::ADD_SUB_immed3> { | |
if instr & 0xfc000000 == 0x1c000000 { | |
Some(super::fields::ADD_SUB_immed3(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn MOV_immed(instr: u32) -> Option<super::fields::MOV_immed> { | |
if instr & 0xf8000000 == 0x20000000 { | |
Some(super::fields::MOV_immed(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn CMP_immed(instr: u32) -> Option<super::fields::CMP_immed> { | |
if instr & 0xf8000000 == 0x28000000 { | |
Some(super::fields::CMP_immed(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn ADD_SUB_immed8(instr: u32) -> Option<super::fields::ADD_SUB_immed8> { | |
if instr & 0xf0000000 == 0x30000000 { | |
Some(super::fields::ADD_SUB_immed8(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn data_proc(instr: u32) -> Option<super::fields::data_proc> { | |
if instr & 0xfc000000 == 0x40000000 { | |
Some(super::fields::data_proc(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn ADD_high(instr: u32) -> Option<super::fields::ADD_high> { | |
if instr & 0xff000000 == 0x44000000 { | |
Some(super::fields::ADD_high(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn CMP_high(instr: u32) -> Option<super::fields::CMP_high> { | |
if instr & 0xff000000 == 0x45000000 { | |
Some(super::fields::CMP_high(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn MOV_high(instr: u32) -> Option<super::fields::MOV_high> { | |
if instr & 0xff000000 == 0x46000000 { | |
Some(super::fields::MOV_high(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn BX_BLX_reg(instr: u32) -> Option<super::fields::BX_BLX_reg> { | |
if instr & 0xff070000 == 0x47000000 { | |
Some(super::fields::BX_BLX_reg(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn LDR_lit(instr: u32) -> Option<super::fields::LDR_lit> { | |
if instr & 0xf8000000 == 0x48000000 { | |
Some(super::fields::LDR_lit(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn LDR_STR_reg(instr: u32) -> Option<super::fields::LDR_STR_reg> { | |
if instr & 0xf0000000 == 0x50000000 { | |
Some(super::fields::LDR_STR_reg(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn LDR_STR_immed(instr: u32) -> Option<super::fields::LDR_STR_immed> { | |
if instr & 0xf0000000 == 0x60000000 { | |
Some(super::fields::LDR_STR_immed(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn LDRB_STRB_immed(instr: u32) -> Option<super::fields::LDRB_STRB_immed> { | |
if instr & 0xf0000000 == 0x70000000 { | |
Some(super::fields::LDRB_STRB_immed(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn LDRH_STRH_immed(instr: u32) -> Option<super::fields::LDRH_STRH_immed> { | |
if instr & 0xf0000000 == 0x80000000 { | |
Some(super::fields::LDRH_STRH_immed(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn LDR_STR_sp_immed(instr: u32) -> Option<super::fields::LDR_STR_sp_immed> { | |
if instr & 0xf0000000 == 0x90000000 { | |
Some(super::fields::LDR_STR_sp_immed(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn ADR(instr: u32) -> Option<super::fields::ADR> { | |
if instr & 0xf8000000 == 0xa0000000 { | |
Some(super::fields::ADR(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn ADR_sp(instr: u32) -> Option<super::fields::ADR_sp> { | |
if instr & 0xf8000000 == 0xa8000000 { | |
Some(super::fields::ADR_sp(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn ADD_SUB_sp(instr: u32) -> Option<super::fields::ADD_SUB_sp> { | |
if instr & 0xff000000 == 0xb0000000 { | |
Some(super::fields::ADD_SUB_sp(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn CBZ_CBNZ(instr: u32) -> Option<super::fields::CBZ_CBNZ> { | |
if instr & 0xf5000000 == 0xb1000000 { | |
Some(super::fields::CBZ_CBNZ(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn SXT_UXT(instr: u32) -> Option<super::fields::SXT_UXT> { | |
if instr & 0xff000000 == 0xb2000000 { | |
Some(super::fields::SXT_UXT(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn PUSH_POP(instr: u32) -> Option<super::fields::PUSH_POP> { | |
if instr & 0xf6000000 == 0xb4000000 { | |
Some(super::fields::PUSH_POP(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn SETEND(instr: u32) -> Option<super::fields::SETEND> { | |
if instr & 0xfff70000 == 0xb6500000 { | |
Some(super::fields::SETEND(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn SETPAN(instr: u32) -> Option<super::fields::SETPAN> { | |
if instr & 0xfff70000 == 0xb6100000 { | |
Some(super::fields::SETPAN(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn CPS(instr: u32) -> Option<super::fields::CPS> { | |
if instr & 0xffe80000 == 0xb6600000 { | |
Some(super::fields::CPS(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn REV(instr: u32) -> Option<super::fields::REV> { | |
if instr & 0xff000000 == 0xba000000 && instr & 0xc00000 != 0x800000 { | |
Some(super::fields::REV(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn HLT(instr: u32) -> Option<super::fields::HLT> { | |
if instr & 0xffc00000 == 0xba800000 { | |
Some(super::fields::HLT(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn BKPT(instr: u32) -> Option<super::fields::BKPT> { | |
if instr & 0xff000000 == 0xbe000000 { | |
Some(super::fields::BKPT(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn IT(instr: u32) -> Option<super::fields::IT> { | |
if instr & 0xff000000 == 0xbf000000 && instr & 0xf0000 != 0x0 { | |
Some(super::fields::IT(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn HINT(instr: u32) -> Option<super::fields::HINT> { | |
if instr & 0xff0f0000 == 0xbf000000 { | |
Some(super::fields::HINT(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn LDM_STM(instr: u32) -> Option<super::fields::LDM_STM> { | |
if instr & 0xf0000000 == 0xc0000000 { | |
Some(super::fields::LDM_STM(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn B_cond(instr: u32) -> Option<super::fields::B_cond> { | |
if instr & 0xf0000000 == 0xd0000000 && instr & 0xe000000 != 0xe000000 { | |
Some(super::fields::B_cond(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn UDF(instr: u32) -> Option<super::fields::UDF> { | |
if instr & 0xff000000 == 0xde000000 { | |
Some(super::fields::UDF(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn SVC(instr: u32) -> Option<super::fields::SVC> { | |
if instr & 0xff000000 == 0xdf000000 { | |
Some(super::fields::SVC(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn B(instr: u32) -> Option<super::fields::B> { | |
if instr & 0xf8000000 == 0xe0000000 { | |
Some(super::fields::B(instr)) | |
} else { | |
None | |
} | |
} | |
#[inline] | |
pub fn thumb32_prefix(instr: u32) -> Option<super::fields::thumb32_prefix> { | |
if instr & 0xe0000000 == 0xe0000000 && instr & 0x18000000 != 0x0 { | |
Some(super::fields::thumb32_prefix(instr)) | |
} else { | |
None | |
} | |
} | |
} | |
#[derive(Copy, Clone)] | |
pub enum Instruction { | |
shift_immed(fields::shift_immed), | |
ADD_SUB_reg(fields::ADD_SUB_reg), | |
ADD_SUB_immed3(fields::ADD_SUB_immed3), | |
MOV_immed(fields::MOV_immed), | |
CMP_immed(fields::CMP_immed), | |
ADD_SUB_immed8(fields::ADD_SUB_immed8), | |
data_proc(fields::data_proc), | |
ADD_high(fields::ADD_high), | |
CMP_high(fields::CMP_high), | |
MOV_high(fields::MOV_high), | |
BX_BLX_reg(fields::BX_BLX_reg), | |
LDR_lit(fields::LDR_lit), | |
LDR_STR_reg(fields::LDR_STR_reg), | |
LDR_STR_immed(fields::LDR_STR_immed), | |
LDRB_STRB_immed(fields::LDRB_STRB_immed), | |
LDRH_STRH_immed(fields::LDRH_STRH_immed), | |
LDR_STR_sp_immed(fields::LDR_STR_sp_immed), | |
ADR(fields::ADR), | |
ADR_sp(fields::ADR_sp), | |
ADD_SUB_sp(fields::ADD_SUB_sp), | |
CBZ_CBNZ(fields::CBZ_CBNZ), | |
SXT_UXT(fields::SXT_UXT), | |
PUSH_POP(fields::PUSH_POP), | |
SETEND(fields::SETEND), | |
SETPAN(fields::SETPAN), | |
CPS(fields::CPS), | |
REV(fields::REV), | |
HLT(fields::HLT), | |
BKPT(fields::BKPT), | |
IT(fields::IT), | |
HINT(fields::HINT), | |
LDM_STM(fields::LDM_STM), | |
B_cond(fields::B_cond), | |
UDF(fields::UDF), | |
SVC(fields::SVC), | |
B(fields::B), | |
thumb32_prefix(fields::thumb32_prefix), | |
undefined, | |
} | |
pub fn decode<T, F: FnOnce(Instruction) -> T>(instr: u32, f: F) -> T { | |
match instr & 0xe0000000 { | |
0x00000000 => if instr & 0x18000000 == 0x18000000 { | |
match instr & 0x04000000 { | |
0x00000000 => f(Instruction::ADD_SUB_reg(fields::ADD_SUB_reg(instr))), | |
0x04000000 => f(Instruction::ADD_SUB_immed3(fields::ADD_SUB_immed3(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
} | |
} else { | |
f(Instruction::shift_immed(fields::shift_immed(instr))) | |
}, | |
0x80000000 => match instr & 0x10000000 { | |
0x00000000 => f(Instruction::LDRH_STRH_immed(fields::LDRH_STRH_immed(instr))), | |
0x10000000 => f(Instruction::LDR_STR_sp_immed(fields::LDR_STR_sp_immed(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0x40000000 => match instr & 0x10000000 { | |
0x00000000 => match instr & 0x08000000 { | |
0x00000000 => match instr & 0x04000000 { | |
0x00000000 => f(Instruction::data_proc(fields::data_proc(instr))), | |
0x04000000 => match instr & 0x03000000 { | |
0x00000000 => f(Instruction::ADD_high(fields::ADD_high(instr))), | |
0x02000000 => f(Instruction::MOV_high(fields::MOV_high(instr))), | |
0x01000000 => f(Instruction::CMP_high(fields::CMP_high(instr))), | |
0x03000000 => match instr & 0x00070000 { | |
0x00000000 => f(Instruction::BX_BLX_reg(fields::BX_BLX_reg(instr))), | |
_ => f(Instruction::undefined), | |
}, | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0x08000000 => f(Instruction::LDR_lit(fields::LDR_lit(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0x10000000 => f(Instruction::LDR_STR_reg(fields::LDR_STR_reg(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0xc0000000 => match instr & 0x10000000 { | |
0x00000000 => f(Instruction::LDM_STM(fields::LDM_STM(instr))), | |
0x10000000 => if instr & 0x0e000000 == 0x0e000000 { | |
match instr & 0x01000000 { | |
0x00000000 => f(Instruction::UDF(fields::UDF(instr))), | |
0x01000000 => f(Instruction::SVC(fields::SVC(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
} | |
} else { | |
f(Instruction::B_cond(fields::B_cond(instr))) | |
}, | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0x20000000 => match instr & 0x10000000 { | |
0x00000000 => match instr & 0x08000000 { | |
0x00000000 => f(Instruction::MOV_immed(fields::MOV_immed(instr))), | |
0x08000000 => f(Instruction::CMP_immed(fields::CMP_immed(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0x10000000 => f(Instruction::ADD_SUB_immed8(fields::ADD_SUB_immed8(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0xa0000000 => match instr & 0x10000000 { | |
0x00000000 => match instr & 0x08000000 { | |
0x00000000 => f(Instruction::ADR(fields::ADR(instr))), | |
0x08000000 => f(Instruction::ADR_sp(fields::ADR_sp(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0x10000000 => match instr & 0x04000000 { | |
0x00000000 => match instr & 0x01000000 { | |
0x00000000 => match instr & 0x0a000000 { | |
0x00000000 => f(Instruction::ADD_SUB_sp(fields::ADD_SUB_sp(instr))), | |
0x02000000 => f(Instruction::SXT_UXT(fields::SXT_UXT(instr))), | |
0x0a000000 => if instr & 0x00c00000 == 0x00800000 { | |
f(Instruction::HLT(fields::HLT(instr))) | |
} else { | |
f(Instruction::REV(fields::REV(instr))) | |
}, | |
_ => f(Instruction::undefined), | |
}, | |
0x01000000 => f(Instruction::CBZ_CBNZ(fields::CBZ_CBNZ(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0x04000000 => match instr & 0x02000000 { | |
0x00000000 => f(Instruction::PUSH_POP(fields::PUSH_POP(instr))), | |
0x02000000 => match instr & 0x09000000 { | |
0x00000000 => match instr & 0x00e00000 { | |
0x00000000 => match instr & 0x00170000 { | |
0x00100000 => f(Instruction::SETPAN(fields::SETPAN(instr))), | |
_ => f(Instruction::undefined), | |
}, | |
0x00400000 => match instr & 0x00170000 { | |
0x00100000 => f(Instruction::SETEND(fields::SETEND(instr))), | |
_ => f(Instruction::undefined), | |
}, | |
0x00600000 => match instr & 0x00080000 { | |
0x00000000 => f(Instruction::CPS(fields::CPS(instr))), | |
_ => f(Instruction::undefined), | |
}, | |
_ => f(Instruction::undefined), | |
}, | |
0x08000000 => f(Instruction::BKPT(fields::BKPT(instr))), | |
0x09000000 => if instr & 0x000f0000 == 0x00000000 { | |
f(Instruction::HINT(fields::HINT(instr))) | |
} else { | |
f(Instruction::IT(fields::IT(instr))) | |
}, | |
_ => f(Instruction::undefined), | |
}, | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0x60000000 => match instr & 0x10000000 { | |
0x00000000 => f(Instruction::LDR_STR_immed(fields::LDR_STR_immed(instr))), | |
0x10000000 => f(Instruction::LDRB_STRB_immed(fields::LDRB_STRB_immed(instr))), | |
_ => unsafe { hint::unreachable_unchecked() } | |
}, | |
0xe0000000 => if instr & 0x18000000 == 0x00000000 { | |
f(Instruction::B(fields::B(instr))) | |
} else { | |
f(Instruction::thumb32_prefix(fields::thumb32_prefix(instr))) | |
}, | |
_ => unsafe { hint::unreachable_unchecked() } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Shift, add, subtract and compare | |
shift_immed 000 type:2 imm5:5 Rm:3 Rd:3 ?type!=11 | |
ADD_SUB_reg 000110 op:1 Rm:3 Rn:3 Rd:3 | |
ADD_SUB_immed3 000111 op:1 imm3:3 Rn:3 Rd:3 | |
MOV_immed 00100 Rd:3 imm8:8 | |
CMP_immed 00101 Rn:3 imm8:8 | |
ADD_SUB_immed8 0011 op:1 Rdn:3 imm8:8 | |
# Data-processing | |
data_proc 010000 op:4 Rm:3 Rdn:3 | |
# Special data instructions and branch and exchange | |
ADD_high 01000100 DN:1 Rm:4 Rdn:3 | |
CMP_high 01000101 N:1 Rm:4 Rn:3 | |
MOV_high 01000110 D:1 Rm:4 Rd:3 | |
BX_BLX_reg 01000111 L:1 Rm:4 000 | |
# Load from Literal Pool | |
LDR_lit 01001 Rt:3 imm8:8 | |
# Load/store single data item | |
LDR_STR_reg 0101 op:3 Rm:3 Rn:3 Rt:3 | |
LDR_STR_immed 0110 L:1 imm5:5 Rn:3 Rt:3 | |
LDRB_STRB_immed 0111 L:1 imm5:5 Rn:3 Rt:3 | |
LDRH_STRH_immed 1000 L:1 imm5:5 Rn:3 Rt:3 | |
LDR_STR_sp_immed 1001 L:1 Rt:3 imm8:8 | |
# Generate PC-relative address | |
ADR 10100 Rd:3 imm8:8 | |
# Generate SP-relative address | |
ADR_sp 10101 Rd:3 imm8:8 | |
# Miscellaneous 16-bit instructions | |
ADD_SUB_sp 10110000 op:1 imm7:7 | |
CBZ_CBNZ 1011 op:1 0 i:1 1 imm5:5 Rn:3 | |
SXT_UXT 10110010 op:2 Rm:3 Rd:3 | |
PUSH_POP 1011 L:1 10 MP:1 reg_list:8 | |
SETEND 101101100101 E:1 000 | |
SETPAN 101101100001 imm:1 000 | |
CPS 10110110011 im:1 0 A:1 I:1 F:1 | |
REV 10111010 op:2 Rm:3 Rd:3 ?op!=10 | |
HLT 1011101010 imm6:6 | |
BKPT 10111110 imm8:8 | |
IT 10111111 firstcond:4 mask:4 ?mask!=0000 | |
HINT 10111111 op:4 0000 | |
# Load/store multiple registers | |
LDM_STM 1100 L:1 Rn:3 reg_list:8 | |
# Conditional branch and supervisor call | |
B_cond 1101 cond:4 imm8:s8 ?cond!=111x | |
UDF 11011110 imm8:8 | |
SVC 11011111 imm8:8 | |
# Unconditional branch | |
B 11100 imm11:s11 | |
# Thumb32 prefix | |
thumb32_prefix 111 x:2 y:11 ?x!=00 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment