diff options
-rw-r--r-- | src/lib.rs | 1021 | ||||
-rw-r--r-- | tests/test.rs | 37 |
2 files changed, 954 insertions, 104 deletions
@@ -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 |