summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-10-04 23:50:11 -0700
committeriximeow <me@iximeow.net>2020-10-04 23:50:11 -0700
commit0a67a0cffdb503967885422c2b966a0e70ec6969 (patch)
treec7bb70878fac7418a1291512b0b87bc28e243172
parent08527f0716a8ebe53273cd03eb559eaf031a2793 (diff)
add most of opcode decoding
-rw-r--r--src/lib.rs1021
-rw-r--r--tests/test.rs37
2 files changed, 954 insertions, 104 deletions
diff --git a/src/lib.rs b/src/lib.rs
index ddfbe09..b8dc192 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -17,9 +17,13 @@ impl Arch for IA64 {
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
+#[allow(non_camel_case_types)]
pub enum Opcode {
- // TODO; maybe don't actually do this one huh
+ // TODO: what kind of no-op/undefined are these exactly
Purple,
+ Cyan,
+ Brown,
+ White,
Addp4,
Adds,
@@ -165,9 +169,7 @@ pub enum Opcode {
Ldfp8_c_nc,
Ldfps_c_nc,
Ldfpd_c_nc,
- Ldfp8,
- Ldfps_a,
- Ldfps_sa,
+ Break_m,
Invala,
Fwb,
Srlz_d,
@@ -235,18 +237,262 @@ pub enum Opcode {
Psub1_uuu,
Psub1_uus,
+ Ldfp8,
Ldfps,
Ldfpd,
Ldfp8_s,
Ldfps_s,
Ldfpd_s,
Ldfp8_a,
- Ldfp8_a,
+ Ldfps_a,
Ldfpd_a,
Ldfp8_sa,
- Ldfp8_sa,
+ Ldfps_sa,
Ldfpd_sa,
+
+ Mov_m_to_ar_imm,
+ Mov_from_pkr,
+ Setf_sig,
+ Setf_exp,
+ Setf_s,
+ Setf_d,
+ Pavg1,
+ Pavg1_raz,
+ Pavgsub1,
+ Pcmp1_eq,
+ Pcmp1_gt,
+ Padd2,
+ Padd2_sss,
+ Padd2_uuu,
+ Padd2_uus,
+ Psub2,
+ Psub2_sss,
+ Psub2_uuu,
+ Psub2_uus,
+ Pavg2,
+ Pavg2_raz,
+ Pavgsub2,
+ Pshladd2,
+ Pshradd2,
+ Pcmp2_eq,
+ Pcmp2_gt,
+ Padd4,
+ Psub4,
+ Pcmp4_eq,
+ Pcmp4_gt,
+ Hint_x,
+ Nop_x,
+ Movl,
+ Brl_cond_bwh_ph_dh,
+ Brl_call_bwh_ph_dh,
+ Br_call_bwh_ph_dh,
+ Brp_ipwh_ih,
+ Break_x,
+ Break_i,
+ Zxt1,
+ Mov_from_ip,
+ Zxt2,
+ Mov_from_b,
+ Zxt4,
+ Mov_i_from_ar,
+ Sxt1,
+ Sxt2,
+ Sxt4,
+ Czx1_l,
+ Czx2_l,
+ Mov_i_to_ar_imm,
+ Mov_i_to_ar,
+ Czx1_r,
+ Czx2_r,
+ Hint_i,
+ Nop_i,
+ Chk_s_i_int,
+ Mov_to_pr_rot_imm,
+ Mov_to_pr,
+ Mov_from_pr,
+ Mov_to_b,
+ Dep,
+ Tbit_z,
+ Tnat_z,
+ Tbit_z_unc,
+ Tnat_z_unc,
+ Tbit_z_and,
+ Tnat_z_and,
+ Tbit_nz_and,
+ Tnat_nz_and,
+ Tbit_z_or,
+ Tnat_z_or,
+ Tbit_nz_or,
+ Tnat_nz_or,
+ Tbit_z_or_andcm,
+ Tnat_z_or_andcm,
+ Tbit_nz_or_andcm,
+ Tnat_nz_or_andcm,
+ Tf_z,
+ Tf_z_nc,
+ Tf_z_and,
+ Tf_nz_and,
+ Tf_z_or,
+ Tf_nz_or,
+ Tf_z_or_andcm,
+ Tf_nz_or_andcm,
+ Dep_z_imm,
+ Dep_imm,
+ Dep_z,
+ Extr,
+ Shrp,
+ Extr_u,
+ Pmin1_u,
+ Unpack1_h,
+ Pmax1_u,
+ Unpack1_l,
+ Mix1_r,
+ Mix1_l,
+ Psad1,
+ Mux1,
+ Pshr2_u_var,
+ Pmpyshr2_u,
+ Pshr2_var,
+ Pmpyshr2,
+ Pshl1_var,
+ Pshr2_u_fixed,
+ Pshr2_fixed,
+ Popcnt,
+ Clz,
+ Pack2_uss,
+ Pack2_sss,
+ Pmin2,
+ Unpack2_h,
+ Unpack2_l,
+ Pmax2,
+ Mix2_r,
+ Mix2_l,
+ Pmpy2_r,
+ Pmpy2_l,
+ Pshl2_fixed,
+ Mux2,
+ Pshr4_u_var,
+ Pshr4_var,
+ Pshl4_var,
+ Mpy4,
+ Mpyshl4,
+ Pshr4_u_fixed,
+ Pshr4_fixed,
+ Pack4_sss,
+ Unpack4_h,
+ Unpack4_l,
+ Mix4_r,
+ Mix4_l,
+ Pshl4_fixed,
+ Shr_u_var,
+ Shr_var,
+ Shl_var,
+
+ Break_b,
+ Cover,
+ Clrrb,
+ Clrrb_pr,
+ Rfi,
+ Bsw_0,
+ Bsw_1,
+ Epc,
+ Vmsw_0,
+ Vmsw_1,
+ Br_cond,
+ Br_ia,
+ Br_ret,
+
+ Nop_b,
+ Hint_b,
+ Brp,
+ Brp_ret,
+
+ Br_wexit,
+ Br_wtop,
+ Br_cloop,
+ Br_cexit,
+ Br_ctop,
+
+ Frcpa,
+ Frsqta,
+ Break_f,
+ Fsetc,
+ Fclrf,
+ Fchkf,
+ Fmerge_s,
+ Fmerge_ns,
+ Fmerge_se,
+
+ Fmin,
+ Fmax,
+ Famin,
+ Famax,
+ Fcvt_fx,
+ Fcvt_fxu,
+ Fcvt_fx_trunc,
+ Fcvt_fxu_trunc,
+ Fcvt_xf,
+ Fpack,
+ Fand,
+ Fandcm,
+ For,
+ Fxor,
+
+ Fswap,
+ Fswap_nl,
+ Fswap_nr,
+ Fmix_lr,
+ Fmix_r,
+ Fmix_l,
+
+ Fsxt_r,
+ Fsxt_l,
+
+ Hint_f,
+ Nop_f,
+
+ Fprcpa,
+ Fprsqrta,
+ Fpmerge_s,
+ Fpmerge_ns,
+ Fpmerge_se,
+
+ Fpmin,
+ Fpmax,
+ Fpamin,
+ Fpamax,
+ Fpcvt_fx,
+ Fpcvt_fxu,
+ Fpcvt_fx_trunc,
+ Fpcvt_fxu_trunc,
+ Fcmp_eq,
+ Fcmp_lt,
+ Fcmp_le,
+ Fcmp_unord,
+ Fcmp_eq_unc,
+ Fcmp_lt_unc,
+ Fcmp_le_unc,
+ Fcmp_unord_unc,
+ Fclass_m_unc,
+ Fclass_m,
+ Fma_s_sf,
+ Fma_sf,
+ Fpma_sf,
+ Fma_d_sf,
+ Fms_s_sf,
+ Fms_sf,
+ Fpms_sf,
+ Fms_d_sf,
+ Fnma_s_sf,
+ Fnma_sf,
+ Fpnma_sf,
+ Fnma_d_sf,
+ Xma_l,
+ Xma_hu,
+ Xma_h,
+ Fselect,
}
+
#[derive(Debug, PartialEq, Eq)]
pub struct Instruction {}
impl yaxpeax_arch::LengthedInstruction for Instruction {
@@ -409,37 +655,36 @@ impl Decoder<Instruction> for InstDecoder {
};
match ty {
+ InstructionType::I => {
+ let (opcode, operand_encoding) = get_i_opcode_and_encoding(tag, word);
+ read_i_operands(operand_encoding, word);
+ panic!("i");
+ },
+ InstructionType::F => {
+ let (opcode, operand_encoding) = get_f_opcode_and_encoding(tag, word);
+ read_f_operands(operand_encoding, word);
+ panic!("f");
+ },
+ InstructionType::B => {
+ let (opcode, operand_encoding) = get_b_opcode_and_encoding(tag, word);
+ read_b_operands(operand_encoding, word);
+ panic!("b");
+ },
+ InstructionType::LX => {
+ let (opcode, operand_encoding) = get_lx_opcode_and_encoding(tag, word);
+ read_lx_operands(operand_encoding, word);
+ panic!("lx");
+ },
InstructionType::A => {
let (opcode, operand_encoding) = get_a_opcode_and_encoding(tag, word);
+ eprintln!("A {:?}/{:?}", opcode, operand_encoding);
read_a_operands(operand_encoding, word);
- panic!("aaa");
+ Instruction {}
}
InstructionType::M => {
let (opcode, operand_encoding) = get_m_opcode_and_encoding(tag, word);
+ eprintln!("M({}) {:?}/{:?}", tag, opcode, operand_encoding);
read_m_operands(operand_encoding, word);
- panic!("mmm");
- match tag {
- 4 => {
- let x = word[27];
- let m = word[36];
- println!("x, m {}, {}", x, m);
- if x == false && m == true {
- let x6l = word[30..32].load::<u8>();
- let x6u = word[32..36].load::<u8>();
- println!("x6l, x6u {}, {}", x6l, x6u);
- if x6u == 5 && x6l == 3 {
- panic!("ld8.acq");
- }
- } else {
- panic!("b");
- }
- },
- _ => {
- }
- }
- Instruction {}
- }
- _ => {
Instruction {}
}
}
@@ -456,6 +701,14 @@ impl Decoder<Instruction> for InstDecoder {
}
}
+fn read_lx_operands(encoding: OperandEncodingX, word: &BitSlice<Lsb0, u8>) {
+}
+fn read_b_operands(encoding: OperandEncodingB, word: &BitSlice<Lsb0, u8>) {
+}
+fn read_f_operands(encoding: OperandEncodingF, word: &BitSlice<Lsb0, u8>) {
+}
+fn read_i_operands(encoding: OperandEncodingI, word: &BitSlice<Lsb0, u8>) {
+}
fn read_m_operands(encoding: OperandEncodingM, word: &BitSlice<Lsb0, u8>) {
use OperandEncodingM::*;
match encoding {
@@ -538,6 +791,7 @@ fn read_m_operands(encoding: OperandEncodingM, word: &BitSlice<Lsb0, u8>) {
fn read_a_operands(encoding: OperandEncodingA, word: &BitSlice<Lsb0, u8>) {
use OperandEncodingA::*;
match encoding {
+ None => { unreachable!("none operand encoding"); }
A1 => {
let r1 = word[6..13].load::<u8>();
let r2 = word[13..20].load::<u8>();
@@ -607,7 +861,7 @@ fn read_a_operands(encoding: OperandEncodingA, word: &BitSlice<Lsb0, u8>) {
let r1 = word[6..13].load::<u8>();
let r2 = word[13..20].load::<u8>();
let r3 = word[20..27].load::<u8>();
- eprintln!("a9 operands, r1={}, r2={}, r3={}, ct={}", r1, r2, r3);
+ eprintln!("a9 operands, r1={}, r2={}, r3={}", r1, r2, r3);
},
A10 => {
let r1 = word[6..13].load::<u8>();
@@ -619,6 +873,540 @@ fn read_a_operands(encoding: OperandEncodingA, word: &BitSlice<Lsb0, u8>) {
}
}
+fn get_lx_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, OperandEncodingX) {
+ use Opcode::*;
+ use OperandEncodingX::*;
+
+ match tag {
+ 0x0 => {
+ let x3 = word[33..36].load::<u8>();
+ if x3 == 0 {
+ // `Table 4-70 Misc X-Unit 6-bit Opcode Extensions`
+ let x6 = word[27..33].load::<u8>();
+ if x6 == 0 {
+ (Break_x, X1)
+ } else if x6 == 1 {
+ // `1-bit Ext (Table 4-73)`
+ if word[26] {
+ (Hint_x, X5)
+ } else {
+ (Nop_x, X5)
+ }
+ } else {
+ (Purple, None)
+ }
+ } else {
+ (Purple, None)
+ }
+ },
+ 0x1 => { (Purple, None) },
+ 0x2 => { (Purple, None) },
+ 0x3 => { (Purple, None) },
+ 0x4 => { (Purple, None) },
+ 0x5 => { (Purple, None) },
+ 0x6 => { (Movl, X2) },
+ 0x7 => { (Purple, None) },
+ 0x8 => { (Cyan, None) },
+ 0x9 => { (Cyan, None) },
+ 0xa => { (Cyan, None) },
+ 0xb => { (Cyan, None) },
+ 0xc => {
+ // p, wh, d, described in tables 4-51, 4-52, 4-54
+ (Brl_cond_bwh_ph_dh, X3)
+ },
+ 0xd => {
+ // p, wh, d, described in tables 4-51, 4-52, 4-54
+ (Brl_call_bwh_ph_dh, X4)
+ },
+ 0xe => { (Cyan, None) },
+ 0xf => { (Cyan, None) },
+ _ => { unreachable!() },
+ }
+}
+
+fn get_b_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, OperandEncodingB) {
+ use Opcode::*;
+ use OperandEncodingB::*;
+
+ match tag {
+ 0x0 => {
+ // `Table 4-48 Indirect/Miscellaneous Branch Opcode Extensions`
+ const TABLE4_48: [(Opcode, OperandEncodingB); 64] = [
+ (Break_b, B9), (White, None), (Cover, B8), (Cyan, None), (Clrrb, B8), (Clrrb_pr, B8), (Cyan, None), (Cyan, None), (Rfi, B8), (Cyan, None), (Cyan, None), (Cyan, None), (Bsw_0, B8), (Bsw_1, B8), (Cyan, None), (Cyan, None),
+ (Epc, B8), (Cyan, None), (Cyan, None), (Cyan, None), (Cyan, None), (Cyan, None), (Cyan, None), (Cyan, None), (Vmsw_0, B8), (Vmsw_1, B8), (Cyan, None), (Cyan, None), (Cyan, None), (Cyan, None), (Cyan, None), (Cyan, None),
+ (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None),
+ (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None), (Brown, None)
+ ];
+
+ let index = word[27..33].load::<u8>();
+ if index == 0b10000 {
+ // `Indirect Branch (Table 4-49)`
+ const TABLE4_49: [(Opcode, OperandEncodingB); 8] = [
+ (Br_cond, B4), (Br_ia, B4), (Brown, None), (Brown, None),
+ (Brown, None), (Brown, None), (Brown, None), (Brown, None),
+ ];
+ let subindex = word[6..9].load::<u8>();
+ TABLE4_49[subindex as usize]
+ } else if index == 0b10001 {
+ // `Indirect Return (Table 4-50)`
+ const TABLE4_50: [(Opcode, OperandEncodingB); 8] = [
+ (Brown, None), (Brown, None), (Brown, None), (Brown, None),
+ (Br_ret, B4), (Brown, None), (Brown, None), (Brown, None),
+ ];
+ let subindex = word[6..9].load::<u8>();
+ TABLE4_50[subindex as usize]
+ } else {
+ TABLE4_48[index as usize]
+ }
+ },
+ 0x1 => {
+ (Br_call_bwh_ph_dh, B5)
+ },
+ 0x2 => {
+ // `Table 4-55 Indirect Predict/Nop/Hint Opcode Extensions`
+ let x6 = word[27..33].load::<u8>();
+ if x6 == 0b000000 {
+ (Nop_b, B9)
+ } else if x6 == 0b000001 {
+ (Hint_b, B9)
+ } else if x6 == 0b010000 {
+ (Brp, B7)
+ } else if x6 == 0b010001 {
+ (Brp_ret, B7)
+ } else {
+ (White, None)
+ }
+ },
+ 0x3 => { (White, None) },
+ 0x4 => {
+ // `Table 4-47 IP-Relative Branch Types`
+ const TABLE4_47: [(Opcode, OperandEncodingB); 8] = [
+ (Br_cond, B1), (Brown, None), (Br_wexit, B1), (Br_wtop, B1),
+ (Brown, None), (Br_cloop, B2), (Br_cexit, B2), (Br_ctop, B2),
+ ];
+ let btype = word[6..9].load::<u8>();
+ TABLE4_47[btype as usize]
+ },
+ 0x5 => {
+ (Br_call_bwh_ph_dh, B3)
+ },
+ 0x6 => { (White, None) },
+ 0x7 => {
+ (Brp_ipwh_ih, B6)
+ },
+ 0x8 => { (Brown, None) },
+ 0x9 => { (Brown, None) },
+ 0xa => { (Brown, None) },
+ 0xb => { (Brown, None) },
+ 0xc => { (Brown, None) },
+ 0xd => { (Brown, None) },
+ 0xe => { (Brown, None) },
+ 0xf => { (Brown, None) },
+ _ => { unreachable!() },
+ }
+}
+
+fn get_f_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, OperandEncodingF) {
+ use Opcode::*;
+ use OperandEncodingF::*;
+
+ // `Table 4-63 Floating-point Status Field Completer` maps `sf` bits (35:34) to a FPSR status
+ // field (.s0, .s1, .s2, .s3). the mapping is "bit value N" -> ".sN", so this table is
+ // implicit.
+
+ match tag {
+ 0x0 => {
+ // `Table 4-59 Miscellaneous Floating-point 1-bit Opcode Extensions`
+ if word[33] {
+ if word[36] {
+ (Frcpa, F6)
+ } else {
+ (Frsqta, F7)
+ }
+ } else {
+ // `Table 4-60 Opcode 0 Miscellaneous Floating-point 6-bit Opcode Extensions`
+ // `1-bit Ext (Table 4-68)` handled independently,
+ const TABLE4_60: [(Opcode, OperandEncodingF); 64] = [
+ (Break_f, F15), (Purple, None), (Purple, None), (Purple, None),
+ (Fsetc, F12), (Fclrf, F13), (Purple, None), (Purple, None),
+ (Fchkf, F14), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Fmerge_s, F9), (Fmerge_ns, F9), (Fmerge_se, F9), (Purple, None),
+ (Fmin, F8), (Fmax, F8), (Famin, F8), (Famax, F8),
+ (Fcvt_fx, F10), (Fcvt_fxu, F10), (Fcvt_fx_trunc, F10), (Fcvt_fxu_trunc, F10),
+ (Fcvt_xf, F11), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Fpack, F9), (Purple, None), (Purple, None), (Purple, None),
+ (Fand, F9), (Fandcm, F9), (For, F9), (Fxor, F9),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Fswap, F9), (Fswap_nl, F9), (Fswap_nr, F9), (Purple, None),
+ (Purple, None), (Fmix_lr, F9), (Fmix_r, F9), (Fmix_l, F9),
+ (Fsxt_r, F9), (Fsxt_l, F9), (Purple, None), (Purple, None),
+ ];
+ let index = word[27..33].load::<u8>();
+ if index == 0b00001 {
+ // `Table 4-68 `
+ if word[26] {
+ (Hint_f, F16)
+ } else {
+ (Nop_f, F16)
+ }
+ } else {
+ TABLE4_60[index as usize]
+ }
+ }
+ },
+ 0x1 => {
+ // `Table 4-59 Miscellaneous Floating-point 1-bit Opcode Extensions`
+ if word[33] {
+ if word[36] {
+ (Fprcpa, F6)
+ } else {
+ (Fprsqrta, F7)
+ }
+ } else {
+ // `Table 4-61 Opcode 1 Miscellaneous Floating-point 6-bit Opcode Extensions`
+ const TABLE4_61: [(Opcode, OperandEncodingF); 64] = [
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Fpmerge_s, F9), (Fpmerge_ns, F9), (Fpmerge_se, F9), (Purple, None),
+ (Fpmin, F8), (Fpmax, F8), (Fpamin, F8), (Fpamax, F8),
+ (Fpcvt_fx, F10), (Fpcvt_fxu, F10), (Fpcvt_fx_trunc, F10), (Fpcvt_fxu_trunc, F10),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ ];
+ TABLE4_61[word[27..33].load::<u8>() as usize]
+ }
+ },
+ 2 => { (Purple, None) },
+ 3 => { (Purple, None) },
+ 0x4 => {
+ let index =
+ (word[12] as u8) << 2 +
+ (word[33] as u8) << 1 +
+ (word[36] as u8);
+ const TABLE4_66: [(Opcode, OperandEncodingF); 8] = [
+ (Fcmp_eq, F4), (Fcmp_lt, F4), (Fcmp_le, F4), (Fcmp_unord, F4),
+ (Fcmp_eq_unc, F4), (Fcmp_lt_unc, F4), (Fcmp_le_unc, F4), (Fcmp_unord_unc, F4),
+ ];
+ TABLE4_66[index as usize]
+ },
+ 0x5 => {
+ // `Table 4-67 Floating-point Class 1-bit Opcode Extensions`
+ if word[12] {
+ (Fclass_m_unc, F5)
+ } else {
+ (Fclass_m, F5)
+ }
+ },
+ 6 => { (Purple, None) },
+ 7 => { (Purple, None) },
+ 0x8 => {
+ // from section 4.6.1.1
+ if word[36] {
+ (Fma_s_sf, F1)
+ } else {
+ (Fma_sf, F1)
+ }
+ },
+ 0x9 => {
+ // from section 4.6.1.1
+ if word[36] {
+ (Fpma_sf, F1)
+ } else {
+ (Fma_d_sf, F1)
+ }
+ },
+ 0xa => {
+ // from section 4.6.1.1
+ if word[36] {
+ (Fms_s_sf, F1)
+ } else {
+ (Fms_sf, F1)
+ }
+ },
+ 0xb => {
+ // from section 4.6.1.1
+ if word[36] {
+ (Fpms_sf, F1)
+ } else {
+ (Fms_d_sf, F1)
+ }
+ },
+ 0xc => {
+ // from section 4.6.1.1
+ if word[36] {
+ (Fnma_s_sf, F1)
+ } else {
+ (Fnma_sf, F1)
+ }
+ },
+ 0xd => {
+ // from section 4.6.1.1
+ if word[36] {
+ (Fpnma_sf, F1)
+ } else {
+ (Fnma_d_sf, F1)
+ }
+ },
+ 0xe => {
+ // from section 4.6.1.2 and 4.6.2
+ if word[36] {
+ const TABLE_SECTION_4_6_1_2: [(Opcode, OperandEncodingF); 4] = [
+ (Xma_l, F2),
+ (White, None), // TODO: what exactly happens with x2 == 1? not mentioned?
+ (Xma_hu, F2),
+ (Xma_h, F2),
+ ];
+ TABLE_SECTION_4_6_1_2[word[34..36].load::<u8>() as usize]
+ } else {
+ (Fselect, F3)
+ }
+ },
+ 0xf => { (Purple, None) },
+ _ => { unreachable!() },
+ }
+}
+
+fn get_i_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, OperandEncodingI) {
+ use Opcode::*;
+ use OperandEncodingI::*;
+
+ match tag {
+ 0 => {
+ let x3 = word[33..36].load::<u8>();
+ // `Table 4-24 Misc I-Unit 3-bit Opcode Extensions`
+ if x3 == 0 {
+ // SIDEWAYS
+ // `Table 4-25 Misc I-Unit 6-bit Opcode Extensions`
+ const TABLE4_25: [(Opcode, OperandEncodingI); 64] = [
+ (Break_i, I19), (Zxt1, I29), (Purple, None), (Mov_from_ip, I25),
+ // `1-bit Ext (Table 4-26)` is handled independently
+ (Purple, None), (Zxt2, I29), (Purple, None), (Mov_from_b, I22),
+ (Purple, None), (Zxt4, I29), (Purple, None), (Mov_i_from_ar, I28),
+ (Purple, None), (Purple, None), (Purple, None), (Mov_from_pr, I25),
+ (Purple, None), (Sxt1, I29), (Purple, None), (Purple, None),
+ (Purple, None), (Sxt2, I29), (Purple, None), (Purple, None),
+ (Purple, None), (Sxt4, I29), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Czx1_l, I29), (Purple, None), (Purple, None),
+ (Purple, None), (Czx2_l, I29), (Purple, None), (Purple, None),
+ (Mov_i_to_ar_imm, I27), (Purple, None), (Mov_i_to_ar, I26), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Czx1_r, I29), (Purple, None), (Purple, None),
+ (Purple, None), (Czx2_r, I29), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ ];
+ let index = word[27..33].load::<u8>();
+ if index == 0b00001 {
+ // `1-bit Ext (Table 4-26)`
+ return if word[26] {
+ (Hint_i, I18)
+ } else {
+ (Nop_i, I18)
+ }
+ }
+ TABLE4_25[index as usize]
+ } else {
+ // `Table 4-24 Misc I-Unit 3-bit Opcode Extensions`
+ const TABLE4_24: [(Opcode, OperandEncodingI); 8] = [
+ (Purple, None),
+ (Chk_s_i_int, I20),
+ (Mov_to_pr_rot_imm, I24),
+ (Mov_to_pr, I23),
+ (Purple, None),
+ (Purple, None),
+ (Purple, None),
+ (Mov_to_b, I21),
+ ];
+ TABLE4_24[x3 as usize]
+ }
+ },
+ 1 => { (Purple, None) },
+ 2 => { (Purple, None) },
+ 3 => { (Purple, None) },
+ 4 => { (Dep, I15) },
+ 5 => {
+ let index = word[34..36].load::<u8>();
+
+ // `Table 4-23 Test Bit Opcode Extensions`
+ // this table is indexed by bits 40:37, 35:34, 33, 36, 12, 13, and 19, in that order.
+ // bits 40:37, 35:34, are always zero, so the actual index is constructed from bits 33,
+ // 36, 12, 13, and 19
+ const TABLE4_23: [(Opcode, OperandEncodingI); 32] = [
+ // bit 19 == 0
+ (Tbit_z, I16), (Tnat_z, I17), (Tbit_z_unc, I16), (Tnat_z_unc, I17),
+ (Tbit_z_and, I16), (Tnat_z_and, I17), (Tbit_nz_and, I16), (Tnat_nz_and, I17),
+ (Tbit_z_or, I16), (Tnat_z_or, I17), (Tbit_nz_or, I16), (Tnat_nz_or, I17),
+ (Tbit_z_or_andcm, I16), (Tnat_z_or_andcm, I17), (Tbit_nz_or_andcm, I16), (Tnat_nz_or_andcm, I17),
+ // bit 19 == 1
+ (Tbit_z, I16), (Tf_z, I30), (Tbit_z_unc, I16), (Tf_z_nc, I30),
+ (Tbit_z_and, I16), (Tf_z_and, I30), (Tbit_nz_and, I16), (Tf_nz_and, I30),
+ (Tbit_z_or, I16), (Tf_z_or, I30), (Tbit_nz_or, I16), (Tf_nz_or, I30),
+ (Tbit_z_or_andcm, I16), (Tf_z_or_andcm, I30), (Tbit_nz_or_andcm, I16), (Tf_nz_or_andcm, I30),
+ ];
+
+ let table4_23_index =
+ (word[19] as u8) << 4 +
+ (word[33] as u8) << 3 +
+ (word[36] as u8) << 2 +
+ (word[12] as u8) << 1 +
+ (word[13] as u8);
+
+ if word[33] {
+ if word[26] {
+ match index {
+ 0 => TABLE4_23[table4_23_index as usize],
+ 1 => (Dep_z_imm, I13),
+ 2 => (Purple, None),
+ 3 => (Dep_imm, I14),
+ _ => { unreachable!() },
+ }
+ } else {
+ match index {
+ 0 => TABLE4_23[table4_23_index as usize],
+ 1 => (Dep_z, I12),
+ 2 => (Purple, None),
+ 3 => (Dep_imm, I14),
+ _ => { unreachable!() },
+ }
+ }
+ } else {
+ if word[13] {
+ match index {
+ 0 => TABLE4_23[table4_23_index as usize],
+ 1 => (Extr, I11),
+ 2 => (Purple, None),
+ 3 => (Shrp, I10),
+ _ => { unreachable!() },
+ }
+ } else {
+ match index {
+ 0 => TABLE4_23[table4_23_index as usize],
+ 1 => (Extr_u, I11),
+ 2 => (Purple, None),
+ 3 => (Shrp, I10),
+ _ => { unreachable!() },
+ }
+ }
+ }
+ },
+ 6 => { (Purple, None) },
+ 7 => {
+ // partial interpretation of table 4-16, `v_e == 1`
+ if word[32] {
+ (Purple, None)
+ } else {
+ // `Table 4-16 Multimedia and Variable Shift 1-bit Opcode Extensions`
+ // (`v_e == 0`, since `v_e == 1` parts of this table are all undefined)
+ const TABLE4_16: [&'static [(Opcode, OperandEncodingI); 64]; 4] = [
+ &TABLE4_17,
+ &TABLE4_18,
+ &TABLE4_19,
+ &TABLE4_20,
+ ];
+
+ // `Table 4-17 Multimedia Opcode 7 Size 1 2-bit Opcode Extensions`
+ const TABLE4_17: [(Opcode, OperandEncodingI); 64] = [
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Pmin1_u, I2), (Purple, None), (Purple, None),
+ (Unpack1_h, I2), (Pmax1_u, I2), (Unpack1_l, I2), (Purple, None),
+ (Mix1_r, I2), (Purple, None), (Mix1_l, I2), (Psad1, I1),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Mux1, I3), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ ];
+
+ // `Table 4-18 Multimedia Opcode 7 Size 2 2-bit Opcode Extensions`
+ const TABLE4_18: [(Opcode, OperandEncodingI); 64] = [
+ (Pshr2_u_var, I5), (Pmpyshr2_u, I1), (Pshr2_var, I5), (Pmpyshr2, I1),
+ (Pshl1_var, I7), (Pmpyshr2_u, I1), (Purple, None), (Pmpyshr2, I1),
+ (Purple, None), (Pmpyshr2_u, I1), (Purple, None), (Pmpyshr2, I1),
+ (Purple, None), (Pmpyshr2_u, I1), (Purple, None), (Pmpyshr2, I1),
+ (Purple, None), (Pshr2_u_fixed, I6), (Purple, None), (Pshr2_fixed, I6),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Popcnt, I9), (Purple, None), (Purple, None),
+ (Purple, None), (Clz, I9), (Purple, None), (Purple, None),
+ (Pack2_uss, I2), (Purple, None), (Pack2_sss, I2), (Pmin2, I2),
+ (Unpack2_h, I2), (Purple, None), (Unpack2_l, I2), (Pmax2, I2),
+ (Mix2_r, I2), (Purple, None), (Mix2_l, I2), (Purple, None),
+ (Purple, None), (Pmpy2_r, I2), (Purple, None), (Pmpy2_l, I2),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Pshl2_fixed, I8), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Mux2, I4), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ ];
+
+ // `Table 4-19 Multimedia Opcode 7 Size 4 2-bit Opcode Extensions`
+ const TABLE4_19: [(Opcode, OperandEncodingI); 64] = [
+ (Pshr4_u_var, I5), (Purple, None), (Pshr4_var, I5), (Purple, None),
+ (Pshl4_var, I7), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Mpy4, I2), (Purple, None), (Mpyshl4, I2),
+ (Pshr4_u_fixed, I6), (Purple, None), (Pshr4_fixed, I6), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Pack4_sss, I2), (Purple, None),
+ (Unpack4_h, I2), (Purple, None), (Unpack4_l, I2), (Purple, None),
+ (Mix4_r, I2), (Purple, None), (Mix4_l, I2), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Pshl4_fixed, I8), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ ];
+
+ const TABLE4_20: [(Opcode, OperandEncodingI); 64] = [
+ (Shr_u_var, I5), (Purple, None), (Shr_var, I5), (Purple, None),
+ (Shl_var, I7), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ ];
+
+ let index = (word[36] as u8) << 1 + (word[33] as u8);
+ let inner_index = word[28..32].load::<u8>() + (word[34..35].load::<u8>() << 4);
+ TABLE4_16[index as usize][inner_index as usize]
+ }
+ },
+ _ => {
+ unreachable!("m major op > 7 are a-type instructions");
+ }
+ }
+}
+
fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, OperandEncodingM) {
use Opcode::*;
use OperandEncodingM::*;
@@ -659,7 +1447,8 @@ fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
}
TABLE4_43[index as usize]
} else {
- const TABLE4_42: [(Opcode, OperandEncodingM); 7] = [
+ const TABLE4_42: [(Opcode, OperandEncodingM); 8] = [
+ (Purple, None),
(Purple, None),
(Purple, None),
(Purple, None),
@@ -698,7 +1487,8 @@ fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
let index = word[27..33].load::<u8>();
TABLE4_45[index as usize]
} else {
- const TABLE4_44: [(Opcode, OperandEncodingM); 7] = [
+ const TABLE4_44: [(Opcode, OperandEncodingM); 8] = [
+ (Purple, None),
(Chk_s_m_int, M20),
(Purple, None),
(Chk_s_fp, M21),
@@ -718,26 +1508,34 @@ fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
Some(&TABLE4_30),
Some(&TABLE4_33),
Some(&TABLE4_31),
- None
+ Option::None
];
- // `Table 4-30 Integer Load/Store Opcode Extensions
+ // `Table 4-30 Integer Load/Store Opcode Extensions`
+ // NOTE: this differs from the manual, which i believe to be in error. the manual's
+ // `Table 4-30` lists operand encodings of `M2` in all places that are `M1` here, and is
+ // functionally a duplicate of `Table 4-31` as a result. looking at the `Int Load`
+ // encoding specifically, it indicates that bit 36 (named `m` here) being 0 should pick
+ // `M1` encodings. the manual also lists `M2` twice, so it seems likely at least one
+ // `M2` is in error. the first `M2` matches with the `M1` encoding specified in `Table
+ // 4-4 Instruction Format Summary`, so that's likely the one in error.
+ // `M6` from `Table 4-30` appears to also be in error, and should name `M4`
const TABLE4_30: [(Opcode, OperandEncodingM); 64] = [
- (Ld1, M2), (Ld2, M2), (Ld4, M2), (Ld8, M2),
- (Ld1_s, M2), (Ld2_s, M2), (Ld4_s, M2), (Ld8_s, M2),
- (Ld1_a, M2), (Ld2_a, M2), (Ld4_a, M2), (Ld8_a, M2),
- (Ld1_sa, M2), (Ld2_sa, M2), (Ld4_sa, M2), (Ld8_sa, M2),
- (Ld1_bias, M2), (Ld2_bias, M2), (Ld4_bias, M2), (Ld8_bias, M2),
- (Ld1_acq, M2), (Ld2_acq, M2), (Ld4_acq, M2), (Ld8_acq, M2),
- (Purple, None), (Purple, None), (Purple, None), (Ld8_fill, M2),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Ld1_c_clr, M2), (Ld2_c_clr, M2), (Ld4_c_clr, M2), (Ld8_c_clr, M2),
- (Ld1_c_nc, M2), (Ld2_c_nc, M2), (Ld4_c_nc, M2), (Ld8_c_nc, M2),
- (Ld1_c_clr_acq, M2), (Ld2_c_clr_acq, M2), (Ld4_c_clr_acq, M2), (Ld8_c_clr_acq, M2),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (St1, M6), (St2, M6), (St4, M6), (St8, M6),
- (St1_rel, M6), (St2_rel, M6), (St4_rel, M6), (St8_rel, M6),
- (Purple, None), (Purple, None), (Purple, None), (St8_spill, M6),
+ (Ld1, M1), (Ld2, M1), (Ld4, M1), (Ld8, M1),
+ (Ld1_s, M1), (Ld2_s, M1), (Ld4_s, M1), (Ld8_s, M1),
+ (Ld1_a, M1), (Ld2_a, M1), (Ld4_a, M1), (Ld8_a, M1),
+ (Ld1_sa, M1), (Ld2_sa, M1), (Ld4_sa, M1), (Ld8_sa, M1),
+ (Ld1_bias, M1), (Ld2_bias, M1), (Ld4_bias, M1), (Ld8_bias, M1),
+ (Ld1_acq, M1), (Ld2_acq, M1), (Ld4_acq, M1), (Ld8_acq, M1),
+ (Purple, None), (Purple, None), (Purple, None), (Ld8_fill, M1),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Ld1_c_clr, M1), (Ld2_c_clr, M1), (Ld4_c_clr, M1), (Ld8_c_clr, M1),
+ (Ld1_c_nc, M1), (Ld2_c_nc, M1), (Ld4_c_nc, M1), (Ld8_c_nc, M1),
+ (Ld1_c_clr_acq, M1), (Ld2_c_clr_acq, M1), (Ld4_c_clr_acq, M1), (Ld8_c_clr_acq, M1),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (St1, M4), (St2, M4), (St4, M4), (St8, M4),
+ (St1_rel, M4), (St2_rel, M4), (St4_rel, M4), (St8_rel, M4),
+ (Purple, None), (Purple, None), (Purple, None), (St8_spill, M4),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
];
@@ -762,6 +1560,7 @@ fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
];
// `Table 4-33 Semaphore/Get FR/16-byte Opcode Extensions`
+ // `M6` from `Table 4-33` appears to also be in error, and should name `M4`
const TABLE4_33: [(Opcode, OperandEncodingM); 64] = [
(Cmpxchg1_acq, M16), (Cmpxchg2_acq, M16), (Cmpxchg4_acq, M16), (Cmpxchg8_acq, M16),
(Cmpxchg1_rel, M16), (Cmpxchg2_rel, M16), (Cmpxchg4_rel, M16), (Cmpxchg8_rel, M16),
@@ -775,13 +1574,16 @@ fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
(Cmp8xchg16_rel, M16), (Purple, None), (Purple, None), (Purple, None),
(Ld16, M2), (Purple, None), (Purple, None), (Purple, None),
(Ld16_acq, M2), (Purple, None), (Purple, None), (Purple, None),
- (St16, M6), (Purple, None), (Purple, None), (Purple, None),
- (St16_rel, M6), (Purple, None), (Purple, None), (Purple, None),
+ (St16, M4), (Purple, None), (Purple, None), (Purple, None),
+ (St16_rel, M4), (Purple, None), (Purple, None), (Purple, None),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
];
let index = ((word[36] as u8) << 1) + (word[27] as u8);
+ eprintln!("table {}", index);
+ eprintln!(" subidx {:b}", word[30..36].load::<u8>() as usize);
+ eprintln!(" x6l {:#b}, x6h {:#b}", word[30..32].load::<u8>(), word[32..36].load::<u8>());
if let Some(op_table) = TABLE4_28[index as usize] {
op_table[word[30..36].load::<u8>() as usize]
} else {
@@ -789,24 +1591,23 @@ fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
}
},
5 => {
- unimplemented!("table 4-32");
// `Table 4-32 Integer Load/Store +Imm Opcode Extensions`
const TABLE4_32: [(Opcode, OperandEncodingM); 64] = [
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Ld1, M3), (Ld2, M3), (Ld4, M3), (Ld8, M3),
+ (Ld1_s, M3), (Ld2_s, M3), (Ld4_s, M3), (Ld8_s, M3),
+ (Ld1_a, M3), (Ld2_a, M3), (Ld4_a, M3), (Ld8_a, M3),
+ (Ld1_sa, M3), (Ld2_sa, M3), (Ld4_sa, M3), (Ld8_sa, M3),
+ (Ld1_bias, M3), (Purple, M3), (Purple, M3), (Ld8_bias, M3),
+ (Ld1_acq, M3), (Purple, M3), (Purple, M3), (Ld8_acq, M3),
+ (Purple, None), (Purple, None), (Purple, None), (Ld8_fill, M3),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Ld1_c_clr, M3), (Ld2_c_clr, M3), (Ld4_c_clr, M3), (Ld8_c_clr, M3),
+ (Ld1_c_nc, M3), (Ld2_c_nc, M3), (Ld4_c_nc, M3), (Ld8_c_nc, M3),
+ (Ld1_c_clr_acq, M3), (Ld2_c_clr_acq, M3), (Ld4_c_clr_acq, M3), (Ld8_c_clr_acq, M3),
+ (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (St1, M5), (St2, M5), (St4, M5), (St8, M5),
+ (St1_rel, M5), (St2_rel, M5), (St4_rel, M5), (St8_rel, M5),
+ (Purple, None), (Purple, None), (Purple, None), (St8_spill, M5),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
];
@@ -822,26 +1623,30 @@ fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
];
// `Table 4-34 Floating-point Load/Store/Lfetch Opcode Extensions`
+ // NOTE: manual is in error. `M9` in this table ought to be `M6`.
+ // NOTE: manual is in error. `M13` in this table ought to be `M9`.
+ // NOTE: manual is in error. `M18` in this table ought to be `M13`.
const TABLE4_34: [(Opcode, OperandEncodingM); 64] = [
- (Ldfe, M9), (Ldf8, M9), (Ldfs, M9), (Ldfd, M9),
- (Ldfe_s, M9), (Ldf8_s, M9), (Ldfs_s, M9), (Ldfd_s, M9),
- (Ldfe_a, M9), (Ldf8_a, M9), (Ldfp_a, M9), (Ldfd_a, M9),
- (Ldfe_sa, M9), (Ldf8_sa, M9), (Ldfp_sa, M9), (Ldfd_sa, M9),
+ (Ldfe, M6), (Ldf8, M6), (Ldfs, M6), (Ldfd, M6),
+ (Ldfe_s, M6), (Ldf8_s, M6), (Ldfs_s, M6), (Ldfd_s, M6),
+ (Ldfe_a, M6), (Ldf8_a, M6), (Ldfp_a, M6), (Ldfd_a, M6),
+ (Ldfe_sa, M6), (Ldf8_sa, M6), (Ldfp_sa, M6), (Ldfd_sa, M6),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Ldf_fill, M9),
+ (Purple, None), (Purple, None), (Purple, None), (Ldf_fill, M6),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Ldfe_c_clr, M9), (Ldf8_c_clr, M9), (Ldfs_c_clr, M9), (Ldfd_c_clr, M9),
- (Ldfe_c_nc, M9), (Ldf8_c_nc, M9), (Ldfs_c_nc, M9), (Ldfd_c_nc, M9),
+ (Ldfe_c_clr, M6), (Ldf8_c_clr, M6), (Ldfs_c_clr, M6), (Ldfd_c_clr, M6),
+ (Ldfe_c_nc, M6), (Ldf8_c_nc, M6), (Ldfs_c_nc, M6), (Ldfd_c_nc, M6),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Lfetch, M18), (Lfetch_excl, M18), (Lfetch_fault, M18), (Lfetch_fault_excl, M18),
- (Stfe, M13), (Stf8, M13), (Stfs, M13), (Stfd, M13),
+ (Lfetch, M13), (Lfetch_excl, M13), (Lfetch_fault, M13), (Lfetch_fault_excl, M13),
+ (Stfe, M9), (Stf8, M9), (Stfs, M9), (Stfd, M9),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Stf_spill, M13),
+ (Purple, None), (Purple, None), (Purple, None), (Stf_spill, M9),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
];
// `Table 4-35 Floating-point Load/Lfetch +Reg Opcode Extensions`
+ // NOTE: manual is in error. `M20` in this table ought to be `M14`.
const TABLE4_35: [(Opcode, OperandEncodingM); 64] = [
(Ldfe, M7), (Ldf8, M7), (Ldfs, M7), (Ldfd, M7),
(Ldfe_s, M7), (Ldf8_s, M7), (Ldfs_s, M7), (Ldfd_s, M7),
@@ -854,7 +1659,7 @@ fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
(Ldfe_c_clr, M7), (Ldf8_c_clr, M7), (Ldfs_c_clr, M7), (Ldfd_c_clr, M7),
(Ldfe_c_nc, M7), (Ldf8_c_nc, M7), (Ldfs_c_nc, M7), (Ldfd_c_nc, M7),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Lfetch, M20), (Lfetch_excl, M20), (Lfetch_fault, M20), (Lfetch_fault_excl, M20),
+ (Lfetch, M14), (Lfetch_excl, M14), (Lfetch_fault, M14), (Lfetch_fault_excl, M14),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
@@ -907,22 +1712,23 @@ fn get_m_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
},
7 => {
// `Table 4-36 Floating-point Load/Store/Lfetch +Imm Opcode Extensions`
+ // NOTE: manual is in error. `M22` in this table ought to be `M15`.
const TABLE4_36: [(Opcode, OperandEncodingM); 64] = [
+ (Ldfe, M8), (Ldf8, M8), (Ldfs, M8), (Ldfd, M8),
+ (Ldfe_s, M8), (Ldf8_s, M8), (Ldfs_s, M8), (Ldfd_s, M8),
+ (Ldfe_a, M8), (Ldf8_a, M8), (Ldfs_a, M8), (Ldfd_a, M8),
+ (Ldfe_sa, M8), (Ldf8_sa, M8), (Ldfs_sa, M8), (Ldfd_sa, M8),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Ldf_fill, M8),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Ldfe_c_clr, M8), (Ldf8_c_clr, M8), (Ldfs_c_clr, M8), (Ldfd_c_clr, M8),
+ (Ldfe_c_nc, M8), (Ldf8_c_nc, M8), (Ldfs_c_nc, M8), (Ldfd_c_nc, M8),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Lfetch, M15), (Lfetch_excl, M15), (Lfetch_fault, M15), (Lfetch_fault_excl, M15),
+ (Stfe, M10), (Stf8, M10), (Stfs, M10), (Stfd, M10),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
- (Purple, None), (Purple, None), (Purple, None), (Purple, None),
+ (Purple, None), (Purple, None), (Purple, None), (Stf_spill, M10),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
];
@@ -976,7 +1782,7 @@ fn get_a_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
Some(&TABLE4_13),
Some(&TABLE4_14),
Some(&TABLE4_15),
- None
+ Option::None
];
const TABLE4_13: [(Opcode, OperandEncodingA); 64] = [
@@ -1001,8 +1807,8 @@ fn get_a_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
const TABLE4_14: [(Opcode, OperandEncodingA); 64] = [
(Padd2, A9), (Padd2_sss, A9), (Padd2_uuu, A9), (Padd2_uus, A9),
(Psub2, A9), (Psub2_sss, A9), (Psub2_uuu, A9), (Psub2_uus, A9),
- (Purple, None), (Purple, None), (Pavg2,g A9), (Pavg2_raz, A9),
- (Purple, None), (Purple, None), (Pavgsub2,g A9), (Purple, None),
+ (Purple, None), (Purple, None), (Pavg2, A9), (Pavg2_raz, A9),
+ (Purple, None), (Purple, None), (Pavgsub2, A9), (Purple, None),
(Pshladd2, A10), (Pshladd2, A10), (Pshladd2, A10), (Pshladd2, A10),
(Purple, None), (Purple, None), (Purple, None), (Purple, None),
(Pshradd2, A10), (Pshradd2, A10), (Pshradd2, A10), (Pshradd2, A10),
@@ -1049,6 +1855,9 @@ fn get_a_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
3 => {
(Opcode::Addp4, OperandEncodingA::A4)
}
+ _ => {
+ unreachable!()
+ }
}
}
9 => (Addl, A5),
@@ -1056,35 +1865,35 @@ fn get_a_opcode_and_encoding(tag: u8, word: &BitSlice<Lsb0, u8>) -> (Opcode, Ope
0xb => (Purple, None),
0xc => {
let x2 = word[34..36].load::<u8>();
- if x2 > 1 {
+ let encoding = if x2 > 1 {
// `Table 4-11 Integer Compare Immediate Opcode Extensions`
- let encoding = A8;
+ A8
} else {
// `Table 4-10 Integer Compare Opcode Extensions`
- let encoding = if word[36] { A7 } else { A6 };
- }
+ if word[36] { A7 } else { A6 }
+ };
unimplemented!("type a, tag c");
}
0xd => {
let x2 = word[34..36].load::<u8>();
- if x2 > 1 {
+ let encoding = if x2 > 1 {
// `Table 4-11 Integer Compare Immediate Opcode Extensions`
- let encoding = A8;
+ A8
} else {
// `Table 4-10 Integer Compare Opcode Extensions`
- let encoding = if word[36] { A7 } else { A6 };
- }
+ if word[36] { A7 } else { A6 }
+ };
unimplemented!("type a, tag d");
}
0xe => {
let x2 = word[34..36].load::<u8>();
- if x2 > 1 {
+ let encoding = if x2 > 1 {
// `Table 4-11 Integer Compare Immediate Opcode Extensions`
- let encoding = A8;
+ A8
} else {
// `Table 4-10 Integer Compare Opcode Extensions`
- let encoding = if word[36] { A7 } else { A6 };
- }
+ if word[36] { A7 } else { A6 }
+ };
unimplemented!("type a, tag e");
}
0xf => (Purple, None),
@@ -1111,6 +1920,7 @@ enum OperandEncodingA {
#[derive(Copy, Clone, Debug)]
enum OperandEncodingI {
+ None,
I1,
I2,
I3,
@@ -1198,6 +2008,7 @@ enum OperandEncodingM {
#[derive(Copy, Clone, Debug)]
enum OperandEncodingB {
+ None,
B1,
B2,
B3,
@@ -1211,6 +2022,7 @@ enum OperandEncodingB {
#[derive(Copy, Clone, Debug)]
enum OperandEncodingF {
+ None,
F1,
F2,
F3,
@@ -1231,6 +2043,7 @@ enum OperandEncodingF {
#[derive(Copy, Clone, Debug)]
enum OperandEncodingX {
+ None,
X1,
X2,
X3,
diff --git a/tests/test.rs b/tests/test.rs
new file mode 100644
index 0000000..cac89d0
--- /dev/null
+++ b/tests/test.rs
@@ -0,0 +1,37 @@
+use yaxpeax_ia64::InstDecoder;
+use yaxpeax_arch::Decoder;
+
+#[test]
+fn test_a_bundle() {
+// from elf64-ia64-vms.c
+// [MMI] addl r15=0,r1;;
+// ld8.acq r16=[r15],8
+// mov r14=r1;;
+ let data = [0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, 0x00, 0x41, 0x3c, 0x70, 0x27, 0xc0, 0x01, 0x08, 0x00, 0x84];
+
+ let decoder = InstDecoder::default();
+ decoder.decode(data[..].iter().cloned()).unwrap();
+}
+
+// from elf64-ia64-vms.c
+// 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, 0x00, 0x41, 0x3c, 0x70, 0x27, 0xc0, 0x01, 0x08, 0x00, 0x84
+// [MMI] addl r15=0,r1;;
+// ld8.acq r16=[r15],8
+// mov r14=r1;;
+// 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, 0x60, 0x00, 0x80, 0x00
+// [MIB] ld8 r1=[r15]
+// mov b6=r16
+// br.few b6;;
+// 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
+// [MLX] nop.m 0
+// brl.sptk.few tgt;;
+
+// from ia64 bash_4.2+dfsg-0.1+deb7u3_ia64:
+// 0410 1c00 8045 024c 8009 0060 f013 1a60
+// 0510 4118 0021 0000 0000 6020 0023 c86f
+// 0908 2144 1814 a000 4444 0820 0100 c000
+// 0100 0c50 2a04 1048 040a 40c0 0461 0084
+// 0158 80fb f027 0082 f5e5 4f60 04ed c79f
+// 0918 0016 1810 0002 8030 2080 04e9 b79f
+// 0818 0146 1810 4002 9030 2000 0000 0400
+// 1000 2806 9811 5002 2000 4200 50a5 ff58